From 4f0218bcc0e311e37dd191329a6757bddb2ea97b Mon Sep 17 00:00:00 2001 From: Jack Lloyd Date: Sun, 1 Dec 2024 13:51:19 -0500 Subject: [PATCH] Don't implicitly/always pass CXXFLAGS into LDFLAGS This was done to handle LTO (#4196 #4200) but causes problems especially for MSVC which in some (unclear) circumstances treats unknown flags to the linker as a hard error (#4451). Instead only pass CXXFLAGS into LDFLAGS when an extra option `--lto-cxxflags-to-ldflags` is provided to opt into this behavior. --- configure.py | 76 +++++++++++++++++++------------------- src/build-data/makefile.in | 2 +- src/build-data/ninja.in | 2 +- 3 files changed, 41 insertions(+), 39 deletions(-) diff --git a/configure.py b/configure.py index 8d8d85d56c9..35c78bc10f7 100755 --- a/configure.py +++ b/configure.py @@ -379,6 +379,9 @@ def add_enable_disable_pair(group, what, default, msg=optparse.SUPPRESS_HELP): target_group.add_option('--extra-cxxflags', metavar='FLAGS', default=[], action='append', help='set extra compiler flags') + target_group.add_option('--lto-cxxflags-to-ldflags', default=False, action='store_true', + help='set all compilation flags also during linking (for LTO)') + target_group.add_option('--ldflags', metavar='FLAGS', help='set linker flags', default=None) @@ -1515,48 +1518,50 @@ def cc_lang_flags(self): def cc_lang_binary_linker_flags(self): return self.lang_binary_linker_flags - def cc_compile_flags(self, options, with_debug_info=None, enable_optimizations=None): - def gen_flags(with_debug_info, enable_optimizations): + def ldflags(self, options): + if options.ldflags: + yield options.ldflags + + if options.lto_cxxflags_to_ldflags: + yield from self.cc_compile_flags(options) - sanitizers_enabled = options.with_sanitizers or (len(options.enable_sanitizers) > 0) + def cc_compile_flags(self, options): + sanitizers_enabled = options.with_sanitizers or (len(options.enable_sanitizers) > 0) - if with_debug_info is None: - with_debug_info = options.with_debug_info - if enable_optimizations is None: - enable_optimizations = not options.no_optimizations + if options.cxxflags: + # CXXFLAGS is assumed to be the entire set of desired compilation flags + # if not the case the user should have used --extra-cxxflags + yield options.cxxflags + return - if with_debug_info: - yield self.debug_info_flags + if options.with_debug_info: + yield self.debug_info_flags - if enable_optimizations: - if options.optimize_for_size: - if self.size_optimization_flags != '': - yield self.size_optimization_flags - else: - logging.warning("No size optimization flags set for current compiler") - yield self.optimization_flags - elif sanitizers_enabled and self.sanitizer_optimization_flags != '': - yield self.sanitizer_optimization_flags + if not options.no_optimizations: + if options.optimize_for_size: + if self.size_optimization_flags != '': + yield self.size_optimization_flags else: + logging.warning("No size optimization flags set for current compiler") yield self.optimization_flags + elif sanitizers_enabled and self.sanitizer_optimization_flags != '': + yield self.sanitizer_optimization_flags + else: + yield self.optimization_flags - if options.arch in self.cpu_flags: - yield self.cpu_flags[options.arch] - - if options.arch in self.cpu_flags_no_debug: - - # Only enable these if no debug/sanitizer options enabled - - if not (options.debug_mode or sanitizers_enabled): - yield self.cpu_flags_no_debug[options.arch] + if options.arch in self.cpu_flags: + yield self.cpu_flags[options.arch] - for flag in options.extra_cxxflags: - yield flag + if options.arch in self.cpu_flags_no_debug: + # Only enable these if no debug/sanitizer options enabled + if not (options.debug_mode or sanitizers_enabled): + yield self.cpu_flags_no_debug[options.arch] - for definition in options.define_build_macro: - yield self.add_compile_definition_option + definition + for flag in options.extra_cxxflags: + yield flag - return (' '.join(gen_flags(with_debug_info, enable_optimizations))).strip() + for definition in options.define_build_macro: + yield self.add_compile_definition_option + definition @staticmethod def _so_link_search(osname, debug_info): @@ -2264,9 +2269,6 @@ def test_exe_extra_ldflags(): 'sanitizer_types' : sorted(cc.sanitizer_types), - 'cc_compile_opt_flags': cc.cc_compile_flags(options, False, True), - 'cc_compile_debug_flags': cc.cc_compile_flags(options, True, False), - 'dash_o': cc.output_to_object, 'dash_c': cc.compile_flags, @@ -2274,8 +2276,8 @@ def test_exe_extra_ldflags(): 'cc_lang_binary_linker_flags': cc.cc_lang_binary_linker_flags(), 'os_feature_macros': osinfo.macros(cc), 'cc_sysroot': sysroot_option(), - 'cc_compile_flags': options.cxxflags or cc.cc_compile_flags(options), - 'ldflags': options.ldflags or '', + 'cc_compile_flags': ' '.join(cc.cc_compile_flags(options)).strip(), + 'ldflags': ' '.join(cc.ldflags(options)).strip(), 'test_exe_extra_ldflags': test_exe_extra_ldflags(), 'extra_libs': extra_libs(options.extra_libs, cc), 'cc_warning_flags': cc.cc_warning_flags(options), diff --git a/src/build-data/makefile.in b/src/build-data/makefile.in index e59085667bb..9b3ac587477 100644 --- a/src/build-data/makefile.in +++ b/src/build-data/makefile.in @@ -16,7 +16,7 @@ LANG_EXE_FLAGS = %{cc_lang_binary_linker_flags} CXXFLAGS = %{cc_compile_flags} WARN_FLAGS = %{cc_warning_flags} LIB_FLAGS = %{lib_flags} -LDFLAGS = %{ldflags} %{cc_compile_flags} +LDFLAGS = %{ldflags} EXE_LINK_CMD = %{exe_link_cmd} diff --git a/src/build-data/ninja.in b/src/build-data/ninja.in index a6279d3dea2..414663acfeb 100644 --- a/src/build-data/ninja.in +++ b/src/build-data/ninja.in @@ -10,7 +10,7 @@ LANG_EXE_FLAGS = %{cc_lang_binary_linker_flags} CXXFLAGS = %{cc_compile_flags} WARN_FLAGS = %{cc_warning_flags} -LDFLAGS = %{ldflags} %{cc_compile_flags} +LDFLAGS = %{ldflags} EXE_LINK_CMD = %{exe_link_cmd}