diff options
-rw-r--r-- | CC/EXPRESSIONS | 504 | ||||
-rw-r--r-- | CC/RULES | 538 | ||||
-rw-r--r-- | CC/proto/EXPRESSIONS | 301 | ||||
-rw-r--r-- | CC/proto/RULES | 72 | ||||
-rw-r--r-- | CC/test/RULES | 265 | ||||
-rw-r--r-- | CC/test/test_runner.sh | 36 | ||||
-rw-r--r-- | EXPRESSIONS | 89 | ||||
-rw-r--r-- | data/RULES | 42 | ||||
-rw-r--r-- | proto/RULES | 105 | ||||
-rw-r--r-- | transitions/EXPRESSIONS | 13 |
10 files changed, 1965 insertions, 0 deletions
diff --git a/CC/EXPRESSIONS b/CC/EXPRESSIONS new file mode 100644 index 0000000..f1e6592 --- /dev/null +++ b/CC/EXPRESSIONS @@ -0,0 +1,504 @@ +{ "default-CC": + { "expression": + { "type": "join" + , "$1": + { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "defaults"} + , "body": + { "type": "DEP_PROVIDES" + , "provider": "CC" + , "dep": {"type": "var", "name": "x"} + } + } + } + } + } +, "default-CXX": + { "expression": + { "type": "join" + , "$1": + { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "defaults"} + , "body": + { "type": "DEP_PROVIDES" + , "provider": "CXX" + , "dep": {"type": "var", "name": "x"} + } + } + } + } + } +, "default-CFLAGS": + { "expression": + { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "defaults"} + , "body": + { "type": "DEP_PROVIDES" + , "provider": "CFLAGS" + , "dep": {"type": "var", "name": "x"} + } + } + } + } +, "default-CXXFLAGS": + { "expression": + { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "defaults"} + , "body": + { "type": "DEP_PROVIDES" + , "provider": "CXXFLAGS" + , "dep": {"type": "var", "name": "x"} + } + } + } + } +, "default-ENV": + { "expression": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "defaults"} + , "body": + { "type": "DEP_PROVIDES" + , "provider": "ENV" + , "dep": {"type": "var", "name": "x"} + } + } + } +, "configure transition": + { "expression": + { "type": "let*" + , "bindings": + [ [ "OS" + , { "type": "assert_non_empty" + , "msg": "Missing field \"os\" for \"configure\"." + , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "os"}} + } + ] + , [ "ARCH" + , { "type": "assert_non_empty" + , "msg": "Missing field \"arch\" for \"configure\"." + , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "arch"}} + } + ] + , ["HOST_ARCH", {"type": "var", "name": "ARCH"}] + , [ "TARGET_ARCH" + , {"type": "join", "$1": {"type": "FIELD", "name": "target_arch"}} + ] + , [ "TARGET_ARCH" + , { "type": "if" + , "cond": {"type": "var", "name": "TARGET_ARCH"} + , "then": {"type": "var", "name": "TARGET_ARCH"} + , "else": {"type": "var", "name": "ARCH"} + } + ] + ] + , "body": + { "type": "map_union" + , "$1": + [ { "type": "singleton_map" + , "key": "OS" + , "value": {"type": "var", "name": "OS"} + } + , { "type": "singleton_map" + , "key": "ARCH" + , "value": {"type": "var", "name": "TARGET_ARCH"} + } + , { "type": "singleton_map" + , "key": "HOST_ARCH" + , "value": {"type": "var", "name": "HOST_ARCH"} + } + , { "type": "singleton_map" + , "key": "TARGET_ARCH" + , "value": {"type": "var", "name": "TARGET_ARCH"} + } + ] + } + } + } +, "compile-deps": + { "expression": + { "type": "disjoint_map_union" + , "$1": + { "type": "++" + , "$1": + [ { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "compile-deps" + , "default": {"type": "empty_map"} + } + } + , { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "dep"}} + } + , { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "proto-deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "compile-deps" + , "default": {"type": "empty_map"} + } + } + , { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "proto-deps"} + , "body": + {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "dep"}} + } + ] + } + } + } +, "link-deps": + { "expression": + { "type": "disjoint_map_union" + , "$1": + { "type": "++" + , "$1": + [ { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "link-deps" + , "default": {"type": "empty_map"} + } + } + , { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + {"type": "DEP_ARTIFACTS", "dep": {"type": "var", "name": "dep"}} + } + , { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "proto-deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "link-deps" + , "default": {"type": "empty_map"} + } + } + , { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "proto-deps"} + , "body": + {"type": "DEP_ARTIFACTS", "dep": {"type": "var", "name": "dep"}} + } + ] + } + } + } +, "objects": + { "vars": ["CXX", "CXXFLAGS", "ENV", "srcs", "compile-deps", "local hdrs"] + , "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": "var", "name": "local 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"} + } + ] + } + ] + , [ "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"} + , "cmd": + { "type": "++" + , "$1": + [ [{"type": "var", "name": "CXX"}] + , {"type": "var", "name": "CXXFLAGS"} + , ["-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"} + } + } + } + } + } +, "lib result": + { "vars": + [ "CXX" + , "CXXFLAGS" + , "CC" + , "CFLAGS" + , "ENV" + , "AR" + , "srcs" + , "hdrs" + , "private-hdrs" + , "link external" + , "extra-provides" + ] + , "imports": + { "artifacts": ["./", "..", "field_artifacts"] + , "compile-deps": "compile-deps" + , "link-deps": "link-deps" + , "objects": "objects" + , "default-CC": "default-CC" + , "default-CXX": "default-CXX" + , "default-CFLAGS": "default-CFLAGS" + , "default-CXXFLAGS": "default-CXXFLAGS" + , "default-ENV": "default-ENV" + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "stage" + , { "type": "join" + , "separator": "/" + , "$1": {"type": "FIELD", "name": "stage"} + } + ] + , [ "CXX" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "pure C"} + , "then": + { "type": "var" + , "name": "CC" + , "default": {"type": "CALL_EXPRESSION", "name": "default-CC"} + } + , "else": + { "type": "var" + , "name": "CXX" + , "default": {"type": "CALL_EXPRESSION", "name": "default-CXX"} + } + } + ] + , [ "CXXFLAGS" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "pure C"} + , "then": + { "type": "var" + , "name": "CFLAGS" + , "default": {"type": "CALL_EXPRESSION", "name": "default-CFLAGS"} + } + , "else": + { "type": "var" + , "name": "CXXFLAGS" + , "default": + {"type": "CALL_EXPRESSION", "name": "default-CXXFLAGS"} + } + } + ] + , [ "ENV" + , { "type": "map_union" + , "$1": + { "type": "++" + , "$1": + [ {"type": "CALL_EXPRESSION", "name": "default-ENV"} + , [ { "type": "var" + , "name": "ENV" + , "default": {"type": "empty_map"} + } + ] + ] + } + } + ] + , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}] + , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}] + , [ "local hdrs" + , { "type": "disjoint_map_union" + , "$1": + [ {"type": "var", "name": "hdrs"} + , {"type": "var", "name": "private-hdrs"} + ] + } + ] + , ["objects", {"type": "CALL_EXPRESSION", "name": "objects"}] + , [ "base name" + , {"type": "join", "$1": {"type": "FIELD", "name": "name"}} + ] + , [ "libname" + , { "type": "join" + , "$1": ["lib", {"type": "var", "name": "base name"}, ".a"] + } + ] + , [ "lib" + , { "type": "if" + , "cond": {"type": "var", "name": "objects"} + , "else": {"type": "empty_map"} + , "then": + { "type": "ACTION" + , "outs": [{"type": "var", "name": "libname"}] + , "inputs": {"type": "var", "name": "objects"} + , "cmd": + { "type": "++" + , "$1": + [ [ {"type": "var", "name": "AR", "default": "ar"} + , "cqs" + , {"type": "var", "name": "libname"} + ] + , {"type": "keys", "$1": {"type": "var", "name": "objects"}} + ] + } + } + } + ] + , [ "lib" + , { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "$1": {"type": "var", "name": "lib"} + } + ] + , [ "link-args" + , { "type": "nub_right" + , "$1": + { "type": "++" + , "$1": + [ {"type": "keys", "$1": {"type": "var", "name": "lib"}} + , { "type": "++" + , "$1": + { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "link-args" + } + } + } + , { "type": "++" + , "$1": + { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "proto-deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "link-args" + } + } + } + , {"type": "var", "name": "link external", "default": []} + ] + } + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "var", "name": "lib"} + , "runfiles": {"type": "var", "name": "hdrs"} + , "provides": + { "type": "map_union" + , "$1": + [ { "type": "singleton_map" + , "key": "compile-deps" + , "value": {"type": "var", "name": "compile-deps"} + } + , { "type": "singleton_map" + , "key": "link-deps" + , "value": {"type": "var", "name": "link-deps"} + } + , { "type": "singleton_map" + , "key": "link-args" + , "value": {"type": "var", "name": "link-args"} + } + , { "type": "var" + , "name": "extra-provides" + , "default": {"type": "empty_map"} + } + ] + } + } + } + } +} diff --git a/CC/RULES b/CC/RULES new file mode 100644 index 0000000..93d5afc --- /dev/null +++ b/CC/RULES @@ -0,0 +1,538 @@ +{ "defaults": + { "doc": + [ "A rule to provide defaults." + , "All CC targets take their defaults for CXX, CC, 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." + ] + , "string_fields": ["CC", "CXX", "CFLAGS", "CXXFLAGS", "PATH", "AR"] + , "expression": + { "type": "RESULT" + , "provides": + { "type": "map_union" + , "$1": + [ { "type": "singleton_map" + , "key": "CC" + , "value": {"type": "FIELD", "name": "CC"} + } + , { "type": "singleton_map" + , "key": "CXX" + , "value": {"type": "FIELD", "name": "CXX"} + } + , { "type": "singleton_map" + , "key": "CFLAGS" + , "value": {"type": "FIELD", "name": "CFLAGS"} + } + , { "type": "singleton_map" + , "key": "CXXFLAGS" + , "value": {"type": "FIELD", "name": "CXXFLAGS"} + } + , { "type": "singleton_map" + , "key": "AR" + , "value": {"type": "FIELD", "name": "AR"} + } + , { "type": "singleton_map" + , "key": "ENV" + , "value": + { "type": "singleton_map" + , "key": "PATH" + , "value": + { "type": "join" + , "separator": ":" + , "$1": {"type": "FIELD", "name": "PATH"} + } + } + } + ] + } + } + } +, "configure": + { "doc": + [ "A rule to provide a static platform configuration for a target." + , "The artifacts and runfiles of the specified target will be propagated." + , "The target defined by this rule does not propagate any provides data." + ] + , "config_fields": ["os", "arch", "target_arch"] + , "target_fields": ["target"] + , "field_doc": + { "os": ["The operation system used for building."] + , "arch": ["The architecture used for building."] + , "target_arch": + [ "Non-mandatory target architecture to build for. If omitted, target" + , "architecture is derived from \"arch\"." + ] + , "target": + [ "The target to configure. Multiple targets are supported, but their" + , "artifacts and runfiles should not conflict." + ] + } + , "imports": + { "transition": "configure transition" + , "artifacts": ["./", "..", "field_artifacts"] + , "runfiles": ["./", "..", "field_runfiles"] + } + , "config_transitions": + {"target": [{"type": "CALL_EXPRESSION", "name": "transition"}]} + , "expression": + { "type": "let*" + , "bindings": + [ ["fieldname", "target"] + , ["transition", {"type": "CALL_EXPRESSION", "name": "transition"}] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "CALL_EXPRESSION", "name": "artifacts"} + , "runfiles": {"type": "CALL_EXPRESSION", "name": "runfiles"} + } + } + } +, "header directory": + { "doc": + [ "A directory of header files." + , "" + , "Define a directory of header files that belong together and are staged" + , "in such a way that no other target (used together with this target) will" + , "have to put files in this directory. The typical use case is a library" + , "libfoo that expects all headers to be included as #include \"foo/bar.h\"." + , "In this case, one would define a header direcotry for \"foo\"." + , "" + , "Technically, a tree is created from the given files and staged to the" + , "specified location. Since trees are opaque, the directory name becomes" + , "essentially owned by target. In this way, staging conflicts can be" + , "avoided by detecting them early and not only once a file with the same" + , "name is added to the staging location. Also, as only a tree identifier" + , "has to be passed around, such a directory can be handled more" + , "efficiently by the tool." + ] + , "target_fields": ["hdrs"] + , "string_fields": ["stage", "public stage"] + , "field_doc": + { "hdrs": ["The header files to be put into the header directory."] + , "stage": + [ "The location of the header directory." + , "Path segments are joined with \"/\"." + ] + , "public stage": + [ "If non-empty, no closure for the header directory's stage is created, " + , "so can be combined with other header directories having the same " + , "public staging directory." + ] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "hdrs" + , { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "hdrs"} + , "body": + {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}} + } + } + ] + , [ "stage" + , { "type": "join" + , "separator": "/" + , "$1": {"type": "FIELD", "name": "stage"} + } + ] + , [ "dir" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "public stage"} + , "then": + { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "$1": {"type": "var", "name": "hdrs"} + } + , "else": + { "type": "singleton_map" + , "key": {"type": "var", "name": "stage"} + , "value": {"type": "TREE", "$1": {"type": "var", "name": "hdrs"}} + } + } + ] + ] + , "body": + { "type": "RESULT" + , "artifacts": {"type": "var", "name": "dir"} + , "runfiles": {"type": "var", "name": "dir"} + } + } + } +, "library": + { "doc": ["A C++ libaray"] + , "target_fields": ["srcs", "hdrs", "private-hdrs", "deps", "proto"] + , "string_fields": + ["name", "stage", "pure C", "local defines", "link external"] + , "config_vars": ["CXX", "CC", "CXXFLAGS", "CFLAGS", "ENV", "AR"] + , "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" + ] + , "local defines": + [ "List of defines set for source files local to this target." + , "Each list entry will be prepended by \"-D\"." + ] + , "link external": + ["Additional linker flags for linking external libraries."] + , "deps": ["Any other libraries this library depends upon."] + } + , "config_doc": + { "CXX": ["The name of the C++ compiler to be used."] + , "CC": + ["The name of the C compiler to be used (when compiling pure C code)"] + , "AR": ["The archive tool to used for creating the library"] + , "ENV": ["The environment for any action generated."] + , "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" + ] + , "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" + ] + } + , "anonymous": + { "proto-deps": + { "target": "proto" + , "provider": "proto" + , "rule_map": + { "library": ["./", "proto", "library"] + , "service library": ["./", "proto", "service library"] + } + } + } + , "imports": + { "artifacts": ["./", "..", "field_artifacts"] + , "default-CXXFLAGS": "default-CXXFLAGS" + , "default-CFLAGS": "default-CFLAGS" + , "result": "lib result" + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "local defines" + , { "type": "foreach" + , "var": "def" + , "range": {"type": "FIELD", "name": "local defines"} + , "body": + {"type": "join", "$1": ["-D", {"type": "var", "name": "def"}]} + } + ] + , [ "CFLAGS" + , { "type": "++" + , "$1": + [ { "type": "var" + , "name": "CFLAGS" + , "default": + {"type": "CALL_EXPRESSION", "name": "default-CFLAGS"} + } + , {"type": "var", "name": "local defines"} + ] + } + ] + , [ "CXXFLAGS" + , { "type": "++" + , "$1": + [ { "type": "var" + , "name": "CXXFLAGS" + , "default": + {"type": "CALL_EXPRESSION", "name": "default-CXXFLAGS"} + } + , {"type": "var", "name": "local defines"} + ] + } + ] + , [ "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"} + } + } + ] + , ["link external", {"type": "FIELD", "name": "link external"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "result"} + } + } +, "binary": + { "doc": ["A binary written in C++"] + , "target_fields": ["srcs", "private-hdrs", "deps", "proto"] + , "string_fields": + ["name", "stage", "pure C", "local defines", "link external"] + , "config_vars": ["CXX", "CC", "CXXFLAGS", "CFLAGS", "ENV"] + , "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" + ] + , "local defines": + [ "List of defines set for source files local to this target." + , "Each list entry will be prepended by \"-D\"." + ] + , "link external": + ["Additional linker flags for linking external libraries."] + , "deps": ["Any other libraries this binary depends upon."] + } + , "config_doc": + { "CXX": ["The name of the C++ compiler to be used."] + , "CC": + ["The name of the C compiler to be used (when compiling pure C code)"] + , "ENV": ["The environment for any action generated."] + , "CXXFLAGS": + [ "The flags for CXX to be used instead of the default ones" + , "taken from the [\"CC\", \"defaults\"] target" + ] + , "CFLAGS": + [ "The flags for CXX to be used instead of the default ones" + , "taken from the [\"CC\", \"defaults\"] target" + ] + } + , "anonymous": + { "proto-deps": + { "target": "proto" + , "provider": "proto" + , "rule_map": + { "library": ["./", "proto", "library"] + , "service library": ["./", "proto", "service library"] + } + } + } + , "imports": + { "artifacts": ["./", "..", "field_artifacts"] + , "compile-deps": "compile-deps" + , "link-deps": "link-deps" + , "objects": "objects" + , "default-CC": "default-CC" + , "default-CXX": "default-CXX" + , "default-CFLAGS": "default-CFLAGS" + , "default-CXXFLAGS": "default-CXXFLAGS" + , "default-ENV": "default-ENV" + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "local defines" + , { "type": "foreach" + , "var": "def" + , "range": {"type": "FIELD", "name": "local 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"} + } + } + ] + , [ "local hdrs" + , { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "$1": + { "type": "let*" + , "bindings": [["fieldname", "private-hdrs"]] + , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"} + } + } + ] + , [ "CXX" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "pure C"} + , "then": + { "type": "var" + , "name": "CC" + , "default": {"type": "CALL_EXPRESSION", "name": "default-CC"} + } + , "else": + { "type": "var" + , "name": "CXX" + , "default": {"type": "CALL_EXPRESSION", "name": "default-CXX"} + } + } + ] + , [ "CXXFLAGS" + , { "type": "if" + , "cond": {"type": "FIELD", "name": "pure C"} + , "then": + { "type": "var" + , "name": "CFLAGS" + , "default": {"type": "CALL_EXPRESSION", "name": "default-CFLAGS"} + } + , "else": + { "type": "var" + , "name": "CXXFLAGS" + , "default": + {"type": "CALL_EXPRESSION", "name": "default-CXXFLAGS"} + } + } + ] + , [ "CXXFLAGS" + , { "type": "++" + , "$1": + [ {"type": "var", "name": "CXXFLAGS"} + , {"type": "var", "name": "local defines"} + ] + } + ] + , [ "ENV" + , { "type": "map_union" + , "$1": + { "type": "++" + , "$1": + [ {"type": "CALL_EXPRESSION", "name": "default-ENV"} + , [ { "type": "var" + , "name": "ENV" + , "default": {"type": "empty_map"} + } + ] + ] + } + } + ] + , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}] + , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}] + , ["objects", {"type": "CALL_EXPRESSION", "name": "objects"}] + , [ "base name" + , {"type": "join", "$1": {"type": "FIELD", "name": "name"}} + ] + , [ "binary name" + , { "type": "if" + , "cond": {"type": "var", "name": "stage"} + , "else": {"type": "var", "name": "base name"} + , "then": + { "type": "join" + , "separator": "/" + , "$1": + [ {"type": "var", "name": "stage"} + , {"type": "var", "name": "base name"} + ] + } + } + ] + , [ "link-args" + , { "type": "nub_right" + , "$1": + { "type": "++" + , "$1": + [ {"type": "keys", "$1": {"type": "var", "name": "objects"}} + , { "type": "++" + , "$1": + { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "link-args" + } + } + } + , {"type": "FIELD", "name": "link external"} + ] + } + } + ] + , [ "binary" + , { "type": "ACTION" + , "outs": [{"type": "var", "name": "binary name"}] + , "inputs": + { "type": "disjoint_map_union" + , "$1": + [ {"type": "var", "name": "objects"} + , {"type": "var", "name": "link-deps"} + ] + } + , "cmd": + { "type": "++" + , "$1": + [ [ {"type": "var", "name": "CXX"} + , "-o" + , {"type": "var", "name": "binary name"} + ] + , {"type": "var", "name": "link-args"} + ] + } + , "env": {"type": "var", "name": "ENV"} + } + ] + ] + , "body": + {"type": "RESULT", "artifacts": {"type": "var", "name": "binary"}} + } + } +} diff --git a/CC/proto/EXPRESSIONS b/CC/proto/EXPRESSIONS new file mode 100644 index 0000000..a98c51c --- /dev/null +++ b/CC/proto/EXPRESSIONS @@ -0,0 +1,301 @@ +{ "protoc-deps": + { "expression": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "protoc-deps" + , "default": {"type": "empty_map"} + } + } + } + } +, "protoc-compile": + { "vars": ["transition", "service support"] + , "imports": + { "stage": ["", "stage_singleton_field"] + , "result": ["./", "..", "lib result"] + , "field_runfiles": ["", "field_runfiles"] + , "protoc-deps": "protoc-deps" + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "protoc" + , { "type": "let*" + , "bindings": [["fieldname", "protoc"], ["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"] + , ["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": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "well_known_protos"} + , "body": + {"type": "DEP_ARTIFACTS", "dep": {"type": "var", "name": "x"}} + } + } + } + ] + , [ "proto srcs" + , { "type": "disjoint_map_union" + , "msg": "Sources may not conflict" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "srcs"} + , "body": + {"type": "DEP_ARTIFACTS", "dep": {"type": "var", "name": "x"}} + } + } + ] + , [ "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"} + } + ] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "result"} + } + } +} diff --git a/CC/proto/RULES b/CC/proto/RULES new file mode 100644 index 0000000..04082c1 --- /dev/null +++ b/CC/proto/RULES @@ -0,0 +1,72 @@ +{ "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", "CC", "CXXFLAGS", "CFLAGS", "ENV", "AR"] + , "implicit": + { "protoc": [["@", "protoc", "", "protoc"]] + , "defaults": [["./", "..", "defaults"]] + , "proto-deps": [["@", "protoc", "", "C++ runtime"]] + , "well_known_protos": [["@", "protoc", "", "well_known_protos"]] + , "pure C": [] + } + , "imports": + { "protoc-compile": "protoc-compile" + , "host transition": ["transitions", "for host"] + } + , "config_transitions": + {"protoc": [{"type": "CALL_EXPRESSION", "name": "host transition"}]} + , "expression": + { "type": "let*" + , "bindings": + [["transition", {"type": "CALL_EXPRESSION", "name": "host transition"}]] + , "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", "CC", "CXXFLAGS", "CFLAGS", "ENV", "AR"] + , "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"]] + , "pure C": [] + } + , "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] + , ["transition", {"type": "CALL_EXPRESSION", "name": "host transition"}] + ] + , "body": {"type": "CALL_EXPRESSION", "name": "protoc-compile"} + } + } +} diff --git a/CC/test/RULES b/CC/test/RULES new file mode 100644 index 0000000..de5a485 --- /dev/null +++ b/CC/test/RULES @@ -0,0 +1,265 @@ +{ "test": + { "doc": + [ "A test written in C++" + , "FIXME: the test binary and data must be built for host" + ] + , "tainted": ["test"] + , "target_fields": ["srcs", "private-hdrs", "deps", "data"] + , "string_fields": ["name", "stage"] + , "config_vars": ["CXX", "CC", "CXXFLAGS", "CFLAGS", "ENV"] + , "implicit": + { "defaults": [["./", "..", "defaults"]] + , "proto-deps": [] + , "runner": ["test_runner.sh"] + } + , "field_doc": + { "name": + [ "The name of the test" + , "" + , "Used to name the test binary as well as for staging the test result" + ] + , "srcs": ["The sources of the test binary"] + , "private-hdrs": + [ "Any additional header files that need to be present when compiling" + , "the test binary." + ] + , "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": + { "CXX": ["The name of the C++ compiler to be used."] + , "ENV": ["The environment for any action generated."] + , "CXXFLAGS": + [ "The flags for CXX to be used instead of the default ones" + , "taken from the [\"CC\", \"defaults\"] target" + ] + } + , "imports": + { "artifacts": ["./", "../..", "field_artifacts"] + , "compile-deps": ["./", "..", "compile-deps"] + , "link-deps": ["./", "..", "link-deps"] + , "objects": ["./", "..", "objects"] + , "default-CXX": ["./", "..", "default-CXX"] + , "default-CXXFLAGS": ["./", "..", "default-CXXFLAGS"] + , "default-ENV": ["./", "..", "default-ENV"] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "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"} + } + } + ] + , [ "local hdrs" + , { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "$1": + { "type": "let*" + , "bindings": [["fieldname", "private-hdrs"]] + , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"} + } + } + ] + , [ "CXX" + , { "type": "var" + , "name": "CXX" + , "default": {"type": "CALL_EXPRESSION", "name": "default-CXX"} + } + ] + , [ "CXXFLAGS" + , { "type": "var" + , "name": "CXXFLAGS" + , "default": {"type": "CALL_EXPRESSION", "name": "default-CXXFLAGS"} + } + ] + , [ "ENV" + , { "type": "map_union" + , "$1": + { "type": "++" + , "$1": + [ {"type": "CALL_EXPRESSION", "name": "default-ENV"} + , [ { "type": "var" + , "name": "ENV" + , "default": {"type": "empty_map"} + } + ] + ] + } + } + ] + , ["compile-deps", {"type": "CALL_EXPRESSION", "name": "compile-deps"}] + , ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}] + , ["objects", {"type": "CALL_EXPRESSION", "name": "objects"}] + , [ "base name" + , { "type": "assert_non_empty" + , "msg": "A non-empy name has to be provided" + , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "name"}} + } + ] + , [ "binary name" + , { "type": "if" + , "cond": {"type": "var", "name": "stage"} + , "else": {"type": "var", "name": "base name"} + , "then": + { "type": "join" + , "separator": "/" + , "$1": + [ {"type": "var", "name": "stage"} + , {"type": "var", "name": "base name"} + ] + } + } + ] + , [ "link-args" + , { "type": "nub_right" + , "$1": + { "type": "++" + , "$1": + [ {"type": "keys", "$1": {"type": "var", "name": "objects"}} + , { "type": "++" + , "$1": + { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "dep"} + , "provider": "link-args" + } + } + } + ] + } + } + ] + , [ "binary" + , { "type": "ACTION" + , "outs": [{"type": "var", "name": "binary name"}] + , "inputs": + { "type": "disjoint_map_union" + , "$1": + [ {"type": "var", "name": "objects"} + , {"type": "var", "name": "link-deps"} + ] + } + , "cmd": + { "type": "++" + , "$1": + [ [ {"type": "var", "name": "CXX"} + , "-o" + , {"type": "var", "name": "binary name"} + ] + , {"type": "var", "name": "link-args"} + ] + } + , "env": {"type": "var", "name": "ENV"} + } + ] + , [ "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.sh" + , "value": {"type": "var", "name": "runner"} + } + } + } + } + } + ] + , [ "data" + , { "type": "disjoint_map_union" + , "msg": "Data runfiles may not conflict" + , "$1": + { "type": "foreach" + , "var": "dep" + , "range": {"type": "FIELD", "name": "data"} + , "body": + {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "dep"}} + } + } + ] + , [ "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": "staged test binary"} + ] + } + , "cmd": ["sh", "./runner.sh"] + , "may_fail": ["test"] + , "fail_message": + { "type": "join" + , "$1": + ["CC test ", {"type": "var", "name": "binary name"}, " failed"] + } + } + ] + , [ "runfiles" + , { "type": "singleton_map" + , "key": {"type": "var", "name": "base 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/CC/test/test_runner.sh b/CC/test/test_runner.sh new file mode 100644 index 0000000..ed9f48a --- /dev/null +++ b/CC/test/test_runner.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +# ensure all required outputs are present +touch stdout +touch stderr +RESULT=UNKNOWN +echo "${RESULT}" > result +echo UNKNOWN > time-start +echo UNKNOWN > time-stop + +mkdir scratch +export TEST_TMPDIR=$(realpath scratch) +# Change to the working directory; note: the test might not +# have test data, so we have to ensure the presence of the work +# directory. + +mkdir -p work +cd work + +date +%s > ../time-start +# TODO: +# - proper wrapping with timeout +# - test arguments to select specific test cases +if ../test > ../stdout 2> ../stderr +then + RESULT=PASS +else + RESULT=FAIL +fi +date +%s > ../time-stop +echo "${RESULT}" > result + +if [ "${RESULT}" '!=' PASS ] +then + exit 1; +fi diff --git a/EXPRESSIONS b/EXPRESSIONS new file mode 100644 index 0000000..9b35b0a --- /dev/null +++ b/EXPRESSIONS @@ -0,0 +1,89 @@ +{ "field_artifacts": + { "vars": ["fieldname", "transition"] + , "expression": + { "type": "map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": + {"type": "FIELD", "name": {"type": "var", "name": "fieldname"}} + , "body": + { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "x"} + , "transition": + { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + } + } + } + } +, "field_runfiles": + { "vars": ["fieldname", "transition"] + , "expression": + { "type": "map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": + {"type": "FIELD", "name": {"type": "var", "name": "fieldname"}} + , "body": + { "type": "DEP_RUNFILES" + , "dep": {"type": "var", "name": "x"} + , "transition": + { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + } + } + } + } +, "action_env": + { "vars": ["ENV"] + , "expression": + { "type": "map_union" + , "$1": + [ {"type": "singleton_map", "key": "PATH", "value": "/bin:/usr/bin"} + , {"type": "var", "name": "ENV", "default": {"type": "empty_map"}} + ] + } + } +, "stage_singleton_field": + { "vars": ["fieldname", "transition", "location"] + , "expression": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "src" + , "range": + {"type": "FIELD", "name": {"type": "var", "name": "fieldname"}} + , "body": + { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "artifact" + , "range": + { "type": "values" + , "$1": + { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "src"} + , "transition": + { "type": "var" + , "name": "transition" + , "default": {"type": "empty_map"} + } + } + } + , "body": + { "type": "singleton_map" + , "key": {"type": "var", "name": "location"} + , "value": {"type": "var", "name": "artifact"} + } + } + } + } + } + } +} diff --git a/data/RULES b/data/RULES new file mode 100644 index 0000000..34bc624 --- /dev/null +++ b/data/RULES @@ -0,0 +1,42 @@ +{ "staged": + { "doc": ["Stage data to a logical subdirectory."] + , "target_fields": ["srcs"] + , "string_fields": ["stage"] + , "field_doc": + { "srcs": ["The (run)files to be staged"] + , "stage": + [ "The logical directory to stage the files to." + , "Individual directory components are joined with \"/\"." + ] + } + , "expression": + { "type": "let*" + , "bindings": + [ [ "stage" + , { "type": "join" + , "separator": "/" + , "$1": {"type": "FIELD", "name": "stage"} + } + ] + , [ "srcs" + , { "type": "disjoint_map_union" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "srcs"} + , "body": + {"type": "DEP_RUNFILES", "dep": {"type": "var", "name": "x"}} + } + } + ] + , [ "staged" + , { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "$1": {"type": "var", "name": "srcs"} + } + ] + ] + , "body": {"type": "RESULT", "runfiles": {"type": "var", "name": "staged"}} + } + } +} diff --git a/proto/RULES b/proto/RULES new file mode 100644 index 0000000..b6ce000 --- /dev/null +++ b/proto/RULES @@ -0,0 +1,105 @@ +{ "library": + { "target_fields": ["srcs", "deps"] + , "string_fields": ["stage", "name", "service"] + , "expression": + { "type": "let*" + , "bindings": + [ [ "stage" + , { "type": "join" + , "separator": "/" + , "$1": {"type": "FIELD", "name": "stage"} + } + ] + , [ "name" + , { "type": "assert_non_empty" + , "msg": "Have to provide a name, unique in the stage" + , "$1": {"type": "join", "$1": {"type": "FIELD", "name": "name"}} + } + ] + , [ "srcs" + , [ { "type": "VALUE_NODE" + , "$1": + { "type": "RESULT" + , "artifacts": + { "type": "to_subdir" + , "subdir": {"type": "var", "name": "stage"} + , "$1": + { "type": "disjoint_map_union" + , "msg": "Sources have to be conflict free" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "srcs"} + , "body": + { "type": "DEP_ARTIFACTS" + , "dep": {"type": "var", "name": "x"} + } + } + } + } + } + } + ] + ] + , [ "deps" + , { "type": "++" + , "$1": + { "type": "foreach" + , "var": "x" + , "range": {"type": "FIELD", "name": "deps"} + , "body": + { "type": "DEP_PROVIDES" + , "dep": {"type": "var", "name": "x"} + , "provider": "proto" + } + } + } + ] + , [ "node" + , { "type": "ABSTRACT_NODE" + , "node_type": + { "type": "if" + , "cond": {"type": "FIELD", "name": "service"} + , "then": "service library" + , "else": "library" + } + , "target_fields": + { "type": "map_union" + , "$1": + [ { "type": "singleton_map" + , "key": "srcs" + , "value": {"type": "var", "name": "srcs"} + } + , { "type": "singleton_map" + , "key": "deps" + , "value": {"type": "var", "name": "deps"} + } + ] + } + , "string_fields": + { "type": "map_union" + , "$1": + [ { "type": "singleton_map" + , "key": "name" + , "value": [{"type": "var", "name": "name"}] + } + , { "type": "singleton_map" + , "key": "stage" + , "value": [{"type": "var", "name": "stage"}] + } + ] + } + } + ] + ] + , "body": + { "type": "RESULT" + , "provides": + { "type": "singleton_map" + , "key": "proto" + , "value": [{"type": "var", "name": "node"}] + } + } + } + } +} diff --git a/transitions/EXPRESSIONS b/transitions/EXPRESSIONS new file mode 100644 index 0000000..8ea7550 --- /dev/null +++ b/transitions/EXPRESSIONS @@ -0,0 +1,13 @@ +{ "for host": + { "vars": ["ARCH", "HOST_ARCH"] + , "expression": + { "type": "singleton_map" + , "key": "TARGET_ARCH" + , "value": + { "type": "var" + , "name": "HOST_ARCH" + , "default": {"type": "var", "name": "ARCH"} + } + } + } +} |