diff options
author | Norbert Nemec <Norbert@Nemec-online.de> | 2019-07-11 01:05:48 +0200 |
---|---|---|
committer | Jussi Pakkanen <jpakkane@gmail.com> | 2019-07-11 02:05:48 +0300 |
commit | 555847f20f42bc82f76b193f155e607faf58c574 (patch) | |
tree | 4b04ca1d29edd6450eaf66869a324a05fee9cd85 /mesonbuild | |
parent | 19cda6b7c96cc3a63796549764261306e1db94b4 (diff) | |
download | meson-555847f20f42bc82f76b193f155e607faf58c574.zip meson-555847f20f42bc82f76b193f155e607faf58c574.tar.gz meson-555847f20f42bc82f76b193f155e607faf58c574.tar.bz2 |
Fix MSVC /link argument ordering (#5598)
* correct handling of LDFLAGS in find_library and sanity_check on MSVC (fixes #3629)
The MSVC compiler requires all linker flags to be placed after the compiler flags, separated by a "/link" argument. This was already handled for regular linking commands, but not yet for the aforementioned special code paths.
* on MSVC, add /link separator between compiler and linker flags when it is missing
* avoid unnecessary /link argument
Diffstat (limited to 'mesonbuild')
-rw-r--r-- | mesonbuild/compilers/clike.py | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/mesonbuild/compilers/clike.py b/mesonbuild/compilers/clike.py index 046ffba..16783fa 100644 --- a/mesonbuild/compilers/clike.py +++ b/mesonbuild/compilers/clike.py @@ -255,7 +255,8 @@ class CLikeCompiler: # a ton of compiler flags to differentiate between # arm and x86_64. So just compile. mode = 'compile' - extra_flags = self._get_basic_compiler_args(environment, mode) + cargs, largs = self._get_basic_compiler_args(environment, mode) + extra_flags = cargs + self.linker_to_compiler_args(largs) # Is a valid executable output for all toolchains and platforms binname += '.exe' @@ -264,7 +265,9 @@ class CLikeCompiler: with open(source_name, 'w') as ofile: ofile.write(code) # Compile sanity check - cmdlist = self.exelist + extra_flags + [source_name] + self.get_output_args(binary_name) + # NOTE: extra_flags must be added at the end. On MSVC, it might contain a '/link' argument + # after which all further arguments will be passed directly to the linker + cmdlist = self.exelist + [source_name] + self.get_output_args(binary_name) + extra_flags pc, stdo, stde = mesonlib.Popen_safe(cmdlist, cwd=work_dir) mlog.debug('Sanity check compiler command line:', ' '.join(cmdlist)) mlog.debug('Sanity check compile stdout:') @@ -329,10 +332,10 @@ class CLikeCompiler: dependencies=dependencies) def _get_basic_compiler_args(self, env, mode): - args = [] + cargs, largs = [], [] # Select a CRT if needed since we're linking if mode == 'link': - args += self.get_linker_debug_crt_args() + cargs += self.get_linker_debug_crt_args() # Add CFLAGS/CXXFLAGS/OBJCFLAGS/OBJCXXFLAGS and CPPFLAGS from the env sys_args = env.coredata.get_external_args(self.for_machine, self.language) @@ -341,17 +344,17 @@ class CLikeCompiler: # also used during linking. These flags can break # argument checks. Thanks, Autotools. cleaned_sys_args = self.remove_linkerlike_args(sys_args) - args += cleaned_sys_args + cargs += cleaned_sys_args if mode == 'link': # Add LDFLAGS from the env sys_ld_args = env.coredata.get_external_link_args(self.for_machine, self.language) # CFLAGS and CXXFLAGS go to both linking and compiling, but we want them # to only appear on the command line once. Remove dupes. - args += [x for x in sys_ld_args if x not in sys_args] + largs += [x for x in sys_ld_args if x not in sys_args] - args += self.get_compiler_args_for_mode(mode) - return args + cargs += self.get_compiler_args_for_mode(mode) + return cargs, largs def _get_compiler_check_args(self, env, extra_args, dependencies, mode='compile'): if extra_args is None: @@ -365,19 +368,27 @@ class CLikeCompiler: elif not isinstance(dependencies, list): dependencies = [dependencies] # Collect compiler arguments - args = compilers.CompilerArgs(self) + cargs = compilers.CompilerArgs(self) + largs = [] for d in dependencies: # Add compile flags needed by dependencies - args += d.get_compile_args() + cargs += d.get_compile_args() if mode == 'link': # Add link flags needed to find dependencies - args += d.get_link_args() + largs += d.get_link_args() + + ca, la = self._get_basic_compiler_args(env, mode) + cargs += ca + largs += la - args += self._get_basic_compiler_args(env, mode) + cargs += self.get_compiler_check_args() - args += self.get_compiler_check_args() - # extra_args must override all other arguments, so we add them last - args += extra_args + # on MSVC compiler and linker flags must be separated by the "/link" argument + # at this point, the '/link' argument may already be part of extra_args, otherwise, it is added here + if self.linker_to_compiler_args([]) == ['/link'] and largs != [] and not ('/link' in extra_args): + extra_args += ['/link'] + + args = cargs + extra_args + largs return args def compiles(self, code, env, *, extra_args=None, dependencies=None, mode='compile', disable_cache=False): @@ -964,10 +975,12 @@ class CLikeCompiler: # search for .a. This is only allowed if libtype is LibType.PREFER_SHARED if ((not extra_dirs and libtype is LibType.PREFER_SHARED) or libname in self.internal_libs): - args = ['-l' + libname] - largs = self.linker_to_compiler_args(self.get_allow_undefined_link_args()) - if self.links(code, env, extra_args=(args + largs), disable_cache=True)[0]: - return args + cargs = ['-l' + libname] + largs = self.get_allow_undefined_link_args() + extra_args = cargs + self.linker_to_compiler_args(largs) + + if self.links(code, env, extra_args=extra_args, disable_cache=True)[0]: + return cargs # Don't do a manual search for internal libs if libname in self.internal_libs: return None |