Created
September 9, 2018 16:02
-
-
Save Reflexe/b78962a67277cfbddf6dd5ad56f22e67 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/env bash | |
# I don't know way, but without this line gcc start to compile stdout :\ | |
exec 1>&2 | |
set -x | |
# build the linux targets with {linux_headers_path}/build; | |
# compile it to the our Makefile's path and read | |
# our Makefile from stdin to make its path simpler. | |
# 'info' or 'compile' | |
mode=$1 | |
makefile_path=$2 | |
output_dirname=$3 | |
output_filename="$name.ko" | |
make_mode="" | |
export sandbox_pwd=$PWD | |
if [[ "$mode" == "info" ]]; then | |
make_mode="zq_info" | |
elif [[ "$mode" == "compile" ]]; then | |
make_mode="zq_modules" | |
else | |
echo "Invalid mode: $mode" 1>&2 | |
exit 1 | |
fi | |
make_output=$(make -s -f "-" "$make_mode" < "$makefile_path" 2>&1) | |
if test $? -ne 0; then | |
echo "$make_output" | |
exit 1 | |
fi | |
warnings=`grep 'WARNING:' <<< "$make_output"` | |
if test $? -eq 0; then | |
echo "Error: Found a warning: " 1>&2 | |
echo "$warnings" 1>&2 | |
exit 1 | |
fi | |
if [[ "$mode" == "info" ]]; then | |
echo "$make_output" | |
else | |
# Then, copy the built target (X.ko) to the output directory. | |
cp -r "$(dirname "$makefile_path")/$output_filename" "$output_dirname" | |
fi |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# @brief Escape @string from @chars_to_escape with @escape_char. | |
# @param string [str] A string to escape. | |
# @param chars_to_escape [iteratable] Items to escape from @a string. | |
# @param escape_char [str] Char to replace any occurence of anyone from | |
# @a chars_to_escape. | |
def escape(string, chars_to_escape, escape_char=None): | |
# Set the default escape_char. | |
if escape_char == None: | |
escape_char = '\\' | |
# Replace each occurence of @char with "@char+@escape_char". | |
for char in chars_to_escape: | |
string = string.replace (char, escape_char + char) | |
return string | |
# @brief UNIX: generate a relative path to the workspace root from a path within the workspace. | |
# @param file the file path. | |
def get_relative_file_path_to_workspace(file): | |
return '../' * file.path.count ('/') | |
# @brief Escape spaces from strings (paths) | |
# | |
# non-cross-platform way to escape spaces from strings. | |
# Especially useful for paths with spaces. | |
# | |
# @param A string to escape. | |
# | |
# @return 'A B C' -> 'A\ B\ C' | |
def escape_spaces(string): | |
return escape(string, (' ')) | |
def _impl(ctx): | |
# Add env vars to the default env. | |
make_env_vars = ctx.configuration.default_shell_env | |
includes_files_depset = depset() | |
includes_paths_depset = depset() | |
for target in ctx.attr.includes: | |
includes_files_depset += target.files | |
includes_paths_depset += [file.dirname for file in target.files] | |
# Get the relative path from our makefile's dir to the workspace. | |
CppCore_to_workspace = get_relative_file_path_to_workspace (ctx.file._makefile) | |
# Get the module sources and add it the env var. | |
make_env_vars['ZQ_MODULE_SOURCES'] = '' | |
for f in ctx.files.srcs: | |
make_env_vars['ZQ_MODULE_SOURCES'] += escape_spaces(CppCore_to_workspace + f.path) + ' ' | |
libs_depset = depset() | |
make_env_vars['ZQ_OBJECTS'] = '' | |
for dep in ctx.attr.deps: | |
if 'cc' in dir(dep): | |
libs_depset += dep.cc.libs | |
includes_paths_depset += dep.cc.system_include_directories | |
includes_files_depset += dep.cc.transitive_headers | |
for object in libs_depset.to_list()[::-1]: | |
make_env_vars['ZQ_OBJECTS'] += escape_spaces(CppCore_to_workspace + object.path) + ' ' | |
# Set the target's name. | |
make_env_vars['name'] = ctx.attr.name | |
# Set the header's path. | |
#linux_headers_path_to_workspace = get_relative_file_path_to_workspace (ctx.file.linux_headers_path) | |
make_env_vars['ZQ_LINUX_HEADERS_PATH'] = escape_spaces(ctx.file.linux_headers_path.path) | |
make_env_vars['ZQ_MAKEFILE_PATH'] = escape_spaces(ctx.file._makefile.dirname) | |
# Add includes as compiler arguments. | |
make_env_vars['ZQ_INCLUDE_PATHS'] = '' | |
for d in includes_paths_depset.to_list(): | |
make_env_vars['ZQ_INCLUDE_PATHS'] += escape_spaces(d) + ' ' | |
# Run the actual action. | |
ctx.actions.run( | |
inputs=ctx.files.srcs | |
+ ctx.files._makefile | |
+ ctx.files.linux_headers_path | |
+ ctx.files.deps | |
+ includes_files_depset.to_list() | |
+ libs_depset.to_list(), | |
outputs=[ctx.outputs._output_ko], | |
executable=ctx.file._script, | |
arguments=['compile', | |
ctx.file._makefile.path, | |
ctx.outputs._output_ko.path], | |
progress_message= "Compiling and linking Linux Module: %s" % ctx.attr.name, | |
env = make_env_vars) | |
linux_module = rule( | |
implementation=_impl, | |
attrs={ | |
'_script': attr.label(default=Label(':CompileLinuxModule.sh'), | |
allow_single_file=True), | |
'_makefile': attr.label(default=Label(':Makefile'), | |
allow_single_file=True), | |
'srcs': attr.label_list(allow_files=True), | |
'linux_headers_path': attr.label( | |
allow_single_file=True), | |
'deps': attr.label_list(), | |
'includes': attr.label_list(allow_files=True), | |
}, | |
# The output .ko file. Maybe we should also save the .o files? | |
outputs={"_output_ko": "%{name}.ko"}, | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ZQ_LINUX_MODULE_OBJECT := $(addsuffix .o,$(basename $(ZQ_MODULE_SOURCES))) | |
OTHER_MODULE_OBJECTS=$(filter-out Linux.o,$(ZQ_LINUX_MODULE_OBJECT)) | |
name := $(name) | |
obj-m := $(name).o | |
ko-m := $(name).ko | |
$(name)-objs := $(OTHER_MODULE_OBJECTS) $(ZQ_OBJECTS) | |
ccflags-y := $(addprefix -I${sandbox_pwd}/, $(ZQ_INCLUDE_PATHS)) | |
zq_info : ; make -s -C "${ZQ_LINUX_HEADERS_PATH}" M="${sandbox_pwd}/${ZQ_MAKEFILE_PATH}" -k --no-print-directory --eval='$$(info $$(KBUILD_CFLAGS))' | |
zq_modules : ; make -C "${sandbox_pwd}/${ZQ_LINUX_HEADERS_PATH}" M="${sandbox_pwd}/${ZQ_MAKEFILE_PATH}" modules |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment