{ "config": { "doc": [ "Generate a C/C++ config header" , "" , "Generate a C/C++ configuration header using defines specified via the" , "target configuration. In the usual case, a target using this rule is" , "configured by depending on it from a target that uses the built-in" , "\"configure\" rule." ] , "field_doc": { "name": ["Name of the header file to generate (incl. file name ext)."] , "guard": ["The include guard. Multiple segments are joined with \"_\"."] , "stage": ["The location of the header. Path segments are joined with \"/\"."] , "hdrs": [ "Additional header files to be available in the include path. Useful" , "for providing additional header files to values given in" , "\"have_{cfile,cxxfile,ctype,cxxtype,csymbol,cxxsymbol}\"." ] , "deps": [ "Additional public header files from targets to be available in the" , "include path. Useful for providing additional header files to values" , "given in \"have_{cfile,cxxfile,ctype,cxxtype,csymbol,cxxsymbol}\"." ] , "defaults": ["The C/C++ toolchain to use"] , "shell defaults": ["The shell toolchain to use"] } , "config_doc": { "CC": [ "The name of the C compiler to be used by checks. If None, the" , "respective value from [\"CC\", \"defaults\"] will be taken." ] , "CXX": [ "The name of the C++ compiler to be used by checks. If None, the" , "respective value from [\"CC\", \"defaults\"] will be taken." ] , "CFLAGS": [ "The flags for CXX to be used instead of the default ones" , "taken from the [\"CC\", \"defaults\"] target" ] , "CXXFLAGS": [ "The flags for CXX to be used instead of the default ones" , "taken from the [\"CC\", \"defaults\"] target" ] , "ADD_CFLAGS": [ "The flags to add to the default ones for CC" , "taken from the [\"CC\", \"defaults\"] target" ] , "ADD_CXXFLAGS": [ "The flags to add to the default ones for CXX" , "taken from the [\"CC\", \"defaults\"] target" ] , "ENV": ["The environment for running file/symbol/type/size checks."] , "defines": [ "Set a define to a specific value unless its value is \"null\". Must" , "contain a list of pairs. The first element of each pair is the define" , "name and the second argument is the value to set. Strings must be" , "properly escaped. Defines generated from this field are added last," , "so that they can refer to defines from other \"defines*\", " , "\"have_*\", and \"size_*\" values." ] , "defines1": [ "Set a define to \"1\" unless its value is untrue. Must contain a list" , "of pairs. The first element of each pair is the define name and the" , "second argument is the value." ] , "defines01": [ "Set a define to \"0\" or \"1\" depending on its value being true." , "Must contain a list of pairs. The first element of each pair is the" , "define name and the second argument is the value." ] , "have_cfile": [ "Set a define to \"1\" if the specified C header is in the include" , "path. Must contain a list of pairs. The first element of each pair is" , "the define name and the second argument is the C header file name." ] , "have_cxxfile": [ "Set a define to \"1\" if the specified C++ header is in the include" , "path. Must contain a list of pairs. The first element of each pair is" , "the define name and the second argument is the C++ header file name." ] , "have_ctype": [ "Set a define to \"1\" if the specified C type is defined. Must" , "contain a list of pairs. The first element of each pair is the define" , "name and the second argument is name of the C type. If the specified" , "C type is not a built-in type, additionally the headers" , "\"sys/types.h\", \"stdint.h\", and \"stddef.h\" are checked as well." ] , "have_cxxtype": [ "Set a define to \"1\" if the specified C++ type is defined. Must" , "contain a list of pairs. The first element of each pair is the define" , "name and the second argument is name of the C++ type. If the specified" , "C++ type is not a built-in type, additionally the headers" , "\"sys/types.h\", \"stdint.h\", and \"stddef.h\" are checked as well." ] , "have_csymbol": [ "Set a define to \"1\" if the specified C symbol is defined by one of" , "the specified headers in the include path. Must contain a list of" , "pairs. The first element of each pair is the define name and the" , "second argument is another pair. This pair's first value is the C" , "symbol to search for and the second value is a list with the header" , "file names to consider for searching. If the header file defines the" , "symbol as a macro it is considered available and assumed to work." ] , "have_cxxsymbol": [ "Set a define to \"1\" if the specified C++ symbol is defined by one of" , "the specified headers in the include path. Must contain a list of" , "pairs. The first element of each pair is the define name and the" , "second argument is another pair. This pair's first value is the C++" , "symbol to search for and the second value is a list with the header" , "file names to consider for searching. If the header file defines the" , "symbol as a macro it is considered available and assumed to work." ] , "size_ctype": [ "Set a define to size of the specified C type. Must contain a list of" , "pairs. The first element of each pair is the define name and the" , "second argument is another pair. This pair's first value is the C" , "type to check for and the second value is a list with possible sizes" , "as numbers. If none of the specified sizes matches, the action fails." ] , "size_cxxtype": [ "Set a define to size of the specified C++ type. Must contain a list of" , "pairs. The first element of each pair is the define name and the" , "second argument is another pair. This pair's first value is the C++" , "type to check for and the second value is a list with possible sizes" , "as numbers. If none of the specified sizes matches, the action fails." ] } , "string_fields": ["name", "stage", "guard"] , "target_fields": ["hdrs", "deps"] , "config_vars": [ "CC" , "CXX" , "CFLAGS" , "CXXFLAGS" , "ADD_CFLAGS" , "ADD_CXXFLAGS" , "ENV" , "defines" , "defines1" , "defines01" , "have_cfile" , "have_cxxfile" , "have_ctype" , "have_cxxtype" , "have_csymbol" , "have_cxxsymbol" , "size_ctype" , "size_cxxtype" ] , "imports": { "artifacts": ["./", "../..", "field_artifacts"] , "compile-deps": ["./", "..", "compile-deps"] , "compiler-cc": ["./", "..", "compiler-cc"] , "compiler-cxx": ["./", "..", "compiler-cxx"] , "flags-cc": ["./", "..", "flags-cc"] , "flags-cxx": ["./", "..", "flags-cxx"] , "default-ENV": ["./", "..", "default-ENV"] , "default-PATH": ["./", "..", "default-PATH"] , "default-TOOLCHAIN": ["./", "..", "default-TOOLCHAIN"] , "default-NON_SYSTEM_TOOLS": ["./", "..", "default-NON_SYSTEM_TOOLS"] , "map_provider": ["./", "../..", "field_map_provider"] , "list_provider": ["./", "../..", "field_list_provider"] , "sh": ["./", "../../shell", "sh"] , "sh-PATH": ["./", "../../shell", "PATH"] } , "implicit": { "defaults": [["./", "..", "defaults"]] , "shell defaults": [["./", "../../shell", "defaults"]] } , "expression": { "type": "let*" , "bindings": [ ["name", {"type": "join", "$1": {"type": "FIELD", "name": "name"}}] , [ "stage" , { "type": "join" , "separator": "/" , "$1": {"type": "FIELD", "name": "stage"} } ] , [ "guard" , { "type": "assert_non_empty" , "msg": "Config header include guard may not be empty" , "$1": { "type": "join" , "separator": "_" , "$1": {"type": "FIELD", "name": "guard"} } } ] , [ "includes" , { "type": "to_subdir" , "subdir": "include" , "$1": { "type": "disjoint_map_union" , "msg": "Includes may not overlap" , "$1": [ { "type": "let*" , "bindings": [["fieldname", "hdrs"]] , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"} } , { "type": "let*" , "bindings": [["deps-fieldnames", ["deps"]]] , "body": {"type": "CALL_EXPRESSION", "name": "compile-deps"} } ] } } ] , ["TOOLCHAIN_DIR", "toolchain"] , ["TOOLCHAIN", {"type": "CALL_EXPRESSION", "name": "default-TOOLCHAIN"}] , [ "shell TOOLCHAIN" , { "type": "let*" , "bindings": [ ["fieldname", "shell defaults"] , ["provider", "TOOLCHAIN"] , ["default", {"type": "empty_map"}] ] , "body": {"type": "CALL_EXPRESSION", "name": "map_provider"} } ] , [ "TOOLCHAIN" , { "type": "disjoint_map_union" , "msg": "Shell and CC toolchain must not conflict" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "var", "name": "shell TOOLCHAIN"} ] } ] , [ "TOOLCHAIN" , { "type": "to_subdir" , "subdir": {"type": "var", "name": "TOOLCHAIN_DIR"} , "$1": {"type": "var", "name": "TOOLCHAIN"} } ] , [ "sh" , { "type": "let*" , "bindings": [["fieldname", "shell defaults"]] , "body": {"type": "CALL_EXPRESSION", "name": "sh"} } ] , [ "bin dirs" , { "type": "let*" , "bindings": [["fieldname", "shell defaults"], ["provider", "bin dirs"]] , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"} } ] , [ "bin dirs" , { "type": "foreach" , "range": {"type": "var", "name": "bin dirs"} , "body": { "type": "join" , "$1": [ "./" , {"type": "var", "name": "TOOLCHAIN_DIR"} , "/" , {"type": "var", "name": "_"} ] } } ] , [ "NON_SYSTEM_TOOLS" , {"type": "CALL_EXPRESSION", "name": "default-NON_SYSTEM_TOOLS"} ] , ["CC", {"type": "CALL_EXPRESSION", "name": "compiler-cc"}] , ["CXX", {"type": "CALL_EXPRESSION", "name": "compiler-cxx"}] , ["CFLAGS", {"type": "CALL_EXPRESSION", "name": "flags-cc"}] , ["CXXFLAGS", {"type": "CALL_EXPRESSION", "name": "flags-cxx"}] , [ "ENV" , { "type": "map_union" , "$1": [ {"type": "CALL_EXPRESSION", "name": "default-ENV"} , {"type": "var", "name": "ENV", "default": {"type": "empty_map"}} ] } ] , [ "ENV_PATH" , { "type": "lookup" , "map": {"type": "var", "name": "ENV"} , "key": "PATH" } ] , [ "ENV" , { "type": "map_union" , "$1": [ {"type": "var", "name": "ENV"} , { "type": "singleton_map" , "key": "PATH" , "value": { "type": "join" , "separator": ":" , "$1": { "type": "++" , "$1": [ {"type": "CALL_EXPRESSION", "name": "default-PATH"} , { "type": "if" , "cond": {"type": "var", "name": "ENV_PATH"} , "then": [{"type": "var", "name": "ENV_PATH"}] } , { "type": "let*" , "bindings": [["fieldname", "shell defaults"]] , "body": {"type": "CALL_EXPRESSION", "name": "sh-PATH"} } , {"type": "var", "name": "bin dirs"} ] } } } ] } ] , [ "c.flags" , { "type": "BLOB" , "data": { "type": "join" , "separator": "\n" , "$1": {"type": "var", "name": "CFLAGS"} } } ] , [ "cxx.flags" , { "type": "BLOB" , "data": { "type": "join" , "separator": "\n" , "$1": {"type": "var", "name": "CXXFLAGS"} } } ] , [ "file_check.sh" , { "type": "BLOB" , "data": { "type": "join" , "separator": "\n" , "$1": [ "set -eu" , "[ $# -ge 4 ]" , "CC=$1" , "LANG=$2" , "DEF=$3" , "HDR=$4" , "DEFINE=\"/* #undef $DEF */\"" , "echo \"#include \\\"$HDR\\\"\" > test.$LANG" , "if $CC @$LANG.flags -c test.$LANG -I ./include 2>/dev/null; then DEFINE=\"#define $DEF 1\"; fi" , "echo \"$DEFINE\n\" > out.def" ] } } ] , [ "type_check.sh" , { "type": "BLOB" , "data": { "type": "join" , "separator": "\n" , "$1": [ "set -eu" , "[ $# -ge 4 ]" , "CC=$1" , "LANG=$2" , "DEF=$3" , "TYPE=$4" , "INC=\"\"" , "DEFINE=\"/* #undef $DEF */\"" , "for HDR in \"\" \"sys/types.h\" \"stdint.h\" \"stddef.h\"; do" , " if [ -n \"$HDR\" ]; then INC=\"#include \\\"$HDR\\\"\"; fi" , " cat > test.$LANG << EOF" , "$INC" , "$TYPE* __test;" , "EOF" , " if $CC @$LANG.flags -c test.$LANG -I ./include 2>/dev/null; then" , " DEFINE=\"#define $DEF 1\"" , " break" , " fi" , "done" , "echo \"$DEFINE\n\" > out.def" ] } } ] , [ "symbol_check.sh" , { "type": "BLOB" , "data": { "type": "join" , "separator": "\n" , "$1": [ "set -eu" , "[ $# -ge 4 ]" , "CC=$1" , "shift" , "LANG=$1" , "shift" , "DEF=$1" , "shift" , "SYMBOL=$1" , "shift" , "DEFINE=\"/* #undef $DEF */\"" , "for INC in \"$@\"; do" , " cat > test_symbol.$LANG << EOF" , "#include \"$INC\"" , "void* __test = &$SYMBOL;" , "EOF" , " if $CC @$LANG.flags -c test_symbol.$LANG -I ./include 2>/dev/null; then" , " DEFINE=\"#define $DEF 1\"" , " break" , " fi" , " cat > test_macro.$LANG << EOF" , "#include \"$INC\"" , "#ifndef $SYMBOL" , "#error not defined as macro" , "#endif" , "EOF" , " if $CC @$LANG.flags -c test_macro.$LANG -I ./include 2>/dev/null; then" , " DEFINE=\"#define $DEF 1\"" , " break" , " fi" , "done" , "echo \"$DEFINE\n\" > out.def" ] } } ] , [ "size_check.sh" , { "type": "BLOB" , "data": { "type": "join" , "separator": "\n" , "$1": [ "set -eu" , "[ $# -ge 4 ]" , "CC=$1" , "shift" , "LANG=$1" , "shift" , "DEF=$1" , "shift" , "TYPE=$1" , "shift" , "INC=\"\"" , "for HDR in \"\" \"sys/types.h\" \"stdint.h\" \"stddef.h\"; do" , " if [ -n \"$HDR\" ]; then INC=\"#include \\\"$HDR\\\"\"; fi" , " for SIZE in \"$@\"; do" , " SIZE=$(printf %.0f $SIZE)" , " cat > test.$LANG << EOF" , "$INC" , "char __test[(sizeof($TYPE) == $SIZE) ? 1 : -1];" , "EOF" , " if $CC @$LANG.flags -c test.$LANG -I ./include 2>/dev/null; then" , " DEFINE=\"#define $DEF $SIZE\"" , " echo \"$DEFINE\n\" > out.def" , " exit 0" , " fi" , " done" , "done" , "exit 1" ] } } ] , [ "guard.def" , { "type": "BLOB" , "data": { "type": "join" , "separator": "\n" , "$1": [ { "type": "join" , "separator": " " , "$1": ["#ifndef", {"type": "var", "name": "guard"}] } , { "type": "join" , "separator": " " , "$1": ["#define", {"type": "var", "name": "guard"}] } , "\n\n" ] } } ] , [ "plain.def" , { "type": "BLOB" , "data": { "type": "join" , "$1": { "type": "foreach" , "range": {"type": "var", "name": "defines", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'defines' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "val" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] ] , "body": { "type": "join" , "separator": " " , "$1": { "type": "case*" , "expr": {"type": "var", "name": "val"} , "case": [ [ null , [ "/* #undef" , {"type": "var", "name": "def"} , "*/\n\n" ] ] ] , "default": [ "#define" , {"type": "var", "name": "def"} , { "type": "join" , "$1": [{"type": "var", "name": "val"}, "\n\n"] } ] } } } } } } ] , [ "int1.def" , { "type": "BLOB" , "data": { "type": "join" , "$1": { "type": "foreach" , "range": {"type": "var", "name": "defines1", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'defines1' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "val" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] ] , "body": { "type": "join" , "separator": " " , "$1": { "type": "if" , "cond": {"type": "var", "name": "val"} , "then": ["#define", {"type": "var", "name": "def"}, "1\n\n"] , "else": ["/* #undef", {"type": "var", "name": "def"}, "*/\n\n"] } } } } } } ] , [ "int01.def" , { "type": "BLOB" , "data": { "type": "join" , "$1": { "type": "foreach" , "range": {"type": "var", "name": "defines01", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'defines01' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "val" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] ] , "body": { "type": "join" , "separator": " " , "$1": [ "#define" , {"type": "var", "name": "def"} , { "type": "if" , "cond": {"type": "var", "name": "val"} , "then": "1\n\n" , "else": "0\n\n" } ] } } } } } ] , [ "cfile-defs" , { "type": "foreach" , "range": {"type": "var", "name": "have_cfile", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'have_cfile' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "val" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] ] , "body": { "type": "lookup" , "key": "out.def" , "map": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "env", "vars": ["file_check.sh", "c.flags"]} , {"type": "var", "name": "includes"} ] } , "cmd": [ {"type": "var", "name": "sh"} , "./file_check.sh" , {"type": "var", "name": "CC"} , "c" , {"type": "var", "name": "def"} , {"type": "var", "name": "val"} ] , "env": {"type": "var", "name": "ENV"} , "outs": ["out.def"] } } } } ] , [ "cxxfile-defs" , { "type": "foreach" , "range": {"type": "var", "name": "have_cxxfile", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'have_cxxfile' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "val" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] ] , "body": { "type": "lookup" , "key": "out.def" , "map": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "env", "vars": ["file_check.sh", "cxx.flags"]} , {"type": "var", "name": "includes"} ] } , "cmd": [ {"type": "var", "name": "sh"} , "./file_check.sh" , {"type": "var", "name": "CXX"} , "cxx" , {"type": "var", "name": "def"} , {"type": "var", "name": "val"} ] , "env": {"type": "var", "name": "ENV"} , "outs": ["out.def"] } } } } ] , [ "ctype-defs" , { "type": "foreach" , "range": {"type": "var", "name": "have_ctype", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'have_ctype' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "type" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] ] , "body": { "type": "lookup" , "key": "out.def" , "map": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "env", "vars": ["type_check.sh", "c.flags"]} , {"type": "var", "name": "includes"} ] } , "cmd": [ {"type": "var", "name": "sh"} , "./type_check.sh" , {"type": "var", "name": "CC"} , "c" , {"type": "var", "name": "def"} , {"type": "var", "name": "type"} ] , "env": {"type": "var", "name": "ENV"} , "outs": ["out.def"] } } } } ] , [ "cxxtype-defs" , { "type": "foreach" , "range": {"type": "var", "name": "have_cxxtype", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'have_cxxtype' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "type" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] ] , "body": { "type": "lookup" , "key": "out.def" , "map": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "env", "vars": ["type_check.sh", "cxx.flags"]} , {"type": "var", "name": "includes"} ] } , "cmd": [ {"type": "var", "name": "sh"} , "./type_check.sh" , {"type": "var", "name": "CXX"} , "cxx" , {"type": "var", "name": "def"} , {"type": "var", "name": "type"} ] , "env": {"type": "var", "name": "ENV"} , "outs": ["out.def"] } } } } ] , [ "csymbol-defs" , { "type": "foreach" , "range": {"type": "var", "name": "have_csymbol", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'have_csymbol' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "sym, hdrs" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] , [ "sym" , { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "sym, hdrs"} } ] , [ "hdrs" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "sym, hdrs"} } ] ] , "body": { "type": "lookup" , "key": "out.def" , "map": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "env", "vars": ["symbol_check.sh", "c.flags"]} , {"type": "var", "name": "includes"} ] } , "cmd": { "type": "++" , "$1": [ [ {"type": "var", "name": "sh"} , "./symbol_check.sh" , {"type": "var", "name": "CC"} , "c" , {"type": "var", "name": "def"} , {"type": "var", "name": "sym"} ] , {"type": "var", "name": "hdrs"} ] } , "env": {"type": "var", "name": "ENV"} , "outs": ["out.def"] } } } } ] , [ "cxxsymbol-defs" , { "type": "foreach" , "range": {"type": "var", "name": "have_cxxsymbol", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'have_csymbol' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "sym, hdrs" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] , [ "sym" , { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "sym, hdrs"} } ] , [ "hdrs" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "sym, hdrs"} } ] ] , "body": { "type": "lookup" , "key": "out.def" , "map": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "env", "vars": ["symbol_check.sh", "cxx.flags"]} , {"type": "var", "name": "includes"} ] } , "cmd": { "type": "++" , "$1": [ [ {"type": "var", "name": "sh"} , "./symbol_check.sh" , {"type": "var", "name": "CXX"} , "cxx" , {"type": "var", "name": "def"} , {"type": "var", "name": "sym"} ] , {"type": "var", "name": "hdrs"} ] } , "env": {"type": "var", "name": "ENV"} , "outs": ["out.def"] } } } } ] , [ "csize-defs" , { "type": "foreach" , "range": {"type": "var", "name": "size_ctype", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'have_csymbol' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "type, sizes" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] , [ "type" , { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "type, sizes"} } ] , [ "sizes" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "type, sizes"} } ] ] , "body": { "type": "lookup" , "key": "out.def" , "map": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "env", "vars": ["size_check.sh", "c.flags"]} , {"type": "var", "name": "includes"} ] } , "cmd": { "type": "++" , "$1": [ [ {"type": "var", "name": "sh"} , "./size_check.sh" , {"type": "var", "name": "CC"} , "c" , {"type": "var", "name": "def"} , {"type": "var", "name": "type"} ] , { "type": "foreach" , "var": "size" , "range": {"type": "var", "name": "sizes"} , "body": { "type": "json_encode" , "$1": {"type": "var", "name": "size"} } } ] } , "env": {"type": "var", "name": "ENV"} , "outs": ["out.def"] } } } } ] , [ "cxxsize-defs" , { "type": "foreach" , "range": {"type": "var", "name": "size_cxxtype", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "def" , { "type": "assert_non_empty" , "msg": "Define name in 'have_csymbol' may not be empty" , "$1": { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } } ] , [ "type, sizes" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] , [ "type" , { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "type, sizes"} } ] , [ "sizes" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "type, sizes"} } ] ] , "body": { "type": "lookup" , "key": "out.def" , "map": { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "env", "vars": ["size_check.sh", "cxx.flags"]} , {"type": "var", "name": "includes"} ] } , "cmd": { "type": "++" , "$1": [ [ {"type": "var", "name": "sh"} , "./size_check.sh" , {"type": "var", "name": "CXX"} , "cxx" , {"type": "var", "name": "def"} , {"type": "var", "name": "type"} ] , { "type": "foreach" , "var": "size" , "range": {"type": "var", "name": "sizes"} , "body": { "type": "json_encode" , "$1": {"type": "var", "name": "size"} } } ] } , "env": {"type": "var", "name": "ENV"} , "outs": ["out.def"] } } } } ] , ["end.def", {"type": "BLOB", "data": "\n#endif\n"}] , [ "definitions" , { "type": "enumerate" , "$1": { "type": "++" , "$1": [ [ {"type": "var", "name": "guard.def"} , {"type": "var", "name": "int1.def"} , {"type": "var", "name": "int01.def"} ] , {"type": "var", "name": "cfile-defs"} , {"type": "var", "name": "cxxfile-defs"} , {"type": "var", "name": "ctype-defs"} , {"type": "var", "name": "cxxtype-defs"} , {"type": "var", "name": "csymbol-defs"} , {"type": "var", "name": "cxxsymbol-defs"} , {"type": "var", "name": "csize-defs"} , {"type": "var", "name": "cxxsize-defs"} , [ {"type": "var", "name": "plain.def"} , {"type": "var", "name": "end.def"} ] ] } } ] , [ "outfile" , { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "TOOLCHAIN"} , {"type": "var", "name": "definitions"} ] } , "cmd": [ {"type": "var", "name": "sh"} , "-c" , { "type": "join" , "separator": " " , "$1": [ "cat" , { "type": "join_cmd" , "$1": { "type": "keys" , "$1": {"type": "var", "name": "definitions"} } } , "> out" ] } ] , "outs": ["out"] , "env": {"type": "var", "name": "ENV"} } ] , [ "outfile" , { "type": "to_subdir" , "subdir": {"type": "var", "name": "stage"} , "$1": { "type": "singleton_map" , "key": {"type": "var", "name": "name"} , "value": { "type": "lookup" , "key": "out" , "map": {"type": "var", "name": "outfile"} } } } ] ] , "body": { "type": "RESULT" , "artifacts": {"type": "var", "name": "outfile"} , "runfiles": {"type": "var", "name": "outfile"} } } } , "config_file": { "doc": [ "Generate a C/C++ config header from a given template" , "" , "Generate a C/C++ configuration header using defines specified via the" , "target configuration. In the usual case, a target using this rule is" , "configured by depending on it from a target that uses the built-in" , "\"configure\" rule." , "" , "The actual generation of the header file from the template" , "is done by the implicit dependency on the \"runner\" target which" , "can be changed globally by setting this target in the" , "target layer of this repository." ] , "field_doc": { "output": [ "Name of the header file to generate (incl. file name ext). Components are joined with /." ] , "input": ["The input configuration file, used as template."] , "magic_string": [ "The magic string (e.g., \"cmakedefine\") which identifies in which line" , "we have to \"#define\" or \"#undef\" variables according to what is" , "defined in the config field \"defines\"." ] , "@only": ["If set, only replace @VAR@ and not ${VAR}"] , "runner": ["The program generating the header file from the template."] } , "config_doc": { "defines": [ "Set a define to a specific value unless its value is \"null\". Must" , "contain a list of pairs. The first element of each pair is the define" , "name and the second argument is the value to set. Strings must be" , "properly escaped. Defines generated from this field are added last," , "so that they can refer to defines from other \"defines*\" values." ] } , "string_fields": ["magic_string", "@only", "output"] , "target_fields": ["input"] , "config_vars": ["defines"] , "imports": { "stage_singleton_field": ["", "stage_singleton_field"] , "default-PATH": ["./", "..", "default-PATH"] } , "implicit": {"runner": ["runner"], "defaults": [["./", "..", "defaults"]]} , "expression": { "type": "let*" , "bindings": [ [ "runner" , { "type": "let*" , "bindings": [["fieldname", "runner"], ["location", "runner"]] , "body": {"type": "CALL_EXPRESSION", "name": "stage_singleton_field"} } ] , [ "dict-defines" , { "type": "map_union" , "$1": { "type": "foreach" , "range": {"type": "var", "name": "defines", "default": []} , "var": "pair" , "body": { "type": "let*" , "bindings": [ [ "key" , { "type": "[]" , "index": 0 , "list": {"type": "var", "name": "pair"} } ] , [ "val" , { "type": "[]" , "index": -1 , "list": {"type": "var", "name": "pair"} } ] ] , "body": { "type": "singleton_map" , "key": {"type": "var", "name": "key"} , "value": {"type": "var", "name": "val"} } } } } ] , [ "magic_string" , { "type": "assert_non_empty" , "msg": "A non-empty string has to be provided for magic_string" , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "magic_string"}} } ] , [ "@only" , { "type": "if" , "cond": {"type": "FIELD", "name": "@only"} , "then": "true" , "else": "false" } ] , [ "param-blob" , { "type": "singleton_map" , "key": "param-file" , "value": { "type": "BLOB" , "data": { "type": "json_encode" , "$1": {"type": "var", "name": "dict-defines"} } } } ] , [ "input-blob" , { "type": "let*" , "bindings": [["fieldname", "input"], ["location", "input-file"]] , "body": {"type": "CALL_EXPRESSION", "name": "stage_singleton_field"} } ] , ["PATH", {"type": "CALL_EXPRESSION", "name": "default-PATH"}] , [ "ENV" , { "type": "if" , "cond": {"type": "var", "name": "PATH"} , "then": { "type": "singleton_map" , "key": "PATH" , "value": { "type": "join" , "separator": ":" , "$1": {"type": "var", "name": "PATH"} } } , "else": {"type": "empty_map"} } ] , [ "outfile" , { "type": "ACTION" , "inputs": { "type": "map_union" , "$1": [ {"type": "var", "name": "param-blob"} , {"type": "var", "name": "input-blob"} , {"type": "var", "name": "runner"} ] } , "cmd": [ "./runner" , "input-file" , "param-file" , {"type": "var", "name": "magic_string"} , {"type": "var", "name": "@only"} ] , "env": {"type": "var", "name": "ENV"} , "outs": ["out"] } ] , [ "outfile" , { "type": "singleton_map" , "key": { "type": "join" , "separator": "/" , "$1": {"type": "FIELD", "name": "output"} } , "value": { "type": "lookup" , "key": "out" , "map": {"type": "var", "name": "outfile"} } } ] ] , "body": { "type": "RESULT" , "artifacts": {"type": "var", "name": "outfile"} , "runfiles": {"type": "var", "name": "outfile"} } } } }