summaryrefslogtreecommitdiff
path: root/rules/CC
diff options
context:
space:
mode:
Diffstat (limited to 'rules/CC')
-rw-r--r--rules/CC/EXPRESSIONS1593
-rw-r--r--rules/CC/IDE/RULES96
-rw-r--r--rules/CC/RULES839
-rw-r--r--rules/CC/TARGETS11
-rw-r--r--rules/CC/auto/EXPRESSIONS32
-rw-r--r--rules/CC/auto/RULES955
-rw-r--r--rules/CC/prebuilt/EXPRESSIONS453
-rw-r--r--rules/CC/prebuilt/RULES147
-rwxr-xr-xrules/CC/prebuilt/read_pkgconfig.py75
-rw-r--r--rules/CC/proto/EXPRESSIONS308
-rw-r--r--rules/CC/proto/RULES93
-rw-r--r--rules/CC/test/RULES338
-rw-r--r--rules/CC/test/TARGETS1
-rwxr-xr-xrules/CC/test/test_runner.py69
14 files changed, 5010 insertions, 0 deletions
diff --git a/rules/CC/EXPRESSIONS b/rules/CC/EXPRESSIONS
new file mode 100644
index 0000000..5a425c7
--- /dev/null
+++ b/rules/CC/EXPRESSIONS
@@ -0,0 +1,1593 @@
+{ "default-CC":
+ { "vars": ["defaults-transition"]
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "join"
+ , "$1":
+ { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "defaults"]
+ , ["provider", "CC"]
+ , [ "transition"
+ , {"type": "var", "name": "defaults-transition", "default": null}
+ ]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+ }
+, "default-CXX":
+ { "vars": ["defaults-transition"]
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "join"
+ , "$1":
+ { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "defaults"]
+ , ["provider", "CXX"]
+ , [ "transition"
+ , {"type": "var", "name": "defaults-transition", "default": null}
+ ]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+ }
+, "default-AR":
+ { "vars": ["defaults-transition"]
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "join"
+ , "$1":
+ { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "defaults"]
+ , ["provider", "AR"]
+ , [ "transition"
+ , {"type": "var", "name": "defaults-transition", "default": null}
+ ]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+ }
+, "default-CFLAGS":
+ { "vars": ["defaults-transition"]
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "defaults"]
+ , ["provider", "CFLAGS"]
+ , [ "transition"
+ , {"type": "var", "name": "defaults-transition", "default": null}
+ ]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+, "default-CXXFLAGS":
+ { "vars": ["defaults-transition"]
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "defaults"]
+ , ["provider", "CXXFLAGS"]
+ , [ "transition"
+ , {"type": "var", "name": "defaults-transition", "default": null}
+ ]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+, "default-LDFLAGS":
+ { "vars": ["defaults-transition"]
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "defaults"]
+ , ["provider", "LDFLAGS"]
+ , [ "transition"
+ , {"type": "var", "name": "defaults-transition", "default": null}
+ ]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+, "default-ENV":
+ { "vars": ["defaults-transition"]
+ , "imports": {"provider_list": ["./", "..", "field_provider_list"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "defaults"]
+ , ["provider", "ENV"]
+ , [ "transition"
+ , {"type": "var", "name": "defaults-transition", "default": null}
+ ]
+ , ["default", {"type": "empty_map"}]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "provider_list"}
+ }
+ }
+, "defaults-base-provides":
+ { "doc": ["Query list-provider from 'base' targets (last wins)"]
+ , "vars": ["provider"]
+ , "vars_doc":
+ {"provider": ["The name of the list-provider in the provides map."]}
+ , "imports": {"provider_list": ["./", "..", "field_provider_list"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings": [["fieldname", "base"]]
+ , "body":
+ { "type": "foldl"
+ , "var": "next"
+ , "accum_var": "curr"
+ , "range": {"type": "CALL_EXPRESSION", "name": "provider_list"}
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "next"}
+ , "then": {"type": "var", "name": "next"}
+ , "else": {"type": "var", "name": "curr"}
+ }
+ }
+ }
+ }
+, "compile-deps":
+ { "doc": ["Collect compile dependencies (headers) from given target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames":
+ ["List of target_field names to collect dependencies from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports":
+ { "runfiles_list": ["./", "..", "field_runfiles_list"]
+ , "provider_list": ["./", "..", "field_provider_list"]
+ }
+ , "expression":
+ { "type": "disjoint_map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "deps-fieldnames"}
+ , "body":
+ { "type": "++"
+ , "$1":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "compile-deps"]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ , ["default", {"type": "empty_map"}]
+ ]
+ , "body":
+ [ {"type": "CALL_EXPRESSION", "name": "provider_list"}
+ , {"type": "CALL_EXPRESSION", "name": "runfiles_list"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+, "compile-args-deps":
+ { "doc": ["Collect compile arguments from given target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames":
+ ["List of target_field names to collect arguments from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "deps-fieldnames"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "compile-args"]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+ }
+ }
+, "link-deps":
+ { "doc": ["Collect link dependencies (libraries) from given target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames":
+ ["List of target_field names to collect dependencies from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports":
+ { "artifacts_list": ["./", "..", "field_artifacts_list"]
+ , "provider_list": ["./", "..", "field_provider_list"]
+ }
+ , "expression":
+ { "type": "disjoint_map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "deps-fieldnames"}
+ , "body":
+ { "type": "++"
+ , "$1":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "link-deps"]
+ , ["default", {"type": "empty_map"}]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body":
+ [ {"type": "CALL_EXPRESSION", "name": "provider_list"}
+ , {"type": "CALL_EXPRESSION", "name": "artifacts_list"}
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+, "link-args-deps":
+ { "doc": ["Collect linker arguments from given target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames":
+ ["List of target_field names to collect arguments from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "deps-fieldnames"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "link-args"]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+ }
+ }
+, "run-libs-deps":
+ { "doc": ["Collect runtime libraries from given target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames":
+ ["List of target_field names to collect dependencies from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"provider_list": ["./", "..", "field_provider_list"]}
+ , "expression":
+ { "type": "to_subdir"
+ , "flat": true
+ , "$1":
+ { "type": "disjoint_map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "deps-fieldnames"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "run-libs"]
+ , ["default", {"type": "empty_map"}]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "provider_list"}
+ }
+ }
+ }
+ }
+ }
+ }
+, "run-libs-args-deps":
+ { "doc":
+ ["Collect runtime libraries link arguments from given target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames":
+ ["List of target_field names to collect arguments from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"list_provider": ["./", "..", "field_list_provider"]}
+ , "expression":
+ { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "deps-fieldnames"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "run-libs-args"]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+ }
+ }
+, "pkg-map-provider-deps":
+ { "doc": ["Collect maps from provider \"package\" for given target_fields"]
+ , "vars": ["pkg-key", "deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "pkg-key": ["Key to lookup in provider \"package\"."]
+ , "deps-fieldnames": ["List of target_field names to collect maps from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"provider_list": ["./", "..", "field_provider_list"]}
+ , "expression":
+ { "type": "disjoint_map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "deps-fieldnames"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "package"]
+ , ["default", {"type": "empty_map"}]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body":
+ { "type": "foreach"
+ , "range": {"type": "CALL_EXPRESSION", "name": "provider_list"}
+ , "var": "map"
+ , "body":
+ { "type": "lookup"
+ , "key": {"type": "var", "name": "pkg-key"}
+ , "map": {"type": "var", "name": "map"}
+ , "default": {"type": "empty_map"}
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+, "cflags-files-deps":
+ { "doc": ["Collect cflags files from target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames": ["List of target_field names to collect files from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"pkg-provider": "pkg-map-provider-deps"}
+ , "expression":
+ { "type": "let*"
+ , "bindings": [["pkg-key", "cflags-files"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "pkg-provider"}
+ }
+ }
+, "ldflags-files-deps":
+ { "doc": ["Collect cflags files from target_fields"]
+ , "vars": ["deps-fieldnames", "deps-transition"]
+ , "vars_doc":
+ { "deps-fieldnames": ["List of target_field names to collect files from."]
+ , "deps-transition":
+ ["The optional configuration transition for the targets."]
+ }
+ , "imports": {"pkg-provider": "pkg-map-provider-deps"}
+ , "expression":
+ { "type": "let*"
+ , "bindings": [["pkg-key", "ldflags-files"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "pkg-provider"}
+ }
+ }
+, "pkg-prefix-lib-paths":
+ { "doc": ["Detect ldflags referring to local libs and prefix them."]
+ , "vars": ["pkg-ldflags", "pkg-libs", "flat-libs", "lib-prefix"]
+ , "imports": {"contains": ["", "contains"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [["list", {"type": "keys", "$1": {"type": "var", "name": "pkg-libs"}}]]
+ , "body":
+ { "type": "foreach"
+ , "var": "item"
+ , "range": {"type": "var", "name": "pkg-ldflags"}
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "CALL_EXPRESSION", "name": "contains"}
+ , "then":
+ { "type": "join"
+ , "$1":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "flat-libs"}
+ , "then":
+ [ "-l:"
+ , {"type": "basename", "$1": {"type": "var", "name": "item"}}
+ ]
+ , "else":
+ [ {"type": "var", "name": "lib-prefix"}
+ , "/"
+ , {"type": "var", "name": "item"}
+ ]
+ }
+ }
+ , "else": {"type": "var", "name": "item"}
+ }
+ }
+ }
+ }
+, "pkg-prefix-flag-paths":
+ { "doc": ["Detect flags referring to local flag files and prefix them."]
+ , "vars": ["flags", "pkg-flag-files", "flag-prefix"]
+ , "imports": {"contains": ["", "contains"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "list"
+ , {"type": "keys", "$1": {"type": "var", "name": "pkg-flag-files"}}
+ ]
+ , ["list_prefix", "@"]
+ ]
+ , "body":
+ { "type": "foreach"
+ , "var": "item"
+ , "range": {"type": "var", "name": "flags"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [["flag-file", {"type": "CALL_EXPRESSION", "name": "contains"}]]
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "flag-file"}
+ , "then":
+ { "type": "join"
+ , "$1":
+ [ "@"
+ , {"type": "var", "name": "flag-prefix"}
+ , "/"
+ , {"type": "var", "name": "flag-file"}
+ ]
+ }
+ , "else": {"type": "var", "name": "item"}
+ }
+ }
+ }
+ }
+ }
+, "pkg-config":
+ { "vars":
+ [ "pkg-name"
+ , "pkg-prefix"
+ , "pkg-version"
+ , "pkg-cflags"
+ , "pkg-ldflags"
+ , "pkg-flag-files"
+ , "pkg-libs"
+ , "flat-libs"
+ , "pc-install-dir"
+ ]
+ , "imports":
+ { "pkg-prefix-lib-paths": "pkg-prefix-lib-paths"
+ , "pkg-prefix-flag-paths": "pkg-prefix-flag-paths"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["lib-prefix", "${libdir}"]
+ , [ "pkg-ldflags"
+ , {"type": "CALL_EXPRESSION", "name": "pkg-prefix-lib-paths"}
+ ]
+ , [ "flag-prefix"
+ , { "type": "join"
+ , "$1": ["${prefix}/", {"type": "var", "name": "pc-install-dir"}]
+ }
+ ]
+ , ["flags", {"type": "var", "name": "pkg-cflags"}]
+ , [ "pkg-cflags"
+ , {"type": "CALL_EXPRESSION", "name": "pkg-prefix-flag-paths"}
+ ]
+ , ["flags", {"type": "var", "name": "pkg-ldflags"}]
+ , [ "pkg-ldflags"
+ , {"type": "CALL_EXPRESSION", "name": "pkg-prefix-flag-paths"}
+ ]
+ ]
+ , "body":
+ { "type": "singleton_map"
+ , "key":
+ {"type": "join", "$1": [{"type": "var", "name": "pkg-name"}, ".pc"]}
+ , "value":
+ { "type": "BLOB"
+ , "data":
+ { "type": "join"
+ , "separator": "\n"
+ , "$1":
+ [ { "type": "join"
+ , "$1":
+ [ "prefix="
+ , {"type": "var", "name": "pkg-prefix", "default": "/"}
+ ]
+ }
+ , "libdir=${prefix}/lib"
+ , "includedir=${prefix}/include"
+ , { "type": "join"
+ , "$1": ["Name: ", {"type": "var", "name": "pkg-name"}]
+ }
+ , { "type": "join"
+ , "$1":
+ [ "Version: "
+ , {"type": "var", "name": "pkg-version", "default": "unknown"}
+ ]
+ }
+ , { "type": "join"
+ , "$1":
+ [ "Description: Pkg-config for "
+ , {"type": "var", "name": "pkg-name"}
+ , ", generated by JustBuild"
+ ]
+ }
+ , "URL: unknown"
+ , { "type": "join"
+ , "separator": " "
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["Cflags:", "-I${includedir}"]
+ , {"type": "var", "name": "pkg-cflags"}
+ ]
+ }
+ }
+ , { "type": "join"
+ , "separator": " "
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["Libs:"]
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "flat-libs"}
+ , "then": ["-L${libdir}"]
+ }
+ , {"type": "var", "name": "pkg-ldflags"}
+ ]
+ }
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+, "objects":
+ { "vars":
+ [ "COMPILER"
+ , "COMPILE_FLAGS"
+ , "ENV"
+ , "srcs"
+ , "hdrs"
+ , "private-hdrs"
+ , "compile-deps"
+ , "cflags-files"
+ ]
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "include tree"
+ , { "type": "singleton_map"
+ , "key": "include"
+ , "value":
+ {"type": "TREE", "$1": {"type": "var", "name": "compile-deps"}}
+ }
+ ]
+ , [ "all hdrs"
+ , { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "include tree"}
+ , { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1":
+ { "type": "disjoint_map_union"
+ , "$1":
+ [ {"type": "var", "name": "hdrs"}
+ , {"type": "var", "name": "private-hdrs"}
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ ]
+ , "body":
+ { "type": "map_union"
+ , "$1":
+ { "type": "foreach_map"
+ , "var_key": "src_name"
+ , "var_val": "src_val"
+ , "range": {"type": "var", "name": "srcs"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ [ "work src_name"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": ["work", {"type": "var", "name": "src_name"}]
+ }
+ ]
+ , [ "inputs"
+ , { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "all hdrs"}
+ , { "type": "singleton_map"
+ , "key": {"type": "var", "name": "work src_name"}
+ , "value": {"type": "var", "name": "src_val"}
+ }
+ , { "type": "var"
+ , "name": "cflags-files"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ }
+ ]
+ , [ "out"
+ , { "type": "change_ending"
+ , "$1": {"type": "var", "name": "src_name"}
+ , "ending": ".o"
+ }
+ ]
+ , [ "work out"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": ["work", {"type": "var", "name": "out"}]
+ }
+ ]
+ , [ "action output"
+ , { "type": "ACTION"
+ , "outs": [{"type": "var", "name": "work out"}]
+ , "inputs": {"type": "var", "name": "inputs"}
+ , "env":
+ { "type": "var"
+ , "name": "ENV"
+ , "default": {"type": "empty_map"}
+ }
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ [{"type": "var", "name": "COMPILER"}]
+ , {"type": "var", "name": "COMPILE_FLAGS"}
+ , ["-I", "work", "-isystem", "include"]
+ , ["-c", {"type": "var", "name": "work src_name"}]
+ , ["-o", {"type": "var", "name": "work out"}]
+ ]
+ }
+ }
+ ]
+ , [ "staged output artifact"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "foreach_map"
+ , "range": {"type": "var", "name": "action output"}
+ , "var_val": "object"
+ , "body":
+ { "type": "singleton_map"
+ , "key": {"type": "var", "name": "out"}
+ , "value": {"type": "var", "name": "object"}
+ }
+ }
+ }
+ ]
+ ]
+ , "body": {"type": "var", "name": "staged output artifact"}
+ }
+ }
+ }
+ }
+ }
+, "compiler-cc":
+ { "vars": ["CC", "defaults-transition"]
+ , "imports": {"default-CC": "default-CC"}
+ , "expression":
+ { "type": "var"
+ , "name": "CC"
+ , "default": {"type": "CALL_EXPRESSION", "name": "default-CC"}
+ }
+ }
+, "compiler-cxx":
+ { "vars": ["CXX", "defaults-transition"]
+ , "imports": {"default-CXX": "default-CXX"}
+ , "expression":
+ { "type": "var"
+ , "name": "CXX"
+ , "default": {"type": "CALL_EXPRESSION", "name": "default-CXX"}
+ }
+ }
+, "compiler":
+ { "vars": ["CC", "CXX", "pure C", "defaults-transition"]
+ , "imports": {"compiler-cc": "compiler-cc", "compiler-cxx": "compiler-cxx"}
+ , "expression":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "pure C"}
+ , "then": {"type": "CALL_EXPRESSION", "name": "compiler-cc"}
+ , "else": {"type": "CALL_EXPRESSION", "name": "compiler-cxx"}
+ }
+ }
+, "flags-cc":
+ { "vars":
+ [ "CFLAGS"
+ , "ADD_CFLAGS"
+ , "BUILD_POSITION_INDEPENDENT"
+ , "defaults-transition"
+ ]
+ , "imports": {"default-CFLAGS": "default-CFLAGS"}
+ , "expression":
+ { "type": "++"
+ , "$1":
+ [ { "type": "if"
+ , "cond": {"type": "var", "name": "BUILD_POSITION_INDEPENDENT"}
+ , "then": ["-fPIC"]
+ }
+ , { "type": "var"
+ , "name": "CFLAGS"
+ , "default": {"type": "CALL_EXPRESSION", "name": "default-CFLAGS"}
+ }
+ , {"type": "var", "name": "ADD_CFLAGS", "default": []}
+ ]
+ }
+ }
+, "flags-cxx":
+ { "vars":
+ [ "CXXFLAGS"
+ , "ADD_CXXFLAGS"
+ , "BUILD_POSITION_INDEPENDENT"
+ , "defaults-transition"
+ ]
+ , "imports": {"default-CXXFLAGS": "default-CXXFLAGS"}
+ , "expression":
+ { "type": "++"
+ , "$1":
+ [ { "type": "if"
+ , "cond": {"type": "var", "name": "BUILD_POSITION_INDEPENDENT"}
+ , "then": ["-fPIC"]
+ }
+ , { "type": "var"
+ , "name": "CXXFLAGS"
+ , "default": {"type": "CALL_EXPRESSION", "name": "default-CXXFLAGS"}
+ }
+ , {"type": "var", "name": "ADD_CXXFLAGS", "default": []}
+ ]
+ }
+ }
+, "flags":
+ { "vars":
+ [ "CFLAGS"
+ , "CXXFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "BUILD_POSITION_INDEPENDENT"
+ , "pure C"
+ , "defaults-transition"
+ ]
+ , "imports": {"flags-cc": "flags-cc", "flags-cxx": "flags-cxx"}
+ , "expression":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "pure C"}
+ , "then": {"type": "CALL_EXPRESSION", "name": "flags-cc"}
+ , "else": {"type": "CALL_EXPRESSION", "name": "flags-cxx"}
+ }
+ }
+, "lib artifact":
+ { "vars":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "AR"
+ , "ENV"
+ , "BUILD_POSITION_INDEPENDENT"
+ , "name"
+ , "pure C"
+ , "srcs"
+ , "hdrs"
+ , "private-hdrs"
+ , "stage"
+ , "compile-deps"
+ , "compile-args"
+ , "cflags-files"
+ , "defaults-transition"
+ ]
+ , "imports":
+ { "compiler": "compiler"
+ , "flags": "flags"
+ , "objects": "objects"
+ , "default-AR": "default-AR"
+ , "default-ENV": "default-ENV"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["COMPILER", {"type": "CALL_EXPRESSION", "name": "compiler"}]
+ , [ "COMPILE_FLAGS"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "flags"}
+ , {"type": "var", "name": "compile-args"}
+ ]
+ }
+ ]
+ , [ "AR"
+ , { "type": "var"
+ , "name": "AR"
+ , "default": {"type": "CALL_EXPRESSION", "name": "default-AR"}
+ }
+ ]
+ , [ "ENV"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "default-ENV"}
+ , [ { "type": "var"
+ , "name": "ENV"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ ]
+ }
+ }
+ ]
+ , ["objects", {"type": "CALL_EXPRESSION", "name": "objects"}]
+ , [ "base name"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "objects"}
+ , "then":
+ { "type": "assert_non_empty"
+ , "msg": "A name has to be provided for non-header-only libraries"
+ , "$1": {"type": "var", "name": "name"}
+ }
+ , "else": {"type": "var", "name": "name"}
+ }
+ ]
+ , [ "libname"
+ , { "type": "join"
+ , "$1": ["lib", {"type": "var", "name": "base name"}, ".a"]
+ }
+ ]
+ , [ "libpath"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "stage"}
+ , "then":
+ { "type": "join"
+ , "separator": "/"
+ , "$1":
+ [ {"type": "var", "name": "stage"}
+ , {"type": "var", "name": "libname"}
+ ]
+ }
+ , "else": {"type": "var", "name": "libname"}
+ }
+ ]
+ , [ "lib"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "objects"}
+ , "else": {"type": "empty_map"}
+ , "then":
+ { "type": "ACTION"
+ , "outs": [{"type": "var", "name": "libpath"}]
+ , "inputs": {"type": "var", "name": "objects"}
+ , "env":
+ {"type": "var", "name": "ENV", "default": {"type": "empty_map"}}
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ [ {"type": "var", "name": "AR", "default": "ar"}
+ , "cqs"
+ , {"type": "var", "name": "libpath"}
+ ]
+ , {"type": "keys", "$1": {"type": "var", "name": "objects"}}
+ ]
+ }
+ }
+ }
+ ]
+ ]
+ , "body": {"type": "var", "name": "lib"}
+ }
+ }
+, "lib result":
+ { "vars":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "AR"
+ , "ENV"
+ , "BUILD_POSITION_INDEPENDENT"
+ , "name"
+ , "pure C"
+ , "srcs"
+ , "hdrs"
+ , "private-hdrs"
+ , "cflags"
+ , "private-cflags"
+ , "ldflags"
+ , "private-ldflags"
+ , "stage"
+ , "pkg-name"
+ , "extra-provides"
+ , "public-fieldnames"
+ , "private-fieldnames"
+ ]
+ , "imports":
+ { "compile-deps": "compile-deps"
+ , "compile-args-deps": "compile-args-deps"
+ , "link-deps": "link-deps"
+ , "link-args-deps": "link-args-deps"
+ , "run-libs-deps": "run-libs-deps"
+ , "run-libs-args-deps": "run-libs-args-deps"
+ , "cflags-files-deps": "cflags-files-deps"
+ , "ldflags-files-deps": "ldflags-files-deps"
+ , "lib artifact": "lib artifact"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["deps-fieldnames", {"type": "var", "name": "private-fieldnames"}]
+ , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
+ , [ "compile-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "cflags"}
+ , {"type": "var", "name": "private-cflags"}
+ , {"type": "CALL_EXPRESSION", "name": "compile-args-deps"}
+ ]
+ }
+ }
+ ]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
+ , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
+ , ["lib", {"type": "CALL_EXPRESSION", "name": "lib artifact"}]
+ , [ "link-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "keys", "$1": {"type": "var", "name": "lib"}}
+ , {"type": "var", "name": "ldflags", "default": []}
+ , {"type": "var", "name": "private-ldflags", "default": []}
+ , {"type": "CALL_EXPRESSION", "name": "link-args-deps"}
+ ]
+ }
+ }
+ ]
+ , ["run-libs", {"type": "CALL_EXPRESSION", "name": "run-libs-deps"}]
+ , [ "run-libs-args"
+ , { "type": "nub_right"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "run-libs-args-deps"}
+ }
+ ]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
+ , ["deps-fieldnames", {"type": "var", "name": "public-fieldnames"}]
+ , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
+ , [ "compile-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "cflags"}
+ , {"type": "CALL_EXPRESSION", "name": "compile-args-deps"}
+ ]
+ }
+ }
+ ]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
+ , [ "package"
+ , { "type": "let*"
+ , "bindings": [["name", {"type": "var", "name": "pkg-name"}]]
+ , "body":
+ {"type": "env", "vars": ["name", "cflags-files", "ldflags-files"]}
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts": {"type": "var", "name": "lib"}
+ , "runfiles": {"type": "var", "name": "hdrs"}
+ , "provides":
+ { "type": "map_union"
+ , "$1":
+ [ { "type": "env"
+ , "vars":
+ [ "compile-deps"
+ , "compile-args"
+ , "link-deps"
+ , "link-args"
+ , "run-libs"
+ , "run-libs-args"
+ , "package"
+ ]
+ }
+ , { "type": "var"
+ , "name": "extra-provides"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ }
+ }
+ }
+ }
+, "shared artifact":
+ { "vars":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "LDFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "ADD_LDFLAGS"
+ , "ENV"
+ , "name"
+ , "pure C"
+ , "srcs"
+ , "hdrs"
+ , "private-hdrs"
+ , "soversion"
+ , "compile-deps"
+ , "compile-args"
+ , "link-deps"
+ , "link-args"
+ , "run-libs"
+ , "run-libs-args"
+ , "cflags-files"
+ , "ldflags-files"
+ , "defaults-transition"
+ ]
+ , "imports":
+ { "compiler": "compiler"
+ , "flags": "flags"
+ , "objects": "objects"
+ , "default-LDFLAGS": "default-LDFLAGS"
+ , "default-ENV": "default-ENV"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["BUILD_POSITION_INDEPENDENT", true]
+ , ["COMPILER", {"type": "CALL_EXPRESSION", "name": "compiler"}]
+ , [ "COMPILE_FLAGS"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "flags"}
+ , {"type": "var", "name": "compile-args"}
+ ]
+ }
+ ]
+ , [ "LDFLAGS"
+ , { "type": "++"
+ , "$1":
+ [ { "type": "var"
+ , "name": "LDFLAGS"
+ , "default":
+ {"type": "CALL_EXPRESSION", "name": "default-LDFLAGS"}
+ }
+ , {"type": "var", "name": "ADD_LDFLAGS", "default": []}
+ ]
+ }
+ ]
+ , [ "ENV"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "default-ENV"}
+ , [ { "type": "var"
+ , "name": "ENV"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ ]
+ }
+ }
+ ]
+ , ["objects", {"type": "CALL_EXPRESSION", "name": "objects"}]
+ , [ "base name"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "objects"}
+ , "then":
+ { "type": "assert_non_empty"
+ , "msg": "A name has to be provided for non-header-only libraries"
+ , "$1": {"type": "var", "name": "name"}
+ }
+ , "else": {"type": "var", "name": "name"}
+ }
+ ]
+ , [ "libname"
+ , { "type": "join"
+ , "$1": ["lib", {"type": "var", "name": "base name"}, ".so"]
+ }
+ ]
+ , [ "libname"
+ , { "type": "join"
+ , "separator": "."
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ [{"type": "var", "name": "libname"}]
+ , {"type": "var", "name": "soversion"}
+ ]
+ }
+ }
+ ]
+ , [ "lib"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "objects"}
+ , "else": {"type": "empty_map"}
+ , "then":
+ { "type": "ACTION"
+ , "outs": [{"type": "var", "name": "libname"}]
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "objects"}
+ , {"type": "var", "name": "link-deps"}
+ , {"type": "var", "name": "run-libs"}
+ , { "type": "var"
+ , "name": "cflags-files"
+ , "default": {"type": "empty_map"}
+ }
+ , { "type": "var"
+ , "name": "ldflags-files"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ }
+ , "env":
+ {"type": "var", "name": "ENV", "default": {"type": "empty_map"}}
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ [ {"type": "var", "name": "COMPILER"}
+ , "-shared"
+ , "-Wl,-rpath,$ORIGIN"
+ , "-Wl,-rpath,$ORIGIN/../lib"
+ , { "type": "join"
+ , "$1":
+ ["-Wl,-soname,", {"type": "var", "name": "libname"}]
+ }
+ ]
+ , {"type": "var", "name": "COMPILE_FLAGS"}
+ , {"type": "var", "name": "LDFLAGS"}
+ , ["-o", {"type": "var", "name": "libname"}]
+ , {"type": "keys", "$1": {"type": "var", "name": "objects"}}
+ , {"type": "var", "name": "link-args"}
+ , {"type": "var", "name": "run-libs-args"}
+ ]
+ }
+ }
+ }
+ ]
+ ]
+ , "body": {"type": "var", "name": "lib"}
+ }
+ }
+, "shared result":
+ { "vars":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "LDFLAGS"
+ , "ADD_CXXFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_LDFLAGS"
+ , "ENV"
+ , "name"
+ , "pure C"
+ , "srcs"
+ , "hdrs"
+ , "private-hdrs"
+ , "cflags"
+ , "private-cflags"
+ , "ldflags"
+ , "private-ldflags"
+ , "soversion"
+ , "pkg-name"
+ , "extra-provides"
+ , "deps-transition"
+ , "public-fieldnames"
+ , "private-fieldnames"
+ ]
+ , "imports":
+ { "compile-deps": "compile-deps"
+ , "compile-args-deps": "compile-args-deps"
+ , "link-deps": "link-deps"
+ , "link-args-deps": "link-args-deps"
+ , "run-libs-deps": "run-libs-deps"
+ , "run-libs-args-deps": "run-libs-args-deps"
+ , "cflags-files-deps": "cflags-files-deps"
+ , "ldflags-files-deps": "ldflags-files-deps"
+ , "shared artifact": "shared artifact"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["deps-fieldnames", {"type": "var", "name": "private-fieldnames"}]
+ , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
+ , [ "compile-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "cflags"}
+ , {"type": "var", "name": "private-cflags"}
+ , {"type": "CALL_EXPRESSION", "name": "compile-args-deps"}
+ ]
+ }
+ }
+ ]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
+ , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
+ , ["link-args", {"type": "CALL_EXPRESSION", "name": "link-args-deps"}]
+ , ["run-libs", {"type": "CALL_EXPRESSION", "name": "run-libs-deps"}]
+ , [ "run-libs-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "ldflags", "default": []}
+ , {"type": "var", "name": "private-ldflags", "default": []}
+ , {"type": "CALL_EXPRESSION", "name": "run-libs-args-deps"}
+ ]
+ }
+ }
+ ]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
+ , ["lib", {"type": "CALL_EXPRESSION", "name": "shared artifact"}]
+ , ["deps-fieldnames", {"type": "var", "name": "public-fieldnames"}]
+ , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
+ , [ "compile-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "cflags"}
+ , {"type": "CALL_EXPRESSION", "name": "compile-args-deps"}
+ ]
+ }
+ }
+ ]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
+ , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
+ , ["link-args", {"type": "CALL_EXPRESSION", "name": "link-args-deps"}]
+ , [ "run-libs"
+ , { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "lib"}
+ , {"type": "var", "name": "run-libs"}
+ ]
+ }
+ ]
+ , [ "run-libs-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "keys", "$1": {"type": "var", "name": "lib"}}
+ , {"type": "var", "name": "ldflags", "default": []}
+ , {"type": "CALL_EXPRESSION", "name": "run-libs-args-deps"}
+ ]
+ }
+ }
+ ]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
+ , [ "package"
+ , { "type": "let*"
+ , "bindings":
+ [ ["name", {"type": "var", "name": "pkg-name"}]
+ , [ "version"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "soversion"}
+ , "then":
+ { "type": "join"
+ , "separator": "."
+ , "$1": {"type": "var", "name": "soversion"}
+ }
+ , "else": null
+ }
+ ]
+ ]
+ , "body":
+ { "type": "env"
+ , "vars": ["name", "version", "cflags-files", "ldflags-files"]
+ }
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts": {"type": "var", "name": "lib"}
+ , "runfiles": {"type": "var", "name": "hdrs"}
+ , "provides":
+ { "type": "map_union"
+ , "$1":
+ [ { "type": "env"
+ , "vars":
+ [ "compile-deps"
+ , "compile-args"
+ , "link-deps"
+ , "link-args"
+ , "run-libs"
+ , "run-libs-args"
+ , "package"
+ ]
+ }
+ , { "type": "var"
+ , "name": "extra-provides"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ }
+ }
+ }
+ }
+, "bin artifact":
+ { "doc": ["Produces the binary artifact."]
+ , "vars":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "LDFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "ADD_LDFLAGS"
+ , "ENV"
+ , "BUILD_POSITION_INDEPENDENT"
+ , "name"
+ , "pure C"
+ , "srcs"
+ , "private-hdrs"
+ , "stage"
+ , "compile-deps"
+ , "compile-args"
+ , "link-deps"
+ , "link-args"
+ , "run-libs"
+ , "run-libs-args"
+ , "cflags-files"
+ , "ldflags-files"
+ , "defaults-transition"
+ ]
+ , "imports":
+ { "compiler": "compiler"
+ , "flags": "flags"
+ , "objects": "objects"
+ , "default-ENV": "default-ENV"
+ , "default-LDFLAGS": "default-LDFLAGS"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["COMPILER", {"type": "CALL_EXPRESSION", "name": "compiler"}]
+ , [ "COMPILE_FLAGS"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "flags"}
+ , {"type": "var", "name": "compile-args"}
+ ]
+ }
+ ]
+ , [ "LDFLAGS"
+ , { "type": "++"
+ , "$1":
+ [ { "type": "var"
+ , "name": "LDFLAGS"
+ , "default":
+ {"type": "CALL_EXPRESSION", "name": "default-LDFLAGS"}
+ }
+ , {"type": "var", "name": "ADD_LDFLAGS", "default": []}
+ ]
+ }
+ ]
+ , [ "ENV"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "default-ENV"}
+ , [ { "type": "var"
+ , "name": "ENV"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ ]
+ }
+ }
+ ]
+ , ["hdrs", {"type": "empty_map"}]
+ , ["objects", {"type": "CALL_EXPRESSION", "name": "objects"}]
+ , [ "link-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "keys", "$1": {"type": "var", "name": "objects"}}
+ , {"type": "var", "name": "link-args"}
+ ]
+ }
+ }
+ ]
+ , [ "binpath"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "stage"}
+ , "then":
+ { "type": "join"
+ , "separator": "/"
+ , "$1":
+ [ {"type": "var", "name": "stage"}
+ , {"type": "var", "name": "name"}
+ ]
+ }
+ , "else": {"type": "var", "name": "name"}
+ }
+ ]
+ , [ "binary"
+ , { "type": "ACTION"
+ , "outs": [{"type": "var", "name": "binpath"}]
+ , "inputs":
+ { "type": "disjoint_map_union"
+ , "$1":
+ [ {"type": "var", "name": "objects"}
+ , {"type": "var", "name": "link-deps"}
+ , {"type": "var", "name": "run-libs"}
+ , { "type": "var"
+ , "name": "cflags-files"
+ , "default": {"type": "empty_map"}
+ }
+ , { "type": "var"
+ , "name": "ldflags-files"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ }
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ [ {"type": "var", "name": "COMPILER"}
+ , "-Wl,-rpath,$ORIGIN"
+ , "-Wl,-rpath,$ORIGIN/../lib"
+ , "-o"
+ , {"type": "var", "name": "binpath"}
+ ]
+ , {"type": "var", "name": "COMPILE_FLAGS"}
+ , {"type": "var", "name": "LDFLAGS"}
+ , {"type": "var", "name": "link-args"}
+ , {"type": "var", "name": "run-libs-args"}
+ ]
+ }
+ , "env": {"type": "var", "name": "ENV"}
+ }
+ ]
+ ]
+ , "body": {"type": "var", "name": "binary"}
+ }
+ }
+, "bin result":
+ { "doc": ["Produces the binary target result."]
+ , "vars":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "LDFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "ADD_LDFLAGS"
+ , "ENV"
+ , "BUILD_POSITION_INDEPENDENT"
+ , "name"
+ , "pure C"
+ , "srcs"
+ , "private-hdrs"
+ , "private-cflags"
+ , "private-ldflags"
+ , "stage"
+ , "private-fieldnames"
+ ]
+ , "imports":
+ { "compile-deps": "compile-deps"
+ , "compile-args-deps": "compile-args-deps"
+ , "link-deps": "link-deps"
+ , "link-args-deps": "link-args-deps"
+ , "run-libs-deps": "run-libs-deps"
+ , "run-libs-args-deps": "run-libs-args-deps"
+ , "cflags-files-deps": "cflags-files-deps"
+ , "ldflags-files-deps": "ldflags-files-deps"
+ , "binary": "bin artifact"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["deps-fieldnames", {"type": "var", "name": "private-fieldnames"}]
+ , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
+ , [ "compile-args"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "compile-args-deps"}
+ , {"type": "var", "name": "private-cflags"}
+ ]
+ }
+ ]
+ , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
+ , [ "link-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "private-ldflags"}
+ , {"type": "CALL_EXPRESSION", "name": "link-args-deps"}
+ ]
+ }
+ }
+ ]
+ , ["run-libs", {"type": "CALL_EXPRESSION", "name": "run-libs-deps"}]
+ , [ "run-libs-args"
+ , {"type": "CALL_EXPRESSION", "name": "run-libs-args-deps"}
+ ]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
+ , ["package", {"type": "singleton_map", "key": "to_bin", "value": true}]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts": {"type": "CALL_EXPRESSION", "name": "binary"}
+ , "provides": {"type": "env", "vars": ["run-libs", "package"]}
+ }
+ }
+ }
+}
diff --git a/rules/CC/IDE/RULES b/rules/CC/IDE/RULES
new file mode 100644
index 0000000..dc4b607
--- /dev/null
+++ b/rules/CC/IDE/RULES
@@ -0,0 +1,96 @@
+{ "headers":
+ { "doc": ["Transitive public headers of C++ target"]
+ , "target_fields": ["proto", "deps"]
+ , "string_fields": ["stage"]
+ , "field_doc":
+ { "proto": ["The proto source files for creating cc bindings."]
+ , "deps": ["The targets to obtain the headers from."]
+ , "stage":
+ [ "The logical location of the header files. Individual directory"
+ , "components are joined with \"/\"."
+ ]
+ }
+ , "anonymous":
+ { "proto-deps":
+ { "target": "proto"
+ , "provider": "proto"
+ , "rule_map":
+ { "library": ["./", "../proto", "library"]
+ , "service library": ["./", "../proto", "service library"]
+ }
+ }
+ }
+ , "imports": {"runfiles_list": ["./", "../..", "field_runfiles_list"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "stage"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": {"type": "FIELD", "name": "stage"}
+ }
+ ]
+ , [ "artifacts"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ { "type": "let*"
+ , "bindings": [["fieldname", "proto-deps"]]
+ , "body":
+ {"type": "CALL_EXPRESSION", "name": "runfiles_list"}
+ }
+ , { "type": "foreach"
+ , "var": "x"
+ , "range": {"type": "FIELD", "name": "proto-deps"}
+ , "body":
+ { "type": "DEP_PROVIDES"
+ , "provider": "compile-deps"
+ , "dep": {"type": "var", "name": "x"}
+ , "default":
+ { "type": "fail"
+ , "msg":
+ [ "Expected a library target, but got:"
+ , {"type": "var", "name": "x"}
+ ]
+ }
+ }
+ }
+ , { "type": "let*"
+ , "bindings": [["fieldname", "deps"]]
+ , "body":
+ {"type": "CALL_EXPRESSION", "name": "runfiles_list"}
+ }
+ , { "type": "foreach"
+ , "var": "x"
+ , "range": {"type": "FIELD", "name": "deps"}
+ , "body":
+ { "type": "DEP_PROVIDES"
+ , "provider": "compile-deps"
+ , "dep": {"type": "var", "name": "x"}
+ , "default":
+ { "type": "fail"
+ , "msg":
+ [ "Expected a library target, but got:"
+ , {"type": "var", "name": "x"}
+ ]
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts": {"type": "var", "name": "artifacts"}
+ , "runfiles": {"type": "var", "name": "artifacts"}
+ }
+ }
+ }
+}
diff --git a/rules/CC/RULES b/rules/CC/RULES
new file mode 100644
index 0000000..730d45b
--- /dev/null
+++ b/rules/CC/RULES
@@ -0,0 +1,839 @@
+{ "defaults":
+ { "doc":
+ [ "A rule to provide defaults."
+ , "All CC targets take their defaults for CC, CXX, flags, etc from"
+ , "the target [\"CC\", \"defaults\"]. This is probably the only sensibe"
+ , "use of this rule. As targets form a different root, the defaults"
+ , "can be provided without changing this directory."
+ ]
+ , "target_fields": ["base"]
+ , "string_fields":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "LDFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "ADD_LDFLAGS"
+ , "AR"
+ , "PATH"
+ ]
+ , "imports": {"base-provides": "defaults-base-provides"}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["CC", {"type": "FIELD", "name": "CC"}]
+ , ["CXX", {"type": "FIELD", "name": "CXX"}]
+ , ["CFLAGS", {"type": "FIELD", "name": "CFLAGS"}]
+ , ["CXXFLAGS", {"type": "FIELD", "name": "CXXFLAGS"}]
+ , ["LDFLAGS", {"type": "FIELD", "name": "LDFLAGS"}]
+ , ["AR", {"type": "FIELD", "name": "AR"}]
+ , ["PATH", {"type": "FIELD", "name": "PATH"}]
+ , ["provider", "CC"]
+ , [ "CC"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "CC"}
+ , "then": {"type": "var", "name": "CC"}
+ , "else": {"type": "CALL_EXPRESSION", "name": "base-provides"}
+ }
+ ]
+ , ["provider", "CXX"]
+ , [ "CXX"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "CXX"}
+ , "then": {"type": "var", "name": "CXX"}
+ , "else": {"type": "CALL_EXPRESSION", "name": "base-provides"}
+ }
+ ]
+ , ["provider", "CFLAGS"]
+ , [ "CFLAGS"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "CFLAGS"}
+ , "then": {"type": "var", "name": "CFLAGS"}
+ , "else": {"type": "CALL_EXPRESSION", "name": "base-provides"}
+ }
+ ]
+ , ["provider", "CXXFLAGS"]
+ , [ "CXXFLAGS"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "CXXFLAGS"}
+ , "then": {"type": "var", "name": "CXXFLAGS"}
+ , "else": {"type": "CALL_EXPRESSION", "name": "base-provides"}
+ }
+ ]
+ , ["provider", "AR"]
+ , [ "AR"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "AR"}
+ , "then": {"type": "var", "name": "AR"}
+ , "else": {"type": "CALL_EXPRESSION", "name": "base-provides"}
+ }
+ ]
+ , ["provider", "ENV"]
+ , [ "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": "CALL_EXPRESSION", "name": "base-provides"}
+ }
+ ]
+ , [ "CFLAGS"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "CFLAGS"}
+ , {"type": "FIELD", "name": "ADD_CFLAGS"}
+ ]
+ }
+ ]
+ , [ "CXXFLAGS"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "CXXFLAGS"}
+ , {"type": "FIELD", "name": "ADD_CXXFLAGS"}
+ ]
+ }
+ ]
+ , [ "LDFLAGS"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "LDFLAGS"}
+ , {"type": "FIELD", "name": "ADD_LDFLAGS"}
+ ]
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "provides":
+ { "type": "env"
+ , "vars": ["CC", "CXX", "CFLAGS", "CXXFLAGS", "LDFLAGS", "AR", "ENV"]
+ }
+ }
+ }
+ }
+, "library":
+ { "doc": ["A C++ library"]
+ , "target_fields":
+ [ "srcs"
+ , "hdrs"
+ , "private-hdrs"
+ , "deps"
+ , "private-deps"
+ , "proto"
+ , "private-proto"
+ ]
+ , "string_fields":
+ [ "name"
+ , "stage"
+ , "pure C"
+ , "defines"
+ , "private-defines"
+ , "cflags"
+ , "private-cflags"
+ , "ldflags"
+ , "private-ldflags"
+ , "soversion"
+ , "pkg-name"
+ ]
+ , "config_fields": ["shared"]
+ , "config_vars":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "LDFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "ADD_LDFLAGS"
+ , "AR"
+ , "ENV"
+ , "BUILD_POSITION_INDEPENDENT"
+ ]
+ , "implicit": {"defaults": ["defaults"]}
+ , "field_doc":
+ { "name":
+ ["The name of the library (without leading \"lib\" or trailing \".a\")."]
+ , "srcs": ["The source files of the library."]
+ , "hdrs": ["Any public header files of the library."]
+ , "private-hdrs":
+ [ "Any header files that only need to be present when compiling the"
+ , "source files, but are not needed for any consumer of the library."
+ ]
+ , "stage":
+ [ "The logical location of all header and source files, as well as the"
+ , "resulting library file. Individual directory components are joined"
+ , "with \"/\"."
+ ]
+ , "pure C":
+ [ "If non-empty, compile as C sources rathter than C++ sources."
+ , "In particular, CC is used to compile rather than CXX (or their"
+ , "respective defaults)."
+ ]
+ , "defines":
+ [ "List of defines set for this target and its consumers."
+ , "Each list entry will be prepended by \"-D\"."
+ ]
+ , "private-defines":
+ [ "List of defines set for source files local to this target."
+ , "Each list entry will be prepended by \"-D\"."
+ ]
+ , "cflags":
+ ["List of compile flags set for this target and its consumers."]
+ , "private-cflags":
+ ["List of compile flags set for source files local to this target."]
+ , "ldflags":
+ [ "Additional linker flags for linking external libraries for this"
+ , "target and its consumers (not built by this tool, typically system"
+ , "libraries)."
+ ]
+ , "private-ldflags":
+ [ "Additional linker flags for linking external libraries (not built"
+ , "by this tool, typically system libraries)."
+ ]
+ , "deps": ["Any other libraries this library depends upon."]
+ , "private-deps":
+ [ "Any other libraries this library depends upon but does not include"
+ , "in its public headers."
+ ]
+ , "proto":
+ [ "Any [\"proto\", \"library\"] this target depends upon directly."
+ , "The creation of C++ bindings for this proto library as well as of"
+ , "its dependencies will be taken care of (as anonymous targets, so no"
+ , "duplicate work will be carried out, even if the same proto library"
+ , "is used at various places)."
+ ]
+ , "private-proto":
+ [ "Any [\"proto\", \"library\"] this target depends upon privately."
+ , "The creation of C++ bindings for this proto library as well as of"
+ , "its dependencies will be taken care of (as anonymous targets, so no"
+ , "duplicate work will be carried out, even if the same proto library"
+ , "is used at various places)."
+ ]
+ , "shared": ["If non-empty, produce a shared instead of a static library."]
+ , "soversion":
+ [ "The SOVERSION for shared libraries. Individual version components are"
+ , "joined with \".\"."
+ ]
+ , "pkg-name":
+ [ "Name to use for pkg-config files. If this field is empty, the field"
+ , "\"name\" is used instead."
+ ]
+ }
+ , "config_doc":
+ { "CC":
+ [ "The name of the C compiler to be used (when compiling pure C code)."
+ , "If None, the respective value from [\"CC\", \"defaults\"] will be taken."
+ ]
+ , "CXX":
+ [ "The name of the C++ compiler to be used."
+ , "If None, the respective value from [\"CC\", \"defaults\"] will be taken."
+ ]
+ , "CFLAGS":
+ [ "The flags for CC to be used instead of the default ones."
+ , "For libraries that should be built in a non-standard way; usually"
+ , "adapting the default target [\"CC\", \"defaults\"] is the better"
+ , "choice."
+ ]
+ , "CXXFLAGS":
+ [ "The flags for CXX to be used instead of the default ones."
+ , "For libraries that should be built in a non-standard way; usually"
+ , "adapting the default target [\"CC\", \"defaults\"] is the better"
+ , "choice."
+ ]
+ , "LDFLAGS":
+ [ "The linker flags to be used instead of the default ones."
+ , "For libraries that should be built in a non-standard way; usually"
+ , "adapting the default target [\"CC\", \"defaults\"] is the better"
+ , "choice."
+ ]
+ , "ADD_CFLAGS":
+ [ "The flags to add to the default ones for CC."
+ , "For libraries that should be built in a non-standard way; usually"
+ , "adapting the default target [\"CC\", \"defaults\"] is the better"
+ , "choice."
+ ]
+ , "ADD_CXXFLAGS":
+ [ "The flags to add to the default ones for CXX."
+ , "For libraries that should be built in a non-standard way; usually"
+ , "adapting the default target [\"CC\", \"defaults\"] is the better"
+ , "choice."
+ ]
+ , "ADD_LDFLAGS":
+ [ "The linker flags to add to the default ones."
+ , "For libraries that should be built in a non-standard way; usually"
+ , "adapting the default target [\"CC\", \"defaults\"] is the better"
+ , "choice."
+ ]
+ , "AR":
+ [ "The archive tool to used for creating the library"
+ , "If None, the respective value from [\"CC\", \"defaults\"] will be taken."
+ ]
+ , "ENV": ["The environment for any action generated."]
+ , "BUILD_POSITION_INDEPENDENT": ["Build with -fPIC."]
+ }
+ , "artifacts_doc":
+ ["The actual library (libname.a) staged in the specified directory"]
+ , "runfiles_doc": ["The public headers of this library"]
+ , "provides_doc":
+ { "compile-deps":
+ [ "Map of artifacts specifying any additional files that, besides the runfiles,"
+ , "have to be present in compile actions of targets depending on this library"
+ ]
+ , "link-deps":
+ [ "Map of artifacts specifying any additional files that, besides the artifacts,"
+ , "have to be present in a link actions of targets depending on this library"
+ ]
+ , "link-args":
+ [ "List of strings that have to be added to the command line for linking actions"
+ , "in targets depending on on this library"
+ ]
+ }
+ , "anonymous":
+ { "proto-deps":
+ { "target": "proto"
+ , "provider": "proto"
+ , "rule_map":
+ { "library": ["./", "proto", "library"]
+ , "service library": ["./", "proto", "service library"]
+ }
+ }
+ , "private-proto-deps":
+ { "target": "private-proto"
+ , "provider": "proto"
+ , "rule_map":
+ { "library": ["./", "proto", "library"]
+ , "service library": ["./", "proto", "service library"]
+ }
+ }
+ }
+ , "imports":
+ { "artifacts": ["./", "..", "field_artifacts"]
+ , "static result": "lib result"
+ , "shared result": "shared result"
+ , "fPIC transition": ["transitions", "with fPIC"]
+ }
+ , "config_transitions":
+ { "deps": [{"type": "CALL_EXPRESSION", "name": "fPIC transition"}]
+ , "private-deps": [{"type": "CALL_EXPRESSION", "name": "fPIC transition"}]
+ , "proto-deps": [{"type": "CALL_EXPRESSION", "name": "fPIC transition"}]
+ , "private-proto-deps":
+ [{"type": "CALL_EXPRESSION", "name": "fPIC transition"}]
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["name", {"type": "join", "$1": {"type": "FIELD", "name": "name"}}]
+ , ["pure C", {"type": "FIELD", "name": "pure C"}]
+ , [ "cflags"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "FIELD", "name": "cflags"}
+ , { "type": "foreach"
+ , "var": "def"
+ , "range": {"type": "FIELD", "name": "defines"}
+ , "body":
+ {"type": "join", "$1": ["-D", {"type": "var", "name": "def"}]}
+ }
+ ]
+ }
+ ]
+ , [ "private-cflags"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "FIELD", "name": "private-cflags"}
+ , { "type": "foreach"
+ , "var": "def"
+ , "range": {"type": "FIELD", "name": "private-defines"}
+ , "body":
+ {"type": "join", "$1": ["-D", {"type": "var", "name": "def"}]}
+ }
+ ]
+ }
+ ]
+ , [ "stage"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": {"type": "FIELD", "name": "stage"}
+ }
+ ]
+ , [ "srcs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "srcs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ }
+ ]
+ , [ "hdrs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "hdrs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ }
+ ]
+ , [ "private-hdrs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "private-hdrs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ }
+ ]
+ , ["ldflags", {"type": "FIELD", "name": "ldflags"}]
+ , ["private-ldflags", {"type": "FIELD", "name": "private-ldflags"}]
+ , ["soversion", {"type": "FIELD", "name": "soversion"}]
+ , [ "pkg-name"
+ , { "type": "if"
+ , "cond": {"type": "FIELD", "name": "pkg-name"}
+ , "then":
+ {"type": "join", "$1": {"type": "FIELD", "name": "pkg-name"}}
+ , "else": {"type": "var", "name": "name"}
+ }
+ ]
+ , [ "deps-transition"
+ , {"type": "CALL_EXPRESSION", "name": "fPIC transition"}
+ ]
+ , ["public-fieldnames", ["deps", "proto-deps"]]
+ , [ "private-fieldnames"
+ , ["deps", "private-deps", "proto-deps", "private-proto-deps"]
+ ]
+ ]
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "FIELD", "name": "shared"}
+ , "then": {"type": "CALL_EXPRESSION", "name": "shared result"}
+ , "else": {"type": "CALL_EXPRESSION", "name": "static result"}
+ }
+ }
+ }
+, "binary":
+ { "doc": ["A binary written in C++"]
+ , "target_fields": ["srcs", "private-hdrs", "private-deps", "private-proto"]
+ , "string_fields":
+ [ "name"
+ , "stage"
+ , "pure C"
+ , "private-defines"
+ , "private-cflags"
+ , "private-ldflags"
+ ]
+ , "config_vars":
+ [ "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "LDFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "ADD_LDFLAGS"
+ , "ENV"
+ , "BUILD_POSITION_INDEPENDENT"
+ ]
+ , "implicit": {"defaults": ["defaults"]}
+ , "field_doc":
+ { "name": ["The name of the binary"]
+ , "srcs": ["The source files of the library."]
+ , "private-hdrs":
+ [ "Any header files that need to be present when compiling the"
+ , "source files."
+ ]
+ , "stage":
+ [ "The logical location of all header and source files, as well as the"
+ , "resulting binary file. Individual directory components are joined"
+ , "with \"/\"."
+ ]
+ , "pure C":
+ [ "If non-empty, compile as C sources rathter than C++ sources."
+ , "In particular, CC is used to compile rather than CXX"
+ ]
+ , "private-defines":
+ [ "List of defines set for source files local to this target."
+ , "Each list entry will be prepended by \"-D\"."
+ ]
+ , "private-cflags":
+ ["List of compile flags set for source files local to this target."]
+ , "private-ldflags":
+ ["Additional linker flags for linking external libraries."]
+ , "private-deps": ["Any other libraries this binary depends upon."]
+ , "private-proto":
+ [ "Any [\"proto\", \"library\"] this target depends upon directly."
+ , "The creation of C++ bindings for this proto library as well as of"
+ , "is dependencies will be taken care of (as anonymous targets, so no"
+ , "duplicate work will be carried out, even if the same proto library"
+ , "is used at various places)."
+ ]
+ }
+ , "config_doc":
+ { "CC":
+ ["The name of the C compiler to be used (when compiling pure C code)"]
+ , "CXX": ["The name of the C++ compiler to be used."]
+ , "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"
+ ]
+ , "LDFLAGS":
+ [ "The linker flags do 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"
+ ]
+ , "ADD_LDFLAGS":
+ [ "The linker flags to add to the default ones"
+ , "taken from the [\"CC\", \"defaults\"] target"
+ ]
+ , "ENV": ["The environment for any action generated."]
+ , "BUILD_POSITION_INDEPENDENT": ["Build with -fPIC."]
+ }
+ , "artifacts_doc": ["The final binary, staged to the given directory"]
+ , "runfiles_doc": ["None"]
+ , "anonymous":
+ { "private-proto-deps":
+ { "target": "private-proto"
+ , "provider": "proto"
+ , "rule_map":
+ { "library": ["./", "proto", "library"]
+ , "service library": ["./", "proto", "service library"]
+ }
+ }
+ }
+ , "imports":
+ {"artifacts": ["./", "..", "field_artifacts"], "bin result": "bin result"}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "name"
+ , { "type": "assert_non_empty"
+ , "msg": "A non-empty name has to be provided for binaries"
+ , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "name"}}
+ }
+ ]
+ , ["pure C", {"type": "FIELD", "name": "pure C"}]
+ , [ "stage"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": {"type": "FIELD", "name": "stage"}
+ }
+ ]
+ , [ "srcs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "srcs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ }
+ ]
+ , [ "private-hdrs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "private-hdrs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ }
+ ]
+ , [ "private-cflags"
+ , { "type": "++"
+ , "$1":
+ [ { "type": "foreach"
+ , "var": "def"
+ , "range": {"type": "FIELD", "name": "private-defines"}
+ , "body":
+ {"type": "join", "$1": ["-D", {"type": "var", "name": "def"}]}
+ }
+ , {"type": "FIELD", "name": "private-cflags"}
+ ]
+ }
+ ]
+ , ["private-ldflags", {"type": "FIELD", "name": "private-ldflags"}]
+ , ["private-fieldnames", ["private-deps", "private-proto-deps"]]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "bin result"}
+ }
+ }
+, "install-with-deps":
+ { "doc":
+ [ "Install target's artifacts with transitive dependencies. Depending on"
+ , "the target, artifacts and dependencies will be installed to"
+ , "subdirectories \"bin\", \"include\", and \"lib\". For library targets,"
+ , "a pkg-config file is generated and provided in \"share/pkgconfig\"."
+ ]
+ , "config_vars": ["PREFIX"]
+ , "target_fields": ["targets"]
+ , "string_fields": ["flat-libs", "prefix"]
+ , "imports":
+ { "compile-deps": "compile-deps"
+ , "compile-args-deps": "compile-args-deps"
+ , "link-deps": "link-deps"
+ , "link-args-deps": "link-args-deps"
+ , "run-libs-deps": "run-libs-deps"
+ , "run-libs-args-deps": "run-libs-args-deps"
+ , "pkg-config": "pkg-config"
+ }
+ , "field_doc":
+ { "targets": ["Targets to install artifacts from."]
+ , "flat-libs":
+ [ "Install libraries flat to the \"lib\" subdirectory. Be aware that"
+ , "conflicts may occur if any of the (transitive) libraries happen to"
+ , "have the same base name."
+ ]
+ , "prefix":
+ [ "The prefix used for pkg-config files. The path will be made absolute"
+ , "and individual directory components are joined with \"/\". If no"
+ , "prefix is specified, the value from the config variable \"PREFIX\" is"
+ , "taken, with the default value being \"/\"."
+ ]
+ }
+ , "config_doc":
+ { "PREFIX":
+ [ "The absolute path that is used as prefix inside generated pkg-config"
+ , "files. The default value for this variable is \"/\". This variable"
+ , "is ignored if the field \"prefix\" is set."
+ ]
+ }
+ , "artifacts_doc":
+ ["Installed artifacts in subdirectories (\"bin\"/\"include\"/\"lib\")."]
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["pc-install-dir", "share/pkgconfig"]
+ , [ "install-stage"
+ , { "type": "disjoint_map_union"
+ , "msg": "install stages may not overlap"
+ , "$1":
+ { "type": "foreach"
+ , "var": "target"
+ , "range": {"type": "FIELD", "name": "targets"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ [ "artifacts"
+ , { "type": "DEP_ARTIFACTS"
+ , "dep": {"type": "var", "name": "target"}
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ , [ "runfiles"
+ , { "type": "DEP_RUNFILES"
+ , "dep": {"type": "var", "name": "target"}
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ , [ "compile-deps"
+ , { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "target"}
+ , "provider": "compile-deps"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ , [ "link-deps"
+ , { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "target"}
+ , "provider": "link-deps"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ , [ "run-libs"
+ , { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "target"}
+ , "provider": "run-libs"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ , [ "package"
+ , { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "target"}
+ , "provider": "package"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ , [ "to_bin"
+ , { "type": "lookup"
+ , "key": "to_bin"
+ , "map": {"type": "var", "name": "package"}
+ }
+ ]
+ , [ "binaries"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "to_bin"}
+ , "then": {"type": "var", "name": "artifacts"}
+ , "else": {"type": "empty_map"}
+ }
+ ]
+ , [ "headers"
+ , { "type": "disjoint_map_union"
+ , "msg": "headers may not overlap"
+ , "$1":
+ [ {"type": "var", "name": "runfiles"}
+ , {"type": "var", "name": "compile-deps"}
+ ]
+ }
+ ]
+ , [ "libraries"
+ , { "type": "disjoint_map_union"
+ , "msg": "libraries may not overlap"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ { "type": "if"
+ , "cond": {"type": "var", "name": "to_bin"}
+ , "then": []
+ , "else": [{"type": "var", "name": "artifacts"}]
+ }
+ , [{"type": "var", "name": "link-deps"}]
+ , [{"type": "var", "name": "run-libs"}]
+ ]
+ }
+ }
+ ]
+ , [ "pkg-name"
+ , { "type": "lookup"
+ , "key": "name"
+ , "map": {"type": "var", "name": "package"}
+ }
+ ]
+ , [ "pkg-config"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "pkg-name"}
+ , "then":
+ { "type": "let*"
+ , "bindings":
+ [ [ "pkg-prefix"
+ , { "type": "if"
+ , "cond": {"type": "FIELD", "name": "prefix"}
+ , "then":
+ { "type": "join"
+ , "separator": "/"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [[""], {"type": "FIELD", "name": "prefix"}]
+ }
+ }
+ , "else":
+ {"type": "var", "name": "PREFIX", "default": "/"}
+ }
+ ]
+ , [ "pkg-version"
+ , { "type": "lookup"
+ , "key": "version"
+ , "map": {"type": "var", "name": "package"}
+ }
+ ]
+ , [ "pkg-cflags"
+ , { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "target"}
+ , "provider": "compile-args"
+ , "default": []
+ }
+ ]
+ , [ "pkg-ldflags"
+ , { "type": "++"
+ , "$1":
+ [ { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "target"}
+ , "provider": "link-args"
+ , "default": []
+ }
+ , { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "target"}
+ , "provider": "run-libs-args"
+ , "default": []
+ }
+ ]
+ }
+ ]
+ , [ "pkg-flag-files"
+ , { "type": "map_union"
+ , "$1":
+ [ { "type": "lookup"
+ , "key": "cflags-files"
+ , "map": {"type": "var", "name": "package"}
+ , "default": {"type": "empty_map"}
+ }
+ , { "type": "lookup"
+ , "key": "ldflags-files"
+ , "map": {"type": "var", "name": "package"}
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ }
+ ]
+ , ["pkg-libs", {"type": "var", "name": "libraries"}]
+ , ["flat-libs", {"type": "FIELD", "name": "flat-libs"}]
+ ]
+ , "body":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "pkg-config"}
+ , {"type": "var", "name": "pkg-flag-files"}
+ ]
+ }
+ }
+ , "else": {"type": "empty_map"}
+ }
+ ]
+ ]
+ , "body":
+ { "type": "map_union"
+ , "$1":
+ [ { "type": "to_subdir"
+ , "subdir": "bin"
+ , "flat": true
+ , "msg": "install binaries may not overlap"
+ , "$1": {"type": "var", "name": "binaries"}
+ }
+ , { "type": "to_subdir"
+ , "subdir": "include"
+ , "$1": {"type": "var", "name": "headers"}
+ }
+ , { "type": "to_subdir"
+ , "subdir": "lib"
+ , "flat": {"type": "FIELD", "name": "flat-libs"}
+ , "msg": "install libraries may not overlap"
+ , "$1": {"type": "var", "name": "libraries"}
+ }
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "pc-install-dir"}
+ , "$1": {"type": "var", "name": "pkg-config"}
+ }
+ ]
+ }
+ }
+ }
+ }
+ ]
+ ]
+ , "body":
+ {"type": "RESULT", "artifacts": {"type": "var", "name": "install-stage"}}
+ }
+ }
+}
diff --git a/rules/CC/TARGETS b/rules/CC/TARGETS
new file mode 100644
index 0000000..8860e8b
--- /dev/null
+++ b/rules/CC/TARGETS
@@ -0,0 +1,11 @@
+{ "defaults":
+ { "type": ["CC", "defaults"]
+ , "CC": ["cc"]
+ , "CXX": ["c++"]
+ , "CFLAGS": []
+ , "CXXFLAGS": []
+ , "LDFLAGS": []
+ , "AR": ["ar"]
+ , "PATH": ["/bin", "/usr/bin"]
+ }
+}
diff --git a/rules/CC/auto/EXPRESSIONS b/rules/CC/auto/EXPRESSIONS
new file mode 100644
index 0000000..ac19f7a
--- /dev/null
+++ b/rules/CC/auto/EXPRESSIONS
@@ -0,0 +1,32 @@
+{ "last_list_entry":
+ { "vars": ["list"]
+ , "expression":
+ { "type": "foldl"
+ , "range": {"type": "var", "name": "list"}
+ , "start": null
+ , "body": {"type": "var", "name": "_"}
+ }
+ }
+, "first_list_entry":
+ { "vars": ["list"]
+ , "imports": {"last": "last_list_entry"}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "list"
+ , { "type": "foldl"
+ , "range": {"type": "var", "name": "list", "default": []}
+ , "start": null
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "$1"}
+ , "then": {"type": "var", "name": "$1"}
+ , "else": [{"type": "var", "name": "_"}]
+ }
+ }
+ ]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "last"}
+ }
+ }
+}
diff --git a/rules/CC/auto/RULES b/rules/CC/auto/RULES
new file mode 100644
index 0000000..4f38504
--- /dev/null
+++ b/rules/CC/auto/RULES
@@ -0,0 +1,955 @@
+{ "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}\"."
+ ]
+ }
+ , "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."
+ ]
+ , "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."
+ ]
+ , "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":
+ { "first": "first_list_entry"
+ , "last": "last_list_entry"
+ , "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"]
+ }
+ , "implicit": {"defaults": [["./", "..", "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"}
+ }
+ ]
+ }
+ }
+ ]
+ , ["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": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "default-ENV"}
+ , [ { "type": "var"
+ , "name": "ENV"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ ]
+ }
+ }
+ ]
+ , [ "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.$LANG << EOF"
+ , "#include \"$INC\""
+ , "#ifndef $SYMBOL"
+ , "void* __test = &$SYMBOL;"
+ , "#endif"
+ , "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"
+ ]
+ }
+ }
+ ]
+ , [ "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'defines' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["val", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'defines1' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["val", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'defines01' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["val", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'have_cfile' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["val", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "body":
+ { "type": "lookup"
+ , "key": "out.def"
+ , "map":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "env", "vars": ["file_check.sh", "c.flags"]}
+ , {"type": "var", "name": "includes"}
+ ]
+ }
+ , "cmd":
+ [ "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'have_cxxfile' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["val", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "body":
+ { "type": "lookup"
+ , "key": "out.def"
+ , "map":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "env", "vars": ["file_check.sh", "cxx.flags"]}
+ , {"type": "var", "name": "includes"}
+ ]
+ }
+ , "cmd":
+ [ "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'have_ctype' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["type", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "body":
+ { "type": "lookup"
+ , "key": "out.def"
+ , "map":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "env", "vars": ["type_check.sh", "c.flags"]}
+ , {"type": "var", "name": "includes"}
+ ]
+ }
+ , "cmd":
+ [ "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'have_cxxtype' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["type", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "body":
+ { "type": "lookup"
+ , "key": "out.def"
+ , "map":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "env", "vars": ["type_check.sh", "cxx.flags"]}
+ , {"type": "var", "name": "includes"}
+ ]
+ }
+ , "cmd":
+ [ "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'have_csymbol' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["list", {"type": "CALL_EXPRESSION", "name": "last"}]
+ , ["sym", {"type": "CALL_EXPRESSION", "name": "first"}]
+ , ["hdrs", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "body":
+ { "type": "lookup"
+ , "key": "out.def"
+ , "map":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "env", "vars": ["symbol_check.sh", "c.flags"]}
+ , {"type": "var", "name": "includes"}
+ ]
+ }
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ [ "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'have_cxxsymbol' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["list", {"type": "CALL_EXPRESSION", "name": "last"}]
+ , ["sym", {"type": "CALL_EXPRESSION", "name": "first"}]
+ , ["hdrs", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "body":
+ { "type": "lookup"
+ , "key": "out.def"
+ , "map":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "env", "vars": ["symbol_check.sh", "cxx.flags"]}
+ , {"type": "var", "name": "includes"}
+ ]
+ }
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ [ "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'size_ctype' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["list", {"type": "CALL_EXPRESSION", "name": "last"}]
+ , ["type", {"type": "CALL_EXPRESSION", "name": "first"}]
+ , ["sizes", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "body":
+ { "type": "lookup"
+ , "key": "out.def"
+ , "map":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "env", "vars": ["size_check.sh", "c.flags"]}
+ , {"type": "var", "name": "includes"}
+ ]
+ }
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ [ "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":
+ [ ["list", {"type": "var", "name": "pair"}]
+ , [ "def"
+ , { "type": "assert_non_empty"
+ , "msg": "Define name in 'size_cxxtype' may not be empty"
+ , "$1": {"type": "CALL_EXPRESSION", "name": "first"}
+ }
+ ]
+ , ["list", {"type": "CALL_EXPRESSION", "name": "last"}]
+ , ["type", {"type": "CALL_EXPRESSION", "name": "first"}]
+ , ["sizes", {"type": "CALL_EXPRESSION", "name": "last"}]
+ ]
+ , "body":
+ { "type": "lookup"
+ , "key": "out.def"
+ , "map":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "env", "vars": ["size_check.sh", "cxx.flags"]}
+ , {"type": "var", "name": "includes"}
+ ]
+ }
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ [ "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": "var", "name": "definitions"}
+ , "cmd":
+ [ "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"}
+ }
+ }
+ }
+}
diff --git a/rules/CC/prebuilt/EXPRESSIONS b/rules/CC/prebuilt/EXPRESSIONS
new file mode 100644
index 0000000..fc901d7
--- /dev/null
+++ b/rules/CC/prebuilt/EXPRESSIONS
@@ -0,0 +1,453 @@
+{ "check-file-ending":
+ { "doc": ["Returns true if all file names end with the given ending."]
+ , "vars": ["files", "ending", "invert"]
+ , "vars_doc":
+ { "files": ["Artifact map that contains the files."]
+ , "ending": ["The ending to check for (without \".\")."]
+ , "invert": ["Invert condition to file name not ending with \"ending\"."]
+ }
+ , "expression":
+ { "type": "and"
+ , "$1":
+ { "type": "foreach"
+ , "var": "file"
+ , "range": {"type": "keys", "$1": {"type": "var", "name": "files"}}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ [ "is-equal"
+ , { "type": "=="
+ , "$1": {"type": "var", "name": "file"}
+ , "$2":
+ { "type": "change_ending"
+ , "$1": {"type": "var", "name": "file"}
+ , "ending":
+ { "type": "join"
+ , "$1": [".", {"type": "var", "name": "ending"}]
+ }
+ }
+ }
+ ]
+ ]
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "invert", "default": false}
+ , "then":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "is-equal"}
+ , "then": false
+ , "else": true
+ }
+ , "else": {"type": "var", "name": "is-equal"}
+ }
+ }
+ }
+ }
+ }
+, "check-libs-non-static":
+ { "doc":
+ [ "Returns true if all libs are non-static libraries or false otherwise."
+ , "Throws if static and non-static libraries are mixed."
+ ]
+ , "vars": ["libs"]
+ , "vars_doc": {"libs": ["List of artifact maps that contain the libraries."]}
+ , "imports": {"check-file-ending": "check-file-ending"}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["files", {"type": "map_union", "$1": {"type": "var", "name": "libs"}}]
+ , [ "static"
+ , { "type": "let*"
+ , "bindings": [["ending", "a"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "check-file-ending"}
+ }
+ ]
+ , [ "shared"
+ , { "type": "let*"
+ , "bindings": [["ending", "a"], ["invert", true]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "check-file-ending"}
+ }
+ ]
+ ]
+ , "body":
+ { "type": "if"
+ , "cond":
+ { "type": "or"
+ , "$1":
+ [ {"type": "var", "name": "static"}
+ , {"type": "var", "name": "shared"}
+ ]
+ }
+ , "then": {"type": "var", "name": "shared"}
+ , "else":
+ { "type": "fail"
+ , "msg": "Prebuilt library types (static/shared) may not be mixed."
+ }
+ }
+ }
+ }
+, "prebuilt result":
+ { "vars":
+ [ "ENV"
+ , "name"
+ , "version"
+ , "stage"
+ , "cflags"
+ , "ldflags"
+ , "libs"
+ , "hdrs"
+ , "config_reader"
+ , "pkg-configs"
+ , "deps-fieldnames"
+ ]
+ , "imports":
+ { "check-libs-non-static": "check-libs-non-static"
+ , "compile-deps": ["./", "..", "compile-deps"]
+ , "compile-args-deps": ["./", "..", "compile-args-deps"]
+ , "link-deps": ["./", "..", "link-deps"]
+ , "link-args-deps": ["./", "..", "link-args-deps"]
+ , "run-libs-deps": ["./", "..", "run-libs-deps"]
+ , "run-libs-args-deps": ["./", "..", "run-libs-args-deps"]
+ , "cflags-files-deps": ["./", "..", "cflags-files-deps"]
+ , "ldflags-files-deps": ["./", "..", "ldflags-files-deps"]
+ , "default-ENV": ["./", "..", "default-ENV"]
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "shared"
+ , {"type": "CALL_EXPRESSION", "name": "check-libs-non-static"}
+ ]
+ , [ "lib-stage"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "shared"}
+ , "then": "."
+ , "else": {"type": "var", "name": "stage"}
+ }
+ ]
+ , [ "staged-libs"
+ , { "type": "foreach"
+ , "var": "lib"
+ , "range": {"type": "var", "name": "libs"}
+ , "body":
+ { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "lib-stage"}
+ , "flat": true
+ , "msg": "prebuilt libraries may not overlap"
+ , "$1": {"type": "var", "name": "lib"}
+ }
+ }
+ ]
+ , [ "link-args"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "shared"}
+ , "then": []
+ , "else":
+ { "type": "foreach"
+ , "var": "lib"
+ , "range": {"type": "var", "name": "staged-libs"}
+ , "body":
+ { "type": "join"
+ , "$1": {"type": "keys", "$1": {"type": "var", "name": "lib"}}
+ }
+ }
+ }
+ ]
+ , [ "run-libs-args"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "shared"}
+ , "then":
+ { "type": "foreach"
+ , "var": "lib"
+ , "range": {"type": "var", "name": "staged-libs"}
+ , "body":
+ { "type": "join"
+ , "$1": {"type": "keys", "$1": {"type": "var", "name": "lib"}}
+ }
+ }
+ }
+ ]
+ , [ "libs"
+ , { "type": "disjoint_map_union"
+ , "msg": "prebuilt libraries may not overlap"
+ , "$1": {"type": "var", "name": "staged-libs"}
+ }
+ ]
+ , [ "hdrs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "disjoint_map_union"
+ , "msg": "prebuilt headers may not overlap"
+ , "$1": {"type": "var", "name": "hdrs"}
+ }
+ }
+ ]
+ , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
+ , [ "compile-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "cflags"}
+ , {"type": "CALL_EXPRESSION", "name": "compile-args-deps"}
+ ]
+ }
+ }
+ ]
+ , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
+ , [ "link-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "link-args"}
+ , {"type": "CALL_EXPRESSION", "name": "link-args-deps"}
+ ]
+ }
+ }
+ ]
+ , [ "run-libs"
+ , { "type": "map_union"
+ , "$1":
+ [ { "type": "if"
+ , "cond": {"type": "var", "name": "shared"}
+ , "then": {"type": "var", "name": "libs"}
+ , "else": {"type": "empty_map"}
+ }
+ , {"type": "CALL_EXPRESSION", "name": "run-libs-deps"}
+ ]
+ }
+ ]
+ , [ "run-libs-args"
+ , { "type": "nub_right"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "run-libs-args"}
+ , {"type": "var", "name": "ldflags"}
+ , {"type": "CALL_EXPRESSION", "name": "run-libs-args-deps"}
+ ]
+ }
+ }
+ ]
+ , [ "ENV"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "default-ENV"}
+ , [ { "type": "var"
+ , "name": "ENV"
+ , "default": {"type": "empty_map"}
+ }
+ ]
+ ]
+ }
+ }
+ ]
+ , [ "main-pkg-config"
+ , { "type": "foldl"
+ , "range": {"type": "var", "name": "pkg-configs", "default": []}
+ , "start": null
+ , "accum_var": "name"
+ , "var": "config"
+ , "body":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "name"}
+ , "then": {"type": "var", "name": "name"}
+ , "else":
+ { "type": "join"
+ , "$1": {"type": "keys", "$1": {"type": "var", "name": "config"}}
+ }
+ }
+ }
+ ]
+ , [ "reader-inputs"
+ , { "type": "to_subdir"
+ , "subdir": "lib"
+ , "$1":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "libs"}
+ , { "type": "to_subdir"
+ , "subdir": "pkgconfig"
+ , "flat": true
+ , "$1":
+ { "type": "map_union"
+ , "$1": {"type": "var", "name": "pkg-configs", "default": []}
+ }
+ }
+ ]
+ }
+ }
+ ]
+ , [ "cflags-filename"
+ , {"type": "join", "$1": [{"type": "var", "name": "name"}, ".cflags"]}
+ ]
+ , [ "cflags-file"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "pkg-configs"}
+ , "then":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "config_reader"}
+ , {"type": "var", "name": "reader-inputs"}
+ ]
+ }
+ , "cmd":
+ [ "./config_reader"
+ , {"type": "var", "name": "cflags-filename"}
+ , {"type": "var", "name": "main-pkg-config"}
+ ]
+ , "env": {"type": "var", "name": "ENV"}
+ , "outs": [{"type": "var", "name": "cflags-filename"}]
+ }
+ , "else": {"type": "empty_map"}
+ }
+ }
+ ]
+ , [ "cflags-files"
+ , { "type": "map_union"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ , {"type": "var", "name": "cflags-file"}
+ ]
+ }
+ ]
+ , [ "compile-args"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "compile-args"}
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "cflags-file"}
+ , "then":
+ [ { "type": "join"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["@"]
+ , { "type": "keys"
+ , "$1": {"type": "var", "name": "cflags-file"}
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ , [ "ldflags-filename"
+ , {"type": "join", "$1": [{"type": "var", "name": "name"}, ".ldflags"]}
+ ]
+ , [ "ldflags-file"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "if"
+ , "cond": {"type": "var", "name": "pkg-configs"}
+ , "then":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "config_reader"}
+ , {"type": "var", "name": "reader-inputs"}
+ ]
+ }
+ , "cmd":
+ [ "./config_reader"
+ , {"type": "var", "name": "ldflags-filename"}
+ , {"type": "var", "name": "main-pkg-config"}
+ ]
+ , "env": {"type": "var", "name": "ENV"}
+ , "outs": [{"type": "var", "name": "ldflags-filename"}]
+ }
+ , "else": {"type": "empty_map"}
+ }
+ }
+ ]
+ , [ "ldflags-files"
+ , { "type": "map_union"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ , {"type": "var", "name": "ldflags-file"}
+ ]
+ }
+ ]
+ , [ "run-libs-args"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "run-libs-args"}
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "ldflags-file"}
+ , "then":
+ [ { "type": "join"
+ , "$1":
+ { "type": "++"
+ , "$1":
+ [ ["@"]
+ , { "type": "keys"
+ , "$1": {"type": "var", "name": "ldflags-file"}
+ }
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ , [ "package"
+ , { "type": "let*"
+ , "bindings":
+ [ ["name", {"type": "var", "name": "name"}]
+ , [ "version"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "version"}
+ , "then":
+ { "type": "join"
+ , "separator": "."
+ , "$1": {"type": "var", "name": "version"}
+ }
+ , "else": null
+ }
+ ]
+ ]
+ , "body":
+ { "type": "env"
+ , "vars": ["name", "version", "cflags-files", "ldflags-files"]
+ }
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts": {"type": "var", "name": "libs"}
+ , "runfiles": {"type": "var", "name": "hdrs"}
+ , "provides":
+ { "type": "map_union"
+ , "$1":
+ [ { "type": "env"
+ , "vars":
+ [ "compile-deps"
+ , "compile-args"
+ , "link-deps"
+ , "link-args"
+ , "run-libs"
+ , "run-libs-args"
+ , "package"
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/rules/CC/prebuilt/RULES b/rules/CC/prebuilt/RULES
new file mode 100644
index 0000000..16f9f26
--- /dev/null
+++ b/rules/CC/prebuilt/RULES
@@ -0,0 +1,147 @@
+{ "library":
+ { "doc": ["A prebuilt C++ library"]
+ , "target_fields": ["lib", "hdrs", "deps", "pkg-config"]
+ , "string_fields":
+ ["name", "version", "stage", "defines", "cflags", "ldflags"]
+ , "implicit":
+ { "defaults": [["./", "..", "defaults"]]
+ , "config_reader": [["CC", "prebuilt/read_pkgconfig.py"]]
+ }
+ , "config_vars": ["ENV"]
+ , "field_doc":
+ { "name":
+ [ "The name of the library (without leading \"lib\" or trailing file name"
+ , "extension), also used as name for pkg-config files."
+ ]
+ , "version":
+ [ "The library version, used for pkg-config files. Individual version"
+ , "components are joined with \".\"."
+ ]
+ , "lib":
+ [ "The actual prebuilt library. If multiple libraries are specified"
+ , "(e.g., one depends on the other), the order matters. Library types"
+ , "cannot be mixed. All of them have to be either static or shared."
+ ]
+ , "hdrs": ["Any public header files of the library."]
+ , "deps": ["Any other libraries this library depends upon."]
+ , "stage":
+ [ "The logical location of all header and source files, as well as the"
+ , "resulting library file. Individual directory components are joined"
+ , "with \"/\"."
+ ]
+ , "defines":
+ [ "List of defines set for this target and its consumers."
+ , "Each list entry will be prepended by \"-D\"."
+ ]
+ , "cflags":
+ ["List of compile flags set for this target and its consumers."]
+ , "ldflags":
+ ["Additional linker flags (typically for linking system libraries)."]
+ , "pkg-config":
+ [ "Pkg-config file for optional infer of public cflags and ldflags. If"
+ , "multiple files are specified (e.g., one depends on the other), the"
+ , "first one is used as entry. Note that if this field is non-empty the"
+ , "tool \"pkg-config\" must be available in \"PATH\", which is taken"
+ , "from [\"CC\", \"defaults\"] or the \"ENV\" variable."
+ ]
+ }
+ , "artifacts_doc":
+ [ "The actual library (libname.a or libname.so). Only static libraries are"
+ , "staged in the specified directory."
+ ]
+ , "runfiles_doc": ["The public headers staged to the specified directory."]
+ , "provides_doc":
+ { "compile-deps":
+ [ "Map of artifacts specifying any additional files that, besides the"
+ , "runfiles have to be present in compile actions of targets depending on"
+ , "this library."
+ ]
+ , "link-deps":
+ [ "Map of artifacts specifying any additional files that, besides the artifacts,"
+ , "have to be present in a link actions of targets depending on this library"
+ ]
+ , "run-libs":
+ [ "Map of artifacts specifying all files, including the artifacts of this"
+ , "library if shared, that have to be present in link actions of targets"
+ , "depending on this library."
+ ]
+ , "link-args":
+ [ "List of strings that have to be added to the command line for linking"
+ , "actions in targets depending on this library."
+ ]
+ , "run-libs-args":
+ [ "List of strings that have to be added to the command line for linking"
+ , "runtime libraries in targets depending on this library."
+ ]
+ , "compile-args":
+ [ "List of strings that have to be added to the command line for compile"
+ , "actions in targets depending on this library."
+ ]
+ }
+ , "imports":
+ { "artifacts": ["./", "../..", "field_artifacts"]
+ , "artifacts_list": ["./", "../..", "field_artifacts_list"]
+ , "stage_field": ["", "stage_singleton_field"]
+ , "prebuilt result": "prebuilt result"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "name"
+ , { "type": "assert_non_empty"
+ , "msg": "name is required for prebuilt library"
+ , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "name"}}
+ }
+ ]
+ , ["version", {"type": "FIELD", "name": "version"}]
+ , [ "stage"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": {"type": "FIELD", "name": "stage"}
+ }
+ ]
+ , [ "cflags"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "FIELD", "name": "cflags"}
+ , { "type": "foreach"
+ , "var": "def"
+ , "range": {"type": "FIELD", "name": "defines"}
+ , "body":
+ {"type": "join", "$1": ["-D", {"type": "var", "name": "def"}]}
+ }
+ ]
+ }
+ ]
+ , ["ldflags", {"type": "FIELD", "name": "ldflags"}]
+ , [ "libs"
+ , { "type": "let*"
+ , "bindings": [["fieldname", "lib"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts_list"}
+ }
+ ]
+ , [ "hdrs"
+ , { "type": "let*"
+ , "bindings": [["fieldname", "hdrs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts_list"}
+ }
+ ]
+ , [ "config_reader"
+ , { "type": "let*"
+ , "bindings":
+ [["fieldname", "config_reader"], ["location", "config_reader"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "stage_field"}
+ }
+ ]
+ , [ "pkg-configs"
+ , { "type": "let*"
+ , "bindings": [["fieldname", "pkg-config"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts_list"}
+ }
+ ]
+ , ["deps-fieldnames", ["deps"]]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "prebuilt result"}
+ }
+ }
+}
diff --git a/rules/CC/prebuilt/read_pkgconfig.py b/rules/CC/prebuilt/read_pkgconfig.py
new file mode 100755
index 0000000..cb4154f
--- /dev/null
+++ b/rules/CC/prebuilt/read_pkgconfig.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+# Copyright 2023 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import os
+import subprocess
+import sys
+from pathlib import Path
+
+
+def run_pkgconfig(args: list[str], env: dict[str, str]) -> str:
+ result = subprocess.run(["pkg-config"] + args, env=env, capture_output=True)
+ if result.returncode != 0:
+ print(result.stderr.decode("utf-8"), file=sys.stderr)
+ exit(1)
+ return result.stdout.decode("utf-8").strip()
+
+
+def read_ldflags(pkg: str, env: dict[str, str]) -> str:
+ def libname(filename: str) -> str:
+ return filename.split(".")[0]
+
+ local_libs = {
+ libname(f)
+ for it in os.walk(".") for f in it[2] if f.startswith("lib")
+ }
+
+ link_flags = run_pkgconfig(["--libs-only-l", pkg], env).split(" ")
+
+ # deduplicate, keep right-most
+ seen: set[str] = set()
+ link_flags = [
+ f for f in link_flags[::-1] if f not in seen and not seen.add(f)
+ ][::-1]
+
+ def is_local(flag: str) -> bool:
+ if not flag.startswith("-l"):
+ return False
+ lib = libname(flag[3:]) if flag.startswith("-l:") else f"lib{flag[2:]}"
+ return lib in local_libs
+
+ return " ".join([f for f in link_flags if not is_local(f)])
+
+
+def read_pkgconfig():
+ if len(sys.argv) < 3:
+ print(f"usage: read_pkgconfig OUT_NAME PC_FILE")
+ exit(1)
+
+ name = sys.argv[1]
+ pkg = Path(sys.argv[2]).stem
+ env = dict(os.environ, PKG_CONFIG_PATH="./lib/pkgconfig")
+
+ if name.endswith(".cflags"):
+ data = run_pkgconfig(["--cflags-only-other", pkg], env)
+ else:
+ data = read_ldflags(pkg, env)
+
+ with open(f"{name}", 'w') as f:
+ f.write(data)
+
+
+if __name__ == "__main__":
+ read_pkgconfig()
diff --git a/rules/CC/proto/EXPRESSIONS b/rules/CC/proto/EXPRESSIONS
new file mode 100644
index 0000000..1ab17a5
--- /dev/null
+++ b/rules/CC/proto/EXPRESSIONS
@@ -0,0 +1,308 @@
+{ "protoc-deps":
+ { "imports": {"map_provider": ["./", "../..", "field_map_provider"]}
+ , "expression":
+ { "type": "let*"
+ , "bindings": [["fieldname", "deps"], ["provider", "protoc-deps"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "map_provider"}
+ }
+ }
+, "protoc-compile":
+ { "vars":
+ [ "CXX"
+ , "CXXFLAGS"
+ , "ADD_CXXFLAGS"
+ , "AR"
+ , "ENV"
+ , "name"
+ , "stage"
+ , "service support"
+ , "deps-transition"
+ , "public-fieldnames"
+ , "private-fieldnames"
+ ]
+ , "imports":
+ { "stage": ["", "stage_singleton_field"]
+ , "result": ["./", "..", "lib result"]
+ , "artifacts": ["./", "../..", "field_artifacts"]
+ , "artifacts_list": ["./", "../..", "field_artifacts_list"]
+ , "protoc-deps": "protoc-deps"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["pure C", false]
+ , [ "protoc"
+ , { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "protoc"]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ , ["location", "protoc"]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "stage"}
+ }
+ ]
+ , [ "grpc_cpp_plugin"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "service support"}
+ , "then":
+ { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "grpc_cpp_plugin"]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ , ["location", "grpc_cpp_plugin"]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "stage"}
+ }
+ , "else": {"type": "empty_map"}
+ }
+ ]
+ , ["protoc-deps", {"type": "CALL_EXPRESSION", "name": "protoc-deps"}]
+ , [ "proto deps"
+ , { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "well_known_protos"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ }
+ ]
+ , [ "proto srcs"
+ , { "type": "disjoint_map_union"
+ , "msg": "Sources may not conflict"
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "srcs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts_list"}
+ }
+ }
+ ]
+ , [ "all proto srcs"
+ , { "type": "disjoint_map_union"
+ , "msg": "Conflict with proto files of dependencies"
+ , "$1":
+ [ {"type": "var", "name": "protoc-deps"}
+ , {"type": "var", "name": "proto srcs"}
+ ]
+ }
+ ]
+ , [ "staged srcs"
+ , { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1": {"type": "var", "name": "proto srcs"}
+ }
+ ]
+ , [ "staged all proto srcs"
+ , { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1": {"type": "var", "name": "all proto srcs"}
+ }
+ ]
+ , [ "outs"
+ , { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "f"
+ , "range":
+ {"type": "keys", "$1": {"type": "var", "name": "staged srcs"}}
+ , "body":
+ { "type": "++"
+ , "$1":
+ [ [ { "type": "change_ending"
+ , "$1": {"type": "var", "name": "f"}
+ , "ending": ".pb.h"
+ }
+ , { "type": "change_ending"
+ , "$1": {"type": "var", "name": "f"}
+ , "ending": ".pb.cc"
+ }
+ ]
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "service support"}
+ , "then":
+ [ { "type": "change_ending"
+ , "$1": {"type": "var", "name": "f"}
+ , "ending": ".grpc.pb.h"
+ }
+ , { "type": "change_ending"
+ , "$1": {"type": "var", "name": "f"}
+ , "ending": ".grpc.pb.cc"
+ }
+ ]
+ , "else": []
+ }
+ ]
+ }
+ }
+ }
+ ]
+ , [ "cmd"
+ , { "type": "++"
+ , "$1":
+ [ ["./protoc", "--proto_path=work", "--cpp_out=work"]
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "service support"}
+ , "then":
+ [ "--grpc_out=work"
+ , "--plugin=protoc-gen-grpc=./grpc_cpp_plugin"
+ ]
+ , "else": []
+ }
+ , {"type": "keys", "$1": {"type": "var", "name": "staged srcs"}}
+ ]
+ }
+ ]
+ , [ "generated"
+ , { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "staged all proto srcs"}
+ , {"type": "var", "name": "protoc"}
+ , {"type": "var", "name": "grpc_cpp_plugin"}
+ , {"type": "var", "name": "proto deps"}
+ ]
+ }
+ , "outs": {"type": "var", "name": "outs"}
+ , "cmd": {"type": "var", "name": "cmd"}
+ }
+ ]
+ , [ "srcs"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "foreach"
+ , "var": "name"
+ , "range":
+ {"type": "keys", "$1": {"type": "var", "name": "proto srcs"}}
+ , "body":
+ { "type": "map_union"
+ , "$1":
+ [ { "type": "singleton_map"
+ , "key":
+ { "type": "change_ending"
+ , "$1": {"type": "var", "name": "name"}
+ , "ending": ".pb.cc"
+ }
+ , "value":
+ { "type": "lookup"
+ , "map": {"type": "var", "name": "generated"}
+ , "key":
+ { "type": "join"
+ , "$1":
+ [ "work/"
+ , { "type": "change_ending"
+ , "$1": {"type": "var", "name": "name"}
+ , "ending": ".pb.cc"
+ }
+ ]
+ }
+ }
+ }
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "service support"}
+ , "then":
+ { "type": "singleton_map"
+ , "key":
+ { "type": "change_ending"
+ , "$1": {"type": "var", "name": "name"}
+ , "ending": ".grpc.pb.cc"
+ }
+ , "value":
+ { "type": "lookup"
+ , "map": {"type": "var", "name": "generated"}
+ , "key":
+ { "type": "join"
+ , "$1":
+ [ "work/"
+ , { "type": "change_ending"
+ , "$1": {"type": "var", "name": "name"}
+ , "ending": ".grpc.pb.cc"
+ }
+ ]
+ }
+ }
+ }
+ , "else": {"type": "empty_map"}
+ }
+ ]
+ }
+ }
+ }
+ ]
+ , [ "hdrs"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "foreach"
+ , "var": "name"
+ , "range":
+ {"type": "keys", "$1": {"type": "var", "name": "proto srcs"}}
+ , "body":
+ { "type": "map_union"
+ , "$1":
+ [ { "type": "singleton_map"
+ , "key":
+ { "type": "change_ending"
+ , "$1": {"type": "var", "name": "name"}
+ , "ending": ".pb.h"
+ }
+ , "value":
+ { "type": "lookup"
+ , "map": {"type": "var", "name": "generated"}
+ , "key":
+ { "type": "join"
+ , "$1":
+ [ "work/"
+ , { "type": "change_ending"
+ , "$1": {"type": "var", "name": "name"}
+ , "ending": ".pb.h"
+ }
+ ]
+ }
+ }
+ }
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "service support"}
+ , "then":
+ { "type": "singleton_map"
+ , "key":
+ { "type": "change_ending"
+ , "$1": {"type": "var", "name": "name"}
+ , "ending": ".grpc.pb.h"
+ }
+ , "value":
+ { "type": "lookup"
+ , "map": {"type": "var", "name": "generated"}
+ , "key":
+ { "type": "join"
+ , "$1":
+ [ "work/"
+ , { "type": "change_ending"
+ , "$1": {"type": "var", "name": "name"}
+ , "ending": ".grpc.pb.h"
+ }
+ ]
+ }
+ }
+ }
+ , "else": {"type": "empty_map"}
+ }
+ ]
+ }
+ }
+ }
+ ]
+ , ["private-hdrs", {"type": "empty_map"}]
+ , [ "extra-provides"
+ , { "type": "singleton_map"
+ , "key": "protoc-deps"
+ , "value": {"type": "var", "name": "all proto srcs"}
+ }
+ ]
+ , ["cflags", []]
+ , ["private-cflags", ["-Wno-sign-conversion", "-Wno-unused-function"]]
+ , ["private-ldflags", []]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "result"}
+ }
+ }
+}
diff --git a/rules/CC/proto/RULES b/rules/CC/proto/RULES
new file mode 100644
index 0000000..d1cfc4e
--- /dev/null
+++ b/rules/CC/proto/RULES
@@ -0,0 +1,93 @@
+{ "library":
+ { "doc":
+ [ "A library C++ library, generated from proto files."
+ , ""
+ , "This rule usually is used to bind anonymous targets generated from"
+ , "proto libraries."
+ ]
+ , "string_fields": ["name", "stage"]
+ , "target_fields": ["srcs", "deps"]
+ , "config_vars":
+ ["OS", "ARCH", "HOST_ARCH", "CXX", "CFLAGS", "ADD_CFLAGS", "AR", "ENV"]
+ , "implicit":
+ { "protoc": [["@", "protoc", "", "protoc"]]
+ , "defaults": [["./", "..", "defaults"]]
+ , "proto-deps": [["@", "protoc", "", "C++ runtime"]]
+ , "well_known_protos": [["@", "protoc", "", "well_known_protos"]]
+ }
+ , "imports":
+ { "protoc-compile": "protoc-compile"
+ , "host transition": ["transitions", "for host"]
+ }
+ , "config_transitions":
+ {"protoc": [{"type": "CALL_EXPRESSION", "name": "host transition"}]}
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["name", {"type": "join", "$1": {"type": "FIELD", "name": "name"}}]
+ , [ "stage"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": {"type": "FIELD", "name": "stage"}
+ }
+ ]
+ , [ "deps-transition"
+ , {"type": "CALL_EXPRESSION", "name": "host transition"}
+ ]
+ , ["public-fieldnames", ["deps", "proto-deps"]]
+ , ["private-fieldnames", ["deps", "proto-deps"]]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "protoc-compile"}
+ }
+ }
+, "service library":
+ { "doc":
+ [ "A service library C++ library, generated from proto files."
+ , ""
+ , "Calls protoc with gRPC plugin to additionally generate gRPC services"
+ , "from proto libraries."
+ ]
+ , "string_fields": ["name", "stage"]
+ , "target_fields": ["srcs", "deps"]
+ , "config_vars":
+ ["OS", "ARCH", "HOST_ARCH", "CXX", "CXXFLAGS", "ADD_CXXFLAGS", "AR", "ENV"]
+ , "implicit":
+ { "protoc": [["@", "protoc", "", "protoc"]]
+ , "grpc_cpp_plugin": [["@", "grpc", "src/compiler", "grpc_cpp_plugin"]]
+ , "defaults": [["./", "..", "defaults"]]
+ , "proto-deps":
+ [ ["@", "grpc", "", "grpc++_codegen_proto"]
+ , ["@", "protoc", "", "C++ runtime"]
+ ]
+ , "well_known_protos": [["@", "protoc", "", "well_known_protos"]]
+ }
+ , "imports":
+ { "protoc-compile": "protoc-compile"
+ , "host transition": ["transitions", "for host"]
+ }
+ , "config_transitions":
+ { "protoc": [{"type": "CALL_EXPRESSION", "name": "host transition"}]
+ , "grpc_cpp_plugin":
+ [{"type": "CALL_EXPRESSION", "name": "host transition"}]
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ ["service support", true]
+ , ["name", {"type": "join", "$1": {"type": "FIELD", "name": "name"}}]
+ , [ "stage"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": {"type": "FIELD", "name": "stage"}
+ }
+ ]
+ , [ "deps-transition"
+ , {"type": "CALL_EXPRESSION", "name": "host transition"}
+ ]
+ , ["public-fieldnames", ["deps", "proto-deps"]]
+ , ["private-fieldnames", ["deps", "proto-deps"]]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "protoc-compile"}
+ }
+ }
+}
diff --git a/rules/CC/test/RULES b/rules/CC/test/RULES
new file mode 100644
index 0000000..b46d6b0
--- /dev/null
+++ b/rules/CC/test/RULES
@@ -0,0 +1,338 @@
+{ "test":
+ { "doc": ["A test written in C++"]
+ , "tainted": ["test"]
+ , "target_fields": ["srcs", "private-hdrs", "private-deps", "data"]
+ , "string_fields":
+ [ "name"
+ , "args"
+ , "stage"
+ , "pure C"
+ , "private-defines"
+ , "private-cflags"
+ , "private-ldflags"
+ ]
+ , "config_vars":
+ [ "ARCH"
+ , "HOST_ARCH"
+ , "CC"
+ , "CXX"
+ , "CFLAGS"
+ , "CXXFLAGS"
+ , "LDFLAGS"
+ , "ADD_CFLAGS"
+ , "ADD_CXXFLAGS"
+ , "ADD_LDFLAGS"
+ , "ENV"
+ , "BUILD_POSITION_INDEPENDENT"
+ , "TEST_ENV"
+ , "CC_TEST_LAUNCHER"
+ ]
+ , "implicit":
+ {"defaults": [["./", "..", "defaults"]], "runner": ["test_runner.py"]}
+ , "field_doc":
+ { "name":
+ [ "The name of the test"
+ , ""
+ , "Used to name the test binary as well as for staging the test result"
+ ]
+ , "args": ["Command line arguments for the test binary"]
+ , "srcs": ["The sources of the test binary"]
+ , "private-hdrs":
+ [ "Any additional header files that need to be present when compiling"
+ , "the test binary."
+ ]
+ , "private-defines":
+ [ "List of defines set for source files local to this target."
+ , "Each list entry will be prepended by \"-D\"."
+ ]
+ , "private-cflags":
+ ["List of compile flags set for source files local to this target."]
+ , "private-ldflags":
+ [ "Additional linker flags for linking external libraries (not built"
+ , "by this tool, typically system libraries)."
+ ]
+ , "stage":
+ [ "The logical location of all header and source files."
+ , "Individual directory components are joined with \"/\"."
+ ]
+ , "data": ["Any files the test binary needs access to when running"]
+ }
+ , "config_doc":
+ { "CC": ["The name of the C compiler to be used."]
+ , "CXX": ["The name of the C++ compiler to be used."]
+ , "CFLAGS":
+ [ "The flags for CC 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"
+ ]
+ , "LDFLAGS":
+ [ "The linker flags do 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"
+ ]
+ , "ADD_LDFLAGS":
+ [ "The linker flags to add to the default ones"
+ , "taken from the [\"CC\", \"defaults\"] target"
+ ]
+ , "ENV": ["The environment for any action generated."]
+ , "BUILD_POSITION_INDEPENDENT": ["Build with -fPIC."]
+ , "TEST_ENV": ["The environment for executing the test runner."]
+ , "CC_TEST_LAUNCHER":
+ [ "List of strings representing the launcher that is prepend to the"
+ , "command line for running the test binary."
+ ]
+ }
+ , "artifacts_doc":
+ [ "result: the result of this test (\"PASS\" or \"FAIL\"); useful for"
+ , " generating test reports."
+ , "stdout/stderr: Any output the invocation of the test binary produced on"
+ , " the respective file descriptor"
+ , "time-start/time-stop: The time (decimally coded) in seconds since the"
+ , " epoch when the test invocation started and ended."
+ ]
+ , "runfiles_doc":
+ [ "A tree consisting of the artifacts staged at the name of the test."
+ , "As the built-in \"install\" rule only takes the runfiles of its"
+ , "\"private-deps\" argument, this gives an easy way of defining test"
+ , "suites."
+ ]
+ , "imports":
+ { "artifacts": ["./", "../..", "field_artifacts"]
+ , "runfiles": ["./", "../..", "field_runfiles"]
+ , "compile-deps": ["./", "..", "compile-deps"]
+ , "compile-args-deps": ["./", "..", "compile-args-deps"]
+ , "link-deps": ["./", "..", "link-deps"]
+ , "link-args-deps": ["./", "..", "link-args-deps"]
+ , "run-libs-deps": ["./", "..", "run-libs-deps"]
+ , "run-libs-args-deps": ["./", "..", "run-libs-args-deps"]
+ , "cflags-files-deps": ["./", "..", "cflags-files-deps"]
+ , "ldflags-files-deps": ["./", "..", "ldflags-files-deps"]
+ , "binary": ["./", "..", "bin artifact"]
+ , "host transition": ["transitions", "for host"]
+ }
+ , "config_transitions":
+ { "defaults": [{"type": "CALL_EXPRESSION", "name": "host transition"}]
+ , "private-deps": [{"type": "CALL_EXPRESSION", "name": "host transition"}]
+ , "data": [{"type": "CALL_EXPRESSION", "name": "host transition"}]
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "name"
+ , { "type": "assert_non_empty"
+ , "msg": "A non-empty name has to be provided for binaries"
+ , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "name"}}
+ }
+ ]
+ , ["pure C", {"type": "FIELD", "name": "pure C"}]
+ , [ "stage"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1": {"type": "FIELD", "name": "stage"}
+ }
+ ]
+ , [ "srcs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "srcs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ }
+ ]
+ , [ "private-hdrs"
+ , { "type": "to_subdir"
+ , "subdir": {"type": "var", "name": "stage"}
+ , "$1":
+ { "type": "let*"
+ , "bindings": [["fieldname", "private-hdrs"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ }
+ ]
+ , ["host-trans", {"type": "CALL_EXPRESSION", "name": "host transition"}]
+ , ["defaults-transition", {"type": "var", "name": "host-trans"}]
+ , ["deps-transition", {"type": "var", "name": "host-trans"}]
+ , ["deps-fieldnames", ["private-deps"]]
+ , [ "cflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "cflags-files-deps"}
+ ]
+ , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}]
+ , [ "compile-args"
+ , { "type": "++"
+ , "$1":
+ [ { "type": "foreach"
+ , "var": "def"
+ , "range": {"type": "FIELD", "name": "private-defines"}
+ , "body":
+ {"type": "join", "$1": ["-D", {"type": "var", "name": "def"}]}
+ }
+ , {"type": "FIELD", "name": "private-cflags"}
+ , {"type": "CALL_EXPRESSION", "name": "compile-args-deps"}
+ ]
+ }
+ ]
+ , [ "ldflags-files"
+ , {"type": "CALL_EXPRESSION", "name": "ldflags-files-deps"}
+ ]
+ , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
+ , [ "link-args"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "link-args-deps"}
+ , {"type": "FIELD", "name": "private-ldflags"}
+ ]
+ }
+ ]
+ , ["run-libs", {"type": "CALL_EXPRESSION", "name": "run-libs-deps"}]
+ , [ "run-libs-args"
+ , {"type": "CALL_EXPRESSION", "name": "run-libs-args-deps"}
+ ]
+ , ["binary", {"type": "CALL_EXPRESSION", "name": "binary"}]
+ , [ "staged test binary"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "foreach_map"
+ , "range": {"type": "var", "name": "binary"}
+ , "var_val": "binary"
+ , "body":
+ { "type": "singleton_map"
+ , "key": "test"
+ , "value": {"type": "var", "name": "binary"}
+ }
+ }
+ }
+ ]
+ , [ "runner"
+ , { "type": "map_union"
+ , "$1":
+ { "type": "foreach"
+ , "var": "runner"
+ , "range": {"type": "FIELD", "name": "runner"}
+ , "body":
+ { "type": "map_union"
+ , "$1":
+ { "type": "foreach"
+ , "var": "runner"
+ , "range":
+ { "type": "values"
+ , "$1":
+ { "type": "DEP_ARTIFACTS"
+ , "dep": {"type": "var", "name": "runner"}
+ }
+ }
+ , "body":
+ { "type": "singleton_map"
+ , "key": "runner"
+ , "value": {"type": "var", "name": "runner"}
+ }
+ }
+ }
+ }
+ }
+ ]
+ , [ "test-args"
+ , { "type": "singleton_map"
+ , "key": "test-args.json"
+ , "value":
+ { "type": "BLOB"
+ , "data":
+ { "type": "json_encode"
+ , "$1": {"type": "FIELD", "name": "args", "default": []}
+ }
+ }
+ }
+ ]
+ , [ "test-launcher"
+ , { "type": "singleton_map"
+ , "key": "test-launcher.json"
+ , "value":
+ { "type": "BLOB"
+ , "data":
+ { "type": "json_encode"
+ , "$1":
+ {"type": "var", "name": "CC_TEST_LAUNCHER", "default": []}
+ }
+ }
+ }
+ ]
+ , [ "data"
+ , { "type": "let*"
+ , "bindings":
+ [ ["fieldname", "data"]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "runfiles"}
+ , {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ ]
+ }
+ }
+ ]
+ , [ "test-name"
+ , { "type": "join"
+ , "separator": "/"
+ , "$1":
+ [{"type": "var", "name": "stage"}, {"type": "var", "name": "name"}]
+ }
+ ]
+ , [ "test-results"
+ , { "type": "ACTION"
+ , "outs": ["result", "stdout", "stderr", "time-start", "time-stop"]
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1": {"type": "var", "name": "data"}
+ }
+ , {"type": "var", "name": "runner"}
+ , {"type": "var", "name": "test-args"}
+ , {"type": "var", "name": "test-launcher"}
+ , {"type": "var", "name": "staged test binary"}
+ , {"type": "var", "name": "run-libs"}
+ ]
+ }
+ , "cmd": ["./runner"]
+ , "env":
+ { "type": "var"
+ , "name": "TEST_ENV"
+ , "default": {"type": "empty_map"}
+ }
+ , "may_fail": ["test"]
+ , "fail_message":
+ { "type": "join"
+ , "$1":
+ ["CC test ", {"type": "var", "name": "test-name"}, " failed"]
+ }
+ }
+ ]
+ , [ "runfiles"
+ , { "type": "singleton_map"
+ , "key": {"type": "var", "name": "name"}
+ , "value":
+ {"type": "TREE", "$1": {"type": "var", "name": "test-results"}}
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts": {"type": "var", "name": "test-results"}
+ , "runfiles": {"type": "var", "name": "runfiles"}
+ }
+ }
+ }
+}
diff --git a/rules/CC/test/TARGETS b/rules/CC/test/TARGETS
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/rules/CC/test/TARGETS
@@ -0,0 +1 @@
+{}
diff --git a/rules/CC/test/test_runner.py b/rules/CC/test/test_runner.py
new file mode 100755
index 0000000..0647621
--- /dev/null
+++ b/rules/CC/test/test_runner.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python3
+# Copyright 2022 Huawei Cloud Computing Technology Co., Ltd.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import json
+import os
+import subprocess
+import time
+
+time_start = time.time()
+time_stop = 0
+result = "UNKNOWN"
+stderr = ""
+stdout = ""
+
+
+def dump_results():
+ with open("result", "w") as f:
+ f.write("%s\n" % (result, ))
+ with open("time-start", "w") as f:
+ f.write("%d\n" % (time_start, ))
+ with open("time-stop", "w") as f:
+ f.write("%d\n" % (time_stop, ))
+ with open("stdout", "w") as f:
+ f.write("%s\n" % (stdout, ))
+ with open("stderr", "w") as f:
+ f.write("%s\n" % (stderr, ))
+
+
+dump_results()
+
+TEMP_DIR = os.path.realpath("scratch")
+os.makedirs(TEMP_DIR, exist_ok=True)
+
+WORK_DIR = os.path.realpath("work")
+os.makedirs(WORK_DIR, exist_ok=True)
+
+ENV = dict(os.environ, TEST_TMPDIR=TEMP_DIR)
+
+with open('test-launcher.json') as f:
+ test_launcher = json.load(f)
+
+with open('test-args.json') as f:
+ test_args = json.load(f)
+
+ret = subprocess.run(test_launcher + ["../test"] + test_args,
+ cwd=WORK_DIR,
+ env=ENV,
+ capture_output=True)
+
+time_stop = time.time()
+result = "PASS" if ret.returncode == 0 else "FAIL"
+stdout = ret.stdout.decode("utf-8")
+stderr = ret.stderr.decode("utf-8")
+
+dump_results()
+
+if result != "PASS": exit(1)