summaryrefslogtreecommitdiff
path: root/CC/auto/config_runner.py
diff options
context:
space:
mode:
authorAlberto Sartori <alberto.sartori@huawei.com>2023-02-21 17:01:02 +0100
committerAlberto Sartori <alberto.sartori@huawei.com>2023-03-15 14:36:44 +0100
commit4cb044433c177868d7e35957f76ce29fa9aaeb47 (patch)
tree43622dc86a2f7bff8972a44b033c87c80993c809 /CC/auto/config_runner.py
parent3b08fc29eff1fa61c3fd317ca5321d47cddd9c69 (diff)
downloadrules-cc-4cb044433c177868d7e35957f76ce29fa9aaeb47.tar.gz
rules: CC/auto: add "config_file" rule to generate a c/c++ header...
...starting from a template (aka configuration file), and using the variables defined via a ["CC/auto", "config"] target. For example, to use a CMake configuration file, the targets could be defined as follows ... , "foo-header-blueprint": { "type": ["@", "rules", "CC/auto", "config_file"] , "input": ["config.hpp.in"] , "output": ["config.hpp"] , "stage": ["foo"] , "magic_string": ["cmakedefine"] , "@only": ["true"] } , "foo-header": { "type": "configure" , "target": "foo-header-blueprint" , "config": { "type": "let*" , "bindings": [ [ "defines" , [ ["var", "\"string value\""] , ["FOO_MAJOR_VERSION", "3"] , ["use_this_feature", true] ] ] ] , "body": {"type": "env", "vars": ["defines"]} } } ... The file config.hpp.in may look as follows #ifndef config_cmake #define config_cmake #cmakedefine var #cmakedefine use_this_feature #cmakedefine01 use_this_feature #cmakedefine unused #define FOO_VERSION @FOO_MAJOR_VERSION@ #define DONT_TOUCH_THIS ${FOO_MAJOR_VERSION} #endif and the generated configuration file foo/config.hpp is #ifndef config_cmake #define config_cmake #define var "string value" #define use_this_feature #define use_this_feature 1 /* #undef unused */ #define FOO_VERSION 3 #define DONT_TOUCH_THIS ${FOO_MAJOR_VERSION} #endif
Diffstat (limited to 'CC/auto/config_runner.py')
-rwxr-xr-xCC/auto/config_runner.py76
1 files changed, 76 insertions, 0 deletions
diff --git a/CC/auto/config_runner.py b/CC/auto/config_runner.py
new file mode 100755
index 0000000..f938c27
--- /dev/null
+++ b/CC/auto/config_runner.py
@@ -0,0 +1,76 @@
+#!/usr/bin/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 re
+from sys import argv
+from re import sub, match
+
+input_file = argv[1]
+param_file = argv[2]
+magic_string = argv[3]
+at_only = argv[4] == "true"
+
+
+with open(param_file) as f:
+ param = json.loads(f.read())
+
+# In many cases, CMake simply defines some variables (without any associated
+# value). We handle this situation by assigning to the boolean True the empty
+# string. Note that no False value should be found, because the right way to set
+# a variable to False in the TARGETS file is to *do not mention* that variable
+# at all.
+for k, v in param.items():
+ if isinstance(v, bool):
+ param[k] = ""
+
+with open(input_file) as i:
+ with open("out", "w") as o:
+ for line in i.readlines():
+ if x := re.search(
+ r"#(.*)(" + magic_string + r" )([ \t]*)([a-zA-Z0-9_]+)", line
+ ):
+ # get the VAR
+ key = x.groups()[-1]
+ if key in param:
+ line = sub(
+ f"{x.group()[1:]}",
+ f"{x.groups()[0]}define {x.groups()[2]}{key} {param[key]}",
+ line,
+ )
+ else:
+ line = f"/* #undef {x.groups()[-1]} */\n"
+ if x := re.search(
+ r"#(.*)(" + magic_string + "01 )([ \t]*)([a-zA-Z0-9_]+)", line
+ ):
+ # get the VAR
+ key = x.groups()[-1]
+ line = sub(
+ f"{x.group()[1:]}",
+ f"{x.groups()[0]}define {x.groups()[2]}{key} "
+ + str(1 if key in param else 0),
+ line,
+ )
+ if match("#[ \t]*define", line):
+ if x := re.search(r"@([a-zA-Z0-9-_]+)@", line):
+ key = x.groups()[0]
+ line = sub(x.group(), param.get(key, ""), line)
+ if not at_only:
+ if x := re.search(r"\${([a-zA-Z0-9-_]+)}", line):
+ key = x.groups()[0]
+ line = sub(r"\${" + key + r"}", param.get(key, ""), line)
+
+ print(line, end="", file=o)