summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CC/EXPRESSIONS235
-rw-r--r--CC/RULES12
-rw-r--r--lint/RULES187
-rw-r--r--lint/TARGETS1
-rwxr-xr-xlint/call_lint41
-rwxr-xr-xlint/call_summary35
6 files changed, 510 insertions, 1 deletions
diff --git a/CC/EXPRESSIONS b/CC/EXPRESSIONS
index 04fd693..56d5c31 100644
--- a/CC/EXPRESSIONS
+++ b/CC/EXPRESSIONS
@@ -1076,6 +1076,214 @@
}
}
}
+, "lint information":
+ { "vars":
+ [ "srcs"
+ , "hdrs"
+ , "private-hdrs"
+ , "compile-deps"
+ , "cflags-files"
+ , "lint-deps fieldnames"
+ , "deps-transition"
+ , "compile-args"
+ ]
+ , "imports":
+ { "objects": "objects"
+ , "list_provider": ["./", "..", "field_list_provider"]
+ , "default-TOOLCHAIN": "default-TOOLCHAIN"
+ , "default-NON_SYSTEM_TOOLS": "default-NON_SYSTEM_TOOLS"
+ , "compiler": "compiler"
+ , "flags": "flags"
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "NON_SYSTEM_TOOLS"
+ , {"type": "CALL_EXPRESSION", "name": "default-NON_SYSTEM_TOOLS"}
+ ]
+ , ["COMPILER", {"type": "CALL_EXPRESSION", "name": "compiler"}]
+ , [ "COMPILE_FLAGS"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "CALL_EXPRESSION", "name": "flags"}
+ , {"type": "var", "name": "compile-args"}
+ ]
+ }
+ ]
+ , [ "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"}
+ ]
+ }
+ }
+ ]
+ }
+ ]
+ , [ "hdr lint"
+ , { "type": "foreach"
+ , "range":
+ { "type": "++"
+ , "$1":
+ [ {"type": "keys", "$1": {"type": "var", "name": "private-hdrs"}}
+ , {"type": "keys", "$1": {"type": "var", "name": "hdrs"}}
+ ]
+ }
+ , "body":
+ { "type": "VALUE_NODE"
+ , "$1":
+ { "type": "RESULT"
+ , "artifacts": {"type": "var", "name": "all hdrs"}
+ , "provides":
+ { "type": "let*"
+ , "bindings":
+ [ [ "src"
+ , { "type": "join"
+ , "$1": ["work/", {"type": "var", "name": "_"}]
+ }
+ ]
+ , [ "cmd"
+ , { "type": "++"
+ , "$1":
+ [ [{"type": "var", "name": "COMPILER"}]
+ , {"type": "var", "name": "COMPILE_FLAGS"}
+ , [ "-I"
+ , "work"
+ , "-isystem"
+ , "include"
+ , "-E"
+ , {"type": "var", "name": "src"}
+ ]
+ ]
+ }
+ ]
+ ]
+ , "body": {"type": "env", "vars": ["cmd", "src"]}
+ }
+ }
+ }
+ }
+ ]
+ , [ "src lint"
+ , { "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"}
+ }
+ , { "type": "var"
+ , "name": "TOOLCHAIN"
+ , "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"}]
+ }
+ ]
+ , [ "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"}]
+ ]
+ }
+ ]
+ ]
+ , "body":
+ { "type": "VALUE_NODE"
+ , "$1":
+ { "type": "RESULT"
+ , "artifacts": {"type": "var", "name": "inputs"}
+ , "provides":
+ { "type": "let*"
+ , "bindings":
+ [["src", {"type": "var", "name": "work src_name"}]]
+ , "body": {"type": "env", "vars": ["cmd", "src"]}
+ }
+ }
+ }
+ }
+ }
+ ]
+ , [ "dep lint nodes"
+ , { "type": "++"
+ , "$1":
+ { "type": "foreach"
+ , "var": "fieldname"
+ , "range": {"type": "var", "name": "lint-deps fieldnames"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ ["provider", "lint"]
+ , ["transition", {"type": "var", "name": "deps-transition"}]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "list_provider"}
+ }
+ }
+ }
+ ]
+ , [ "lint nodes"
+ , { "type": "++"
+ , "$1":
+ [ {"type": "var", "name": "hdr lint"}
+ , {"type": "var", "name": "src lint"}
+ , {"type": "var", "name": "dep lint nodes"}
+ ]
+ }
+ ]
+ , [ "lint nodes"
+ , {"type": "nub_right", "$1": {"type": "var", "name": "lint nodes"}}
+ ]
+ ]
+ , "body": {"type": "var", "name": "lint nodes"}
+ }
+ }
, "compiler-cc":
{ "vars": ["CC", "TOOLCHAIN_DIR", "NON_SYSTEM_TOOLS", "defaults-transition"]
, "imports": {"default-CC": "default-CC"}
@@ -1436,6 +1644,7 @@
, "ENV"
, "BUILD_POSITION_INDEPENDENT"
, "DEBUG"
+ , "LINT"
, "name"
, "pure C"
, "srcs"
@@ -1466,6 +1675,7 @@
, "ldflags-files-deps": "ldflags-files-deps"
, "lib artifact": "lib artifact"
, "debug-deps": "debug-deps"
+ , "lint": "lint information"
}
, "expression":
{ "type": "let*"
@@ -1489,6 +1699,13 @@
]
, ["link-deps", {"type": "CALL_EXPRESSION", "name": "link-deps"}]
, ["lib", {"type": "CALL_EXPRESSION", "name": "lib artifact"}]
+ , ["lint-deps fieldnames", ["deps", "private-deps"]]
+ , [ "lint"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "LINT"}
+ , "then": {"type": "CALL_EXPRESSION", "name": "lint"}
+ }
+ ]
, [ "link-args"
, { "type": "nub_right"
, "$1":
@@ -2286,6 +2503,7 @@
, "package"
, "debug-srcs"
, "debug-hdrs"
+ , "lint"
]
}
, { "type": "var"
@@ -2549,6 +2767,7 @@
, "ENV"
, "BUILD_POSITION_INDEPENDENT"
, "DEBUG"
+ , "LINT"
, "name"
, "pure C"
, "srcs"
@@ -2570,6 +2789,7 @@
, "ldflags-files-deps": "ldflags-files-deps"
, "binary": "bin artifact"
, "debug-deps": "debug-deps"
+ , "lint": "lint information"
}
, "expression":
{ "type": "let*"
@@ -2640,13 +2860,26 @@
, "else": {"type": "empty_map"}
}
]
+ , [ "lint"
+ , { "type": "if"
+ , "cond": {"type": "var", "name": "LINT"}
+ , "then":
+ { "type": "let*"
+ , "bindings":
+ [ ["hdrs", {"type": "empty_map"}]
+ , ["lint-deps fieldnames", ["private-deps"]]
+ ]
+ , "body": {"type": "CALL_EXPRESSION", "name": "lint"}
+ }
+ }
+ ]
]
, "body":
{ "type": "RESULT"
, "artifacts": {"type": "CALL_EXPRESSION", "name": "binary"}
, "provides":
{ "type": "env"
- , "vars": ["run-libs", "package", "debug-srcs", "debug-hdrs"]
+ , "vars": ["run-libs", "package", "debug-srcs", "debug-hdrs", "lint"]
}
}
}
diff --git a/CC/RULES b/CC/RULES
index f6f7272..7e527f7 100644
--- a/CC/RULES
+++ b/CC/RULES
@@ -431,6 +431,7 @@
, "BUILD_OBJECT_ONLY"
, "BUILD_OBJECT_ONLY_DROP_OBJECT_LINKING"
, "DEBUG"
+ , "LINT"
]
, "implicit": {"defaults": ["defaults"]}
, "field_doc":
@@ -572,6 +573,11 @@
, "to still forward the \"link-args\" of that library, and thus getting"
, "correct linking instructions for the resulting library."
]
+ , "LINT":
+ [ "Also provide nodes describing compile actions and header files;"
+ , "those can be used by lint rules (doing also the config transition)"
+ , "for additional checks."
+ ]
}
, "artifacts_doc":
["The actual library (libname.a) staged in the specified directory"]
@@ -799,6 +805,7 @@
, "ENV"
, "BUILD_POSITION_INDEPENDENT"
, "DEBUG"
+ , "LINT"
]
, "implicit": {"defaults": ["defaults"]}
, "field_doc":
@@ -866,6 +873,11 @@
, "ENV": ["The environment for any action generated."]
, "BUILD_POSITION_INDEPENDENT": ["Build with -fPIC."]
, "DEBUG": ["Compute the debug-stage, needed for local debugging."]
+ , "LINT":
+ [ "Also provide nodes describing compile actions and header files;"
+ , "those can be used by lint rules (doing also the config transition)"
+ , "for additional checks."
+ ]
}
, "artifacts_doc": ["The final binary, staged to the given directory"]
, "runfiles_doc": ["None"]
diff --git a/lint/RULES b/lint/RULES
new file mode 100644
index 0000000..d7b2703
--- /dev/null
+++ b/lint/RULES
@@ -0,0 +1,187 @@
+{ "targets":
+ { "doc":
+ [ "Run a given linter on the lint information provided by the given targets."
+ ]
+ , "target_fields": ["linter", "config", "summarizer", "targets"]
+ , "tainted": ["lint"]
+ , "field_doc":
+ { "linter":
+ [ "Single artifact running the lint checks."
+ , ""
+ , "This artifact with"
+ , "- argv[1] the file to lint, and"
+ , "- argv[2:] the original command line."
+ , "This invocation happens in an environment with"
+ , "- CONFIG pointing to the directory with all the artifacts given"
+ , " by the field \"config\"."
+ , "- OUT pointing to a directory to which files with the lint result"
+ , " can be written."
+ , "The linter is supposed to indicate by the exit code whether the"
+ , "indicated file complies with the given linting policy, with 0 meaning"
+ , "compliant."
+ , "Stdout and stderr, as well as the directory ${OUT} can be used to"
+ , "provide additional information."
+ ]
+ , "config": ["Any configuration or other files needed by the linter."]
+ , "summarizer":
+ [ "Single artifact generating a summary of the individual lint results."
+ , "It will be called in a directory where all subdirectories with names"
+ , "consisting entirely of digits are the results of the individual lint"
+ , "actions. Those are given as"
+ , " - a file result with content PASS if and only if the lint action"
+ , " exited 0,"
+ , " - files stdout and stderr with stdout and stderr of the lint"
+ , " action, and"
+ , " - a directory out with the additional information provided by the"
+ , " lint action."
+ , "The summarizer is required to indicate the overall result by the exit"
+ , "code, produce a human-readable summary on stdout, and optionally"
+ , "additional information in the directory ${OUT}."
+ ]
+ , "call_lint": ["Launcher for the linter"]
+ , "call_summary": ["Launcher for the summarizer"]
+ }
+ , "implicit": {"call_lint": ["call_lint"], "call_summary": ["call_summary"]}
+ , "config_transitions":
+ {"targets": [{"type": "singleton_map", "key": "LINT", "value": true}]}
+ , "anonymous":
+ {"lint": {"target": "targets", "provider": "lint", "rule_map": {}}}
+ , "imports":
+ { "stage": ["", "stage_singleton_field"]
+ , "artifacts": ["", "field_artifacts"]
+ }
+ , "expression":
+ { "type": "let*"
+ , "bindings":
+ [ [ "linter"
+ , { "type": "let*"
+ , "bindings": [["fieldname", "linter"], ["location", "linter"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "stage"}
+ }
+ ]
+ , [ "runner"
+ , { "type": "let*"
+ , "bindings": [["fieldname", "call_lint"], ["location", "runner"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "stage"}
+ }
+ ]
+ , [ "config"
+ , { "type": "let*"
+ , "bindings": [["fieldname", "config"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "artifacts"}
+ }
+ ]
+ , [ "lint results"
+ , { "type": "foreach"
+ , "range": {"type": "FIELD", "name": "lint"}
+ , "body":
+ { "type": "let*"
+ , "bindings":
+ [ [ "src"
+ , { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "_"}
+ , "provider": "src"
+ }
+ ]
+ , [ "cmd"
+ , { "type": "DEP_PROVIDES"
+ , "dep": {"type": "var", "name": "_"}
+ , "provider": "cmd"
+ }
+ ]
+ , [ "src input"
+ , { "type": "DEP_ARTIFACTS"
+ , "dep": {"type": "var", "name": "_"}
+ }
+ ]
+ ]
+ , "body":
+ { "type": "TREE"
+ , "$1":
+ { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "runner"}
+ , {"type": "var", "name": "linter"}
+ , { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1": {"type": "var", "name": "src input"}
+ }
+ , { "type": "to_subdir"
+ , "subdir": "config"
+ , "$1": {"type": "var", "name": "config"}
+ }
+ ]
+ }
+ , "cmd":
+ { "type": "++"
+ , "$1":
+ [ ["./runner", {"type": "var", "name": "src"}]
+ , {"type": "var", "name": "cmd"}
+ ]
+ }
+ , "outs": ["stdout", "stderr", "result"]
+ , "out_dirs": ["out"]
+ , "may_fail": ["lint"]
+ , "fail_message":
+ { "type": "join"
+ , "$1": ["lint failed for ", {"type": "var", "name": "src"}]
+ }
+ }
+ }
+ }
+ }
+ ]
+ , [ "summary input"
+ , {"type": "enumerate", "$1": {"type": "var", "name": "lint results"}}
+ ]
+ , [ "summarizer"
+ , { "type": "let*"
+ , "bindings":
+ [["fieldname", "summarizer"], ["location", "summarizer"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "stage"}
+ }
+ ]
+ , [ "runner"
+ , { "type": "let*"
+ , "bindings": [["fieldname", "call_summary"], ["location", "runner"]]
+ , "body": {"type": "CALL_EXPRESSION", "name": "stage"}
+ }
+ ]
+ , [ "summary"
+ , { "type": "ACTION"
+ , "inputs":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "runner"}
+ , {"type": "var", "name": "summarizer"}
+ , { "type": "to_subdir"
+ , "subdir": "work"
+ , "$1": {"type": "var", "name": "summary input"}
+ }
+ ]
+ }
+ , "cmd": ["./runner"]
+ , "outs": ["report", "result"]
+ , "out_dirs": ["out"]
+ }
+ ]
+ ]
+ , "body":
+ { "type": "RESULT"
+ , "artifacts":
+ { "type": "map_union"
+ , "$1":
+ [ {"type": "var", "name": "summary"}
+ , { "type": "singleton_map"
+ , "key": "work"
+ , "value":
+ {"type": "TREE", "$1": {"type": "var", "name": "summary input"}}
+ }
+ ]
+ }
+ }
+ }
+ }
+}
diff --git a/lint/TARGETS b/lint/TARGETS
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/lint/TARGETS
@@ -0,0 +1 @@
+{}
diff --git a/lint/call_lint b/lint/call_lint
new file mode 100755
index 0000000..ab9c2b8
--- /dev/null
+++ b/lint/call_lint
@@ -0,0 +1,41 @@
+#!/bin/sh
+# Copyright 2024 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.
+
+
+# ensure all required outputs are present
+touch stdout
+touch stderr
+RESULT=UNKNOWN
+echo "${RESULT}" > result
+
+export OUT="$(pwd)/out"
+mkdir -p config
+export CONFIG="$(pwd)/config"
+
+cd work
+
+if ../linter "$@" > ../stdout 2> ../stderr
+then
+ RESULT=PASS
+else
+ RESULT=FAIL
+fi
+
+echo "${RESULT}" > ../result
+
+if [ "${RESULT}" '!=' PASS ]
+then
+ exit 1;
+fi
diff --git a/lint/call_summary b/lint/call_summary
new file mode 100755
index 0000000..d4aa8cb
--- /dev/null
+++ b/lint/call_summary
@@ -0,0 +1,35 @@
+#!/bin/sh
+# Copyright 2024 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.
+
+
+# ensure all required outputs are present
+touch report
+RESULT=UNKNOWN
+echo "${RESULT}" > result
+
+export OUT="$(pwd)/out"
+
+cd work
+
+if ../summarizer > ../report
+then
+ RESULT=PASS
+else
+ RESULT=FAIL
+fi
+
+echo "${RESULT}" > ../result
+
+exit 0