From c7c67c3f067cd022054baa25fe226110d3cb308c Mon Sep 17 00:00:00 2001 From: Rene Meusel Date: Tue, 24 Oct 2023 13:35:05 +0200 Subject: [PATCH 1/3] Allow %{foo|concat:some_constant_value} in the template engine This concatenates the static value behind the colon with the value of the template variable. If this value is not set (aka ''), also the static concatenated value is omitted. Co-Authored-By: Philippe Lieser --- configure.py | 31 +++++++++++++++++++++---------- doc/dev_ref/configure.rst | 6 ++++++ 2 files changed, 27 insertions(+), 10 deletions(-) diff --git a/configure.py b/configure.py index cc7c2a78a77..ba2f0c01484 100755 --- a/configure.py +++ b/configure.py @@ -1728,23 +1728,34 @@ class SimpleTemplate: def __init__(self, vals): self.vals = vals - self.value_pattern = re.compile(r'%{([a-z][a-z_0-9\|]+)}') + self.value_pattern = re.compile(r'%{([a-z][a-z_0-9\|]+)(?::([^}]+))?}') self.cond_pattern = re.compile('%{(if|unless) ([a-z][a-z_0-9]+)}') self.for_pattern = re.compile('(.*)%{for ([a-z][a-z_0-9]+)}') self.omitlast_pattern = re.compile('(.*)%{omitlast ([^}]*)}(.*)', re.DOTALL) self.join_pattern = re.compile('%{join ([a-z][a-z_0-9]+)}') def substitute(self, template): + def get_replacement(k): + if k not in self.vals: + raise KeyError(k) + return str(self.vals.get(k)) + def insert_value(match): - v = match.group(1) - if v in self.vals: - return str(self.vals.get(v)) - if v.endswith('|upper'): - v = v.replace('|upper', '') - if v in self.vals: - return str(self.vals.get(v)).upper() - - raise KeyError(v) + k = match.group(1) + if k.endswith('|upper'): + k = k.replace('|upper', '') + v = get_replacement(k).upper() + elif k.endswith('|concat'): + k = k.replace('|concat', '') + if not match.group(2): + raise InternalError("|concat must be of the form '%{val|concat:}'") + v = get_replacement(k) + if v: + v = f"{v}{match.group(2)}" + else: + v = get_replacement(k) + + return v def insert_join(match): var = match.group(1) diff --git a/doc/dev_ref/configure.rst b/doc/dev_ref/configure.rst index 9821855a514..152352e339b 100644 --- a/doc/dev_ref/configure.rst +++ b/doc/dev_ref/configure.rst @@ -77,6 +77,12 @@ to the output unmodified. The template elements are: If a variable reference ends with ``|upper``, the value is uppercased before being inserted into the template output. + Using ``|concat:`` as a suffix, it is possible to conditionally + concatenate the variable value with a static string defined in the template. + This is useful for compiler switches that require a template-defined + parameter value. If the substitution value is not set (i.e. "empty"), also + the static concatenation value is omitted. + * Iteration, ``%{for variable} block %{endfor}``. This iterates over a list and repeats the block as many times as it is included. Variables within the block are expanded. The two template elements ``%{for ...}`` and ``%{endfor}`` must From 1ef9d5ea805a7498c4319352d4c571d2135b5e24 Mon Sep 17 00:00:00 2001 From: Rene Meusel Date: Tue, 24 Oct 2023 13:39:39 +0200 Subject: [PATCH 2/3] Integrate Ninja header dependency tracking for MSVC, GCC and Clang Co-Authored-By: Philippe Lieser --- configure.py | 9 +++++++++ doc/dev_ref/configure.rst | 5 +++++ src/build-data/cc/clang.txt | 6 ++++++ src/build-data/cc/gcc.txt | 6 ++++++ src/build-data/cc/msvc.txt | 5 +++++ src/build-data/ninja.in | 24 +++++++++++++++++++++--- 6 files changed, 52 insertions(+), 3 deletions(-) diff --git a/configure.py b/configure.py index ba2f0c01484..4bda0c91b7d 100755 --- a/configure.py +++ b/configure.py @@ -1249,6 +1249,9 @@ def __init__(self, infofile): 'ar_output_to': '', 'werror_flags': '', 'supports_gcc_inline_asm': 'no', + 'ninja_header_deps_style': '', + 'header_deps_flag': '', + 'header_deps_out': '', }) self.add_framework_option = lex.add_framework_option @@ -1293,6 +1296,9 @@ def __init__(self, infofile): self.warning_flags = lex.warning_flags self.werror_flags = lex.werror_flags self.minimum_supported_version = lex.minimum_supported_version + self.ninja_header_deps_style = lex.ninja_header_deps_style + self.header_deps_flag = lex.header_deps_flag + self.header_deps_out = lex.header_deps_out def cross_check(self, os_info, arch_info, all_isas): @@ -2232,6 +2238,9 @@ def test_exe_extra_ldflags(): 'cc_warning_flags': cc.cc_warning_flags(options), 'output_to_exe': cc.output_to_exe, 'cc_macro': cc.macro_name, + 'ninja_header_deps_style': cc.ninja_header_deps_style, + 'header_deps_flag': cc.header_deps_flag, + 'header_deps_out': cc.header_deps_out, 'visibility_attribute': cc.gen_visibility_attribute(options), diff --git a/doc/dev_ref/configure.rst b/doc/dev_ref/configure.rst index 152352e339b..f14c749dbaa 100644 --- a/doc/dev_ref/configure.rst +++ b/doc/dev_ref/configure.rst @@ -388,6 +388,11 @@ Variables: when generation shared libraries. * ``visibility_attribute`` gives the attribute to use in the ``BOTAN_DLL`` macro to specify visibility when generation shared libraries. + * ``ninja_header_deps_style`` style of include dependency tracking for Ninja, + see also https://ninja-build.org/manual.html#ref_headers. + * ``header_deps_flag`` flag to write out dependency information in the style + required by ``ninja_header_deps_style``. + * ``header_deps_out`` flag to specify name of the dependency output file. * ``ar_command`` gives the command to build static libraries * ``ar_options`` gives the options to pass to ``ar_command``, if not set here takes this from the OS specific information. diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt index 7b4bc3b0bb0..def0a769906 100644 --- a/src/build-data/cc/clang.txt +++ b/src/build-data/cc/clang.txt @@ -37,6 +37,12 @@ stack_protector_flags "-fstack-protector" visibility_build_flags "-fvisibility=hidden" visibility_attribute '__attribute__((visibility("default")))' +# Include dependency tracking for Ninja +# See: https://ninja-build.org/manual.html#ref_headers +ninja_header_deps_style 'gcc' +header_deps_flag '-MD' +header_deps_out '-MF' + macos -> "{cxx} -dynamiclib -fPIC -install_name {libdir}/{soname_abi} -current_version {macos_so_current_ver} -compatibility_version {macos_so_compat_ver}" diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index cebf3a18a8e..18371940b0f 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -39,6 +39,12 @@ undefined -> "-fsanitize=undefined -fno-sanitize-recover=undefined" visibility_build_flags "-fvisibility=hidden" visibility_attribute '__attribute__((visibility("default")))' +# Include dependency tracking for Ninja +# See: https://ninja-build.org/manual.html#ref_headers +ninja_header_deps_style 'gcc' +header_deps_flag '-MD' +header_deps_out '-MF' + # The default works for GNU ld and several other Unix linkers default -> "{cxx} -shared -fPIC -Wl,-soname,{soname_abi}" diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt index 64b6eae46f4..116985f6f0e 100644 --- a/src/build-data/cc/msvc.txt +++ b/src/build-data/cc/msvc.txt @@ -39,6 +39,11 @@ werror_flags "/WX" visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)" visibility_attribute "__declspec(dllimport)" +# Include dependency tracking for Ninja +# See: https://ninja-build.org/manual.html#ref_headers +ninja_header_deps_style 'msvc' +header_deps_flag '/showIncludes' + ar_command lib ar_options "/nologo" ar_output_to "/OUT:" diff --git a/src/build-data/ninja.in b/src/build-data/ninja.in index 6214287e050..93da589cc74 100644 --- a/src/build-data/ninja.in +++ b/src/build-data/ninja.in @@ -22,13 +22,31 @@ SCRIPTS_DIR = %{scripts_dir} INSTALLED_LIB_DIR = %{libdir} rule compile_lib - command = %{cxx} %{lib_flags} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} -DBOTAN_IS_BEING_BUILT ${WARN_FLAGS} ${isa_flags} %{include_paths} %{dash_c} $in %{dash_o}$out +%{if header_deps_out} + depfile = $out.d +%{endif} +%{if ninja_header_deps_style} + deps = %{ninja_header_deps_style} +%{endif} + command = %{cxx} %{lib_flags} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} -DBOTAN_IS_BEING_BUILT ${WARN_FLAGS} ${isa_flags} %{include_paths} %{header_deps_flag} %{header_deps_out|concat: $out.d} %{dash_c} $in %{dash_o}$out rule compile_exe - command = %{cxx} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} -DBOTAN_IS_BEING_BUILT ${WARN_FLAGS} ${isa_flags} %{include_paths} %{dash_c} $in %{dash_o}$out +%{if header_deps_out} + depfile = $out.d +%{endif} +%{if ninja_header_deps_style} + deps = %{ninja_header_deps_style} +%{endif} + command = %{cxx} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} -DBOTAN_IS_BEING_BUILT ${WARN_FLAGS} ${isa_flags} %{include_paths} %{header_deps_flag} %{header_deps_out|concat: $out.d} %{dash_c} $in %{dash_o}$out rule compile_example_exe - command = %{cxx} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} ${WARN_FLAGS} ${isa_flags} %{include_paths} %{dash_c} $in %{dash_o}$out +%{if header_deps_out} + depfile = $out.d +%{endif} +%{if ninja_header_deps_style} + deps = %{ninja_header_deps_style} +%{endif} + command = %{cxx} ${ABI_FLAGS} ${LANG_FLAGS} ${CXXFLAGS} ${WARN_FLAGS} ${isa_flags} %{include_paths} %{header_deps_flag} %{header_deps_out|concat: $out.d} %{dash_c} $in %{dash_o}$out # The primary target build all: phony %{all_targets} From f29366a0edf9f41b3b94a650a2e4fe0459044983 Mon Sep 17 00:00:00 2001 From: Rene Meusel Date: Tue, 24 Oct 2023 13:53:35 +0200 Subject: [PATCH 3/3] Enable Ninja w/ header dependency tracking in VSCode Co-Authored-By: Philippe Lieser --- src/editors/vscode/tasks.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/editors/vscode/tasks.json b/src/editors/vscode/tasks.json index b13653e8d6b..2df051477d5 100644 --- a/src/editors/vscode/tasks.json +++ b/src/editors/vscode/tasks.json @@ -6,7 +6,7 @@ "detail": "Default ./configure.py invocation for gcc. Run your own if you want.", "group": "build", "type": "shell", - "command": "python3 ./configure.py --cc gcc --compiler-cache=ccache --without-documentation --debug-mode --build-targets=\"static,tests,bogo_shim\"", + "command": "python3 ./configure.py --cc gcc --compiler-cache=ccache --build-tool=ninja --without-documentation --debug-mode --build-targets=\"static,tests,bogo_shim\"", "presentation": { "reveal": "always", "panel": "shared", @@ -22,7 +22,7 @@ "args": [ ] }, - "command": "python ./configure.py --cc msvc --compiler-cache=sccache.exe --without-documentation --debug-mode --build-targets=\"static,tests\"", + "command": "python ./configure.py --cc msvc --compiler-cache=sccache.exe --build-tool=ninja --link-method=hardlink --without-documentation --debug-mode --build-targets=\"static,tests\"", "presentation": { "reveal": "always", "panel": "shared",