diff options
-rw-r--r-- | .appveyor.yml | 23 | ||||
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | README.md | 3 | ||||
-rw-r--r-- | authors.txt | 3 | ||||
-rw-r--r-- | mesonbuild/backend/backends.py | 5 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 6 | ||||
-rw-r--r-- | mesonbuild/compilers.py | 184 | ||||
-rw-r--r-- | mesonbuild/environment.py | 2 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 24 | ||||
-rw-r--r-- | mesonbuild/scripts/__init__.py | 22 | ||||
-rw-r--r-- | mesonbuild/scripts/gettext.py | 4 | ||||
-rw-r--r-- | mesonbuild/scripts/gtkdochelper.py | 7 | ||||
-rw-r--r-- | mesonbuild/scripts/meson_install.py | 14 | ||||
-rwxr-xr-x | run_tests.py | 4 | ||||
-rwxr-xr-x | test cases/common/103 manygen/subdir/manygen.py | 15 | ||||
-rw-r--r-- | test cases/common/86 same basename/meson.build | 6 | ||||
-rw-r--r-- | test cases/common/86 same basename/sub/meson.build | 1 |
17 files changed, 208 insertions, 116 deletions
diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000..d5e0fbf --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,23 @@ +version: 1.0.{build} + +os: Visual Studio 2015 + +platform: + - x86 + +branches: + only: + - master + +install: + - ps: (new-object net.webclient).DownloadFile('https://www.python.org/ftp/python/3.4.4/python-3.4.4.msi', 'python-3.4.4.msi') + - ps: msiexec /i python-3.4.4.msi /quiet /qn /norestart + - ps: (new-object net.webclient).DownloadFile('https://dl.dropboxusercontent.com/u/37517477/ninja.exe', 'c:\python34\ninja.exe') + - cmd: copy c:\python34\python.exe c:\python34\python3.exe + - '"C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x86' + +build_script: + - cmd: echo No build step. + +test_script: + - cmd: PATH c:\python34;%PATH% && python3 run_tests.py --backend=ninja @@ -2,6 +2,7 @@ /.pydevproject /.settings /.cproject +/.idea __pycache__ /install dir @@ -6,8 +6,7 @@ build system. ####Build status -<a href="https://travis-ci.org/mesonbuild/meson"><img -src="https://travis-ci.org/mesonbuild/meson.svg?branch=master"></a> +[](https://travis-ci.org/mesonbuild/meson) [](https://ci.appveyor.com/project/jpakkane/meson) ####Dependencies diff --git a/authors.txt b/authors.txt index d628368..f633cb2 100644 --- a/authors.txt +++ b/authors.txt @@ -34,3 +34,6 @@ Luke Adams Rogiel Sulzbach Tim-Philipp Müller Emmanuele Bassi +Martin Hostettler +Sam Thursfield +Noam Meltzer diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 109861c..bc49966 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -226,7 +226,10 @@ class Backend(): def determine_linker(self, target, src): if isinstance(target, build.StaticLibrary): - return self.build.static_linker + if self.build.static_cross_linker is not None: + return self.build.static_cross_linker + else: + return self.build.static_linker if len(self.build.compilers) == 1: return self.build.compilers[0] # Currently a bit naive. C++ must diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 92623a9..eb2579d 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -780,7 +780,7 @@ int dummy; if hasattr(i, 'fname'): i = i.fname if i.endswith('vala'): - vapiname = os.path.splitext(os.path.split(i)[1])[0] + '.vapi' + vapiname = dep.name + '.vapi' fullname = os.path.join(self.get_target_dir(dep), vapiname) result.append(fullname) break @@ -798,7 +798,7 @@ int dummy; vala_input_files.append(s.rel_to_builddir(self.build_to_src)) if len(src) == 0: raise InvalidArguments('Vala library has no Vala source files.') - namebase = os.path.splitext(os.path.split(src[0].fname)[1])[0] + namebase = target.name base_h = namebase + '.h' base_vapi = namebase + '.vapi' hname = os.path.normpath(os.path.join(self.get_target_dir(target), base_h)) @@ -1228,7 +1228,7 @@ rule FORTRAN_DEP_HACK else: command_template = ' command = %s %s $ARGS %s %s %s $in\n' command = command_template % \ - (' '.join(compiler.get_exelist()),\ + (' '.join([ninja_quote(i) for i in compiler.get_exelist()]),\ ' '.join(cross_args), ' '.join(quoted_depargs),\ ' '.join(compiler.get_output_args('$out')),\ diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index eeb4185..99b420f 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -282,12 +282,14 @@ class Compiler(): raise EnvironmentException('Language %s does not support function checks.' % self.language) def unix_link_flags_to_native(self, args): - return args + "Always returns a copy that can be independently mutated" + return args[:] def unix_compile_flags_to_native(self, args): - return args + "Always returns a copy that can be independently mutated" + return args[:] - def find_library(self, libname, extra_dirs): + def find_library(self, *args, **kwargs): raise EnvironmentException('Language {} does not support library finding.'.format(self.language)) def get_library_dirs(self): @@ -296,6 +298,18 @@ class Compiler(): def has_argument(self, arg): raise EnvironmentException('Language {} does not support has_arg.'.format(self.language)) + def get_cross_extra_flags(self, environment, *, compile, link): + extra_flags = [] + if self.is_cross and environment: + if 'properties' in environment.cross_info.config: + lang_args_key = self.language + '_args' + if compile: + extra_flags += environment.cross_info.config['properties'].get(lang_args_key, []) + lang_link_args_key = self.language + '_link_args' + if link: + extra_flags += environment.cross_info.config['properties'].get(lang_link_args_key, []) + return extra_flags + class CCompiler(Compiler): def __init__(self, exelist, version, is_cross, exe_wrapper=None): super().__init__(exelist, version) @@ -423,7 +437,7 @@ class CCompiler(Compiler): def get_linker_search_args(self, dirname): return ['-L'+dirname] - def sanity_check_impl(self, work_dir, sname, code): + def sanity_check_impl(self, work_dir, environment, sname, code): mlog.debug('Sanity testing ' + self.language + ' compiler:', ' '.join(self.exelist)) mlog.debug('Is cross compiler: %s.' % str(self.is_cross)) @@ -438,7 +452,10 @@ class CCompiler(Compiler): # on OSX the compiler binary is the same but you need # a ton of compiler flags to differentiate between # arm and x86_64. So just compile. - extra_flags = self.get_compile_only_args() + extra_flags += self.get_cross_extra_flags(environment, compile=True, link=False) + extra_flags += self.get_compile_only_args() + else: + extra_flags += self.get_cross_extra_flags(environment, compile=True, link=True) # Is a valid executable output for all toolchains and platforms binname += '.exe' # Write binary check source @@ -474,23 +491,23 @@ class CCompiler(Compiler): if pe.returncode != 0: raise EnvironmentException('Executables created by {0} compiler {1} are not runnable.'.format(self.language, self.name_string())) - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): code = 'int main(int argc, char **argv) { int class=0; return class; }\n' - return self.sanity_check_impl(work_dir, 'sanitycheckc.c', code) + return self.sanity_check_impl(work_dir, environment, 'sanitycheckc.c', code) - def has_header(self, hname, extra_args=[]): + def has_header(self, hname, env, extra_args=[]): templ = '''#include<%s> int someSymbolHereJustForFun; ''' - return self.compiles(templ % hname, extra_args) + return self.compiles(templ % hname, env, extra_args) - def has_header_symbol(self, hname, symbol, prefix, extra_args=[]): + def has_header_symbol(self, hname, symbol, prefix, env, extra_args=[]): templ = '''{2} #include <{0}> int main () {{ {1}; }}''' # Pass -O0 to ensure that the symbol isn't optimized away extra_args += self.get_no_optimization_args() - return self.compiles(templ.format(hname, symbol, prefix), extra_args) + return self.compiles(templ.format(hname, symbol, prefix), env, extra_args) def compile(self, code, srcname, extra_args=[]): commands = self.get_exelist() @@ -508,7 +525,7 @@ int main () {{ {1}; }}''' os.remove(srcname) return p - def compiles(self, code, extra_args = []): + def compiles(self, code, env, extra_args=[]): if isinstance(extra_args, str): extra_args = [extra_args] suflen = len(self.default_suffix) @@ -517,8 +534,13 @@ int main () {{ {1}; }}''' ofile = open(srcname, 'w') ofile.write(code) ofile.close() - extra_args = extra_args + self.get_compile_only_args() - p = self.compile(code, srcname, extra_args) + # Convert flags to the native type of the selected compiler + args = self.unix_link_flags_to_native(extra_args) + # Read c_args/cpp_args/etc from the cross-info file (if needed) + args += self.get_cross_extra_flags(env, compile=True, link=False) + # We only want to compile; not link + args += self.get_compile_only_args() + p = self.compile(code, srcname, args) try: trial = srcname[:-suflen] + 'o' os.remove(trial) @@ -530,7 +552,7 @@ int main () {{ {1}; }}''' pass return p.returncode == 0 - def links(self, code, extra_args = []): + def links(self, code, env, extra_args=[]): (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix) os.close(fd) (fd, dstname) = tempfile.mkstemp() @@ -538,21 +560,25 @@ int main () {{ {1}; }}''' ofile = open(srcname, 'w') ofile.write(code) ofile.close() + # Convert flags to the native type of the selected compiler + args = self.unix_link_flags_to_native(extra_args) # Need to add buildtype args to select the CRT to use with MSVC # This is needed especially while trying to link with static libraries # since MSVC won't auto-select a CRT for us in that case and will error # out asking us to select one. - extra_args = self.get_buildtype_args('debug') + \ - self.unix_link_flags_to_native(extra_args) + \ - self.get_output_args(dstname) - p = self.compile(code, srcname, extra_args) + args += self.get_buildtype_args('debug') + # Read c_args/c_link_args/cpp_args/cpp_link_args/etc from the cross-info file (if needed) + args += self.get_cross_extra_flags(env, compile=True, link=True) + # Arguments specifying the output filename + args += self.get_output_args(dstname) + p = self.compile(code, srcname, args) try: os.remove(dstname) except FileNotFoundError: pass return p.returncode == 0 - def run(self, code, extra_args=[]): + def run(self, code, env, extra_args=[]): mlog.debug('Running code:\n\n', code) if self.is_cross and self.exe_wrapper is None: raise CrossNoRunException('Can not run test applications in this cross environment.') @@ -561,11 +587,15 @@ int main () {{ {1}; }}''' ofile = open(srcname, 'w') ofile.write(code) ofile.close() - exename = srcname + '.exe' # Is guaranteed to be executable on every platform. - commands = self.get_exelist() + # Convert flags to the native type of the selected compiler + args = self.unix_link_flags_to_native(extra_args) # Same reasoning as self.links() above - commands += self.get_buildtype_args('debug') - commands += self.unix_link_flags_to_native(extra_args) + args += self.get_buildtype_args('debug') + # Read c_link_args/cpp_link_args/etc from the cross-info file + args += self.get_cross_extra_flags(env, compile=True, link=True) + # Create command list + exename = srcname + '.exe' # Is guaranteed to be executable on every platform. + commands = self.get_exelist() + args commands.append(srcname) commands += self.get_output_args(exename) p = subprocess.Popen(commands, cwd=os.path.split(srcname)[0], stdout=subprocess.PIPE, stderr=subprocess.PIPE) @@ -612,16 +642,12 @@ int main(int argc, char **argv) {{ %s int temparray[%d-sizeof(%s)]; ''' - try: - extra_args += env.cross_info.config['properties'][self.language + '_args'] - except KeyError: - pass extra_args += self.get_no_optimization_args() - if not self.compiles(element_exists_templ.format(prefix, element)): + if not self.compiles(element_exists_templ.format(prefix, element), env, extra_args): return -1 for i in range(1, 1024): code = templ % (prefix, i, element) - if self.compiles(code, extra_args): + if self.compiles(code, env, extra_args): if self.id == 'msvc': # MSVC refuses to construct an array of zero size, so # the test only succeeds when i is sizeof(element) + 1 @@ -640,7 +666,7 @@ int main(int argc, char **argv) { return 0; }; ''' - res = self.run(templ % (prefix, element), extra_args) + res = self.run(templ % (prefix, element), env, extra_args) if not res.compiled: return -1 if res.returncode != 0: @@ -661,16 +687,12 @@ struct tmp { int testarray[%d-offsetof(struct tmp, target)]; ''' - try: - extra_args += env.cross_info.config['properties'][self.language + '_args'] - except KeyError: - pass extra_args += self.get_no_optimization_args() - if not self.compiles(type_exists_templ.format(typename)): + if not self.compiles(type_exists_templ.format(typename), env, extra_args): return -1 for i in range(1, 1024): code = templ % (typename, i) - if self.compiles(code, extra_args): + if self.compiles(code, env, extra_args): if self.id == 'msvc': # MSVC refuses to construct an array of zero size, so # the test only succeeds when i is sizeof(element) + 1 @@ -694,7 +716,7 @@ int main(int argc, char **argv) { return 0; } ''' - res = self.run(templ % typename, extra_args) + res = self.run(templ % typename, env, extra_args) if not res.compiled: raise EnvironmentException('Could not compile alignment test.') if res.returncode != 0: @@ -759,7 +781,7 @@ int main(int argc, char **argv) { if isinstance(val, bool): return val raise EnvironmentException('Cross variable {0} is not a boolean.'.format(varname)) - if self.links(templ.format(prefix, funcname), extra_args): + if self.links(templ.format(prefix, funcname), env, extra_args): return True # Add -O0 to ensure that the symbol isn't optimized away by the compiler extra_args += self.get_no_optimization_args() @@ -768,32 +790,32 @@ int main(int argc, char **argv) { # still detect the function. We still want to fail if __stub_foo or # _stub_foo are defined, of course. header_templ = '#include <limits.h>\n{0}\n' + stubs_fail + '\nint main() {{ {1}; }}' - if self.links(header_templ.format(prefix, funcname), extra_args): + if self.links(header_templ.format(prefix, funcname), env, extra_args): return True # Some functions like alloca() are defined as compiler built-ins which # are inlined by the compiler, so test for that instead. Built-ins are # special functions that ignore all includes and defines, so we just # directly try to link via main(). - return self.links('int main() {{ {0}; }}'.format('__builtin_' + funcname), extra_args) + return self.links('int main() {{ {0}; }}'.format('__builtin_' + funcname), env, extra_args) - def has_member(self, typename, membername, prefix, extra_args=[]): + def has_member(self, typename, membername, prefix, env, extra_args=[]): templ = '''%s void bar() { %s foo; foo.%s; }; ''' - return self.compiles(templ % (prefix, typename, membername), extra_args) + return self.compiles(templ % (prefix, typename, membername), env, extra_args) - def has_type(self, typename, prefix, extra_args): + def has_type(self, typename, prefix, env, extra_args): templ = '''%s void bar() { sizeof(%s); }; ''' - return self.compiles(templ % (prefix, typename), extra_args) + return self.compiles(templ % (prefix, typename), env, extra_args) - def find_library(self, libname, extra_dirs): + def find_library(self, libname, env, extra_dirs): # First try if we can just add the library as -l. code = '''int main(int argc, char **argv) { return 0; @@ -803,7 +825,7 @@ void bar() { # Only try to find std libs if no extra dirs specified. if len(extra_dirs) == 0: args = ['-l' + libname] - if self.links(code, extra_args=args): + if self.links(code, env, extra_args=args): return args # Not found? Try to find the library file itself. extra_dirs += self.get_library_dirs() @@ -824,8 +846,8 @@ void bar() { def thread_link_flags(self): return ['-pthread'] - def has_argument(self, arg): - return self.compiles('int i;\n', extra_args=arg) + def has_argument(self, arg, env): + return self.compiles('int i;\n', env, extra_args=arg) class CPPCompiler(CCompiler): def __init__(self, exelist, version, is_cross, exe_wrap): @@ -839,9 +861,9 @@ class CPPCompiler(CCompiler): return True return False - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): code = 'class breakCCompiler;int main(int argc, char **argv) { return 0; }\n' - return self.sanity_check_impl(work_dir, 'sanitycheckcpp.cc', code) + return self.sanity_check_impl(work_dir, environment, 'sanitycheckcpp.cc', code) class ObjCCompiler(CCompiler): def __init__(self, exelist, version, is_cross, exe_wrap): @@ -855,16 +877,23 @@ class ObjCCompiler(CCompiler): return True return False - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): + # TODO try to use sanity_check_impl instead of duplicated code source_name = os.path.join(work_dir, 'sanitycheckobjc.m') binary_name = os.path.join(work_dir, 'sanitycheckobjc') + extra_flags = self.get_cross_extra_flags(environment, compile=True, link=False) + if self.is_cross: + extra_flags += self.get_compile_only_args() ofile = open(source_name, 'w') ofile.write('#import<stdio.h>\nint main(int argc, char **argv) { return 0; }\n') ofile.close() - pc = subprocess.Popen(self.exelist + [source_name, '-o', binary_name]) + pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name]) pc.wait() if pc.returncode != 0: raise EnvironmentException('ObjC compiler %s can not compile programs.' % self.name_string()) + if self.is_cross: + # Can't check if the binaries run so we have to assume they do + return pe = subprocess.Popen(binary_name) pe.wait() if pe.returncode != 0: @@ -882,16 +911,23 @@ class ObjCPPCompiler(CPPCompiler): return True return False - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): + # TODO try to use sanity_check_impl instead of duplicated code source_name = os.path.join(work_dir, 'sanitycheckobjcpp.mm') binary_name = os.path.join(work_dir, 'sanitycheckobjcpp') + extra_flags = self.get_cross_extra_flags(environment, compile=True, link=False) + if self.is_cross: + extra_flags += self.get_compile_only_args() ofile = open(source_name, 'w') ofile.write('#import<stdio.h>\nclass MyClass;int main(int argc, char **argv) { return 0; }\n') ofile.close() - pc = subprocess.Popen(self.exelist + [source_name, '-o', binary_name]) + pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name]) pc.wait() if pc.returncode != 0: raise EnvironmentException('ObjC++ compiler %s can not compile programs.' % self.name_string()) + if self.is_cross: + # Can't check if the binaries run so we have to assume they do + return pe = subprocess.Popen(binary_name) pe.wait() if pe.returncode != 0: @@ -980,7 +1016,7 @@ class MonoCompiler(Compiler): def get_pch_name(self, header_name): return '' - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): src = 'sanity.cs' obj = 'sanity.exe' source_name = os.path.join(work_dir, src) @@ -1092,7 +1128,7 @@ class JavaCompiler(Compiler): def get_buildtype_args(self, buildtype): return java_buildtype_args[buildtype] - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): src = 'SanityCheck.java' obj = 'SanityCheck' source_name = os.path.join(work_dir, src) @@ -1140,7 +1176,7 @@ class ValaCompiler(Compiler): def get_language(self): return self.language - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): src = 'valatest.vala' source_name = os.path.join(work_dir, src) ofile = open(source_name, 'w') @@ -1148,7 +1184,8 @@ class ValaCompiler(Compiler): } ''') ofile.close() - pc = subprocess.Popen(self.exelist + ['-C', '-c', src], cwd=work_dir) + extra_flags = self.get_cross_extra_flags(environment, compile=True, link=False) + pc = subprocess.Popen(self.exelist + extra_flags + ['-C', '-c', src], cwd=work_dir) pc.wait() if pc.returncode != 0: raise EnvironmentException('Vala compiler %s can not compile programs.' % self.name_string()) @@ -1183,7 +1220,7 @@ class RustCompiler(Compiler): def get_language(self): return self.language - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): source_name = os.path.join(work_dir, 'sanity.rs') output_name = os.path.join(work_dir, 'rusttest') ofile = open(source_name, 'w') @@ -1281,7 +1318,7 @@ class SwiftCompiler(Compiler): def get_compile_only_args(self): return ['-c'] - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): src = 'swifttest.swift' source_name = os.path.join(work_dir, src) output_name = os.path.join(work_dir, 'swifttest') @@ -1289,7 +1326,8 @@ class SwiftCompiler(Compiler): ofile.write('''1 + 2 ''') ofile.close() - pc = subprocess.Popen(self.exelist + ['-emit-executable', '-o', output_name, src], cwd=work_dir) + extra_flags = self.get_cross_extra_flags(environment, compile=True, link=True) + pc = subprocess.Popen(self.exelist + extra_flags + ['-emit-executable', '-o', output_name, src], cwd=work_dir) pc.wait() if pc.returncode != 0: raise EnvironmentException('Swift compiler %s can not compile programs.' % self.name_string()) @@ -1409,7 +1447,7 @@ class VisualStudioCCompiler(CCompiler): if i.startswith('-L'): i = '/LIBPATH:' + i[2:] # Translate GNU-style -lfoo library name to the import library - if i.startswith('-l'): + elif i.startswith('-l'): name = i[2:] if name in ('m', 'c'): # With MSVC, these are provided by the C runtime which is @@ -1438,7 +1476,7 @@ class VisualStudioCCompiler(CCompiler): # Visual Studio is special. It ignores arguments it does not # understand and you can't tell it to error out on those. # http://stackoverflow.com/questions/15259720/how-can-i-make-the-microsoft-c-compiler-treat-unknown-flags-as-errors-rather-t - def has_argument(self, arg): + def has_argument(self, arg, env): warning_text = b'9002' code = 'int i;\n' (fd, srcname) = tempfile.mkstemp(suffix='.'+self.default_suffix) @@ -1446,7 +1484,10 @@ class VisualStudioCCompiler(CCompiler): ofile = open(srcname, 'w') ofile.write(code) ofile.close() - commands = self.exelist + [arg] + self.get_compile_only_args() + [srcname] + # Read c_args/cpp_args/etc from the cross-info file (if needed) + extra_args = self.get_cross_extra_flags(env, compile=True, link=False) + extra_args += self.get_compile_only_args() + commands = self.exelist + [arg] + extra_args + [srcname] mlog.debug('Running VS compile:') mlog.debug('Command line: ', ' '.join(commands)) mlog.debug('Code:\n', code) @@ -1825,7 +1866,7 @@ class FortranCompiler(Compiler): def needs_static_linker(self): return True - def sanity_check(self, work_dir): + def sanity_check(self, work_dir, environment): source_name = os.path.join(work_dir, 'sanitycheckf.f90') binary_name = os.path.join(work_dir, 'sanitycheckf') ofile = open(source_name, 'w') @@ -1834,7 +1875,8 @@ class FortranCompiler(Compiler): end program prog ''') ofile.close() - pc = subprocess.Popen(self.exelist + [source_name, '-o', binary_name]) + extra_flags = self.get_cross_extra_flags(environment, compile=True, link=True) + pc = subprocess.Popen(self.exelist + extra_flags + [source_name, '-o', binary_name]) pc.wait() if pc.returncode != 0: raise EnvironmentException('Compiler %s can not compile programs.' % self.name_string()) @@ -2089,10 +2131,10 @@ class VisualStudioLinker(): return [] def unix_link_flags_to_native(self, args): - return args + return args[:] def unix_compile_flags_to_native(self, args): - return args + return args[:] class ArLinker(): @@ -2138,7 +2180,7 @@ class ArLinker(): return [] def unix_link_flags_to_native(self, args): - return args + return args[:] def unix_compile_flags_to_native(self, args): - return args + return args[:] diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index fcd4bdb..e1e4613 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -246,7 +246,7 @@ class Environment(): version = 'unknown version' if 'apple' in out and 'Free Software Foundation' in out: return GnuCCompiler(ccache + [compiler], version, GCC_OSX, is_cross, exe_wrap) - if (out.startswith('cc') or 'gcc' in out) and \ + if (out.startswith('cc') or 'gcc' in out.lower()) and \ 'Free Software Foundation' in out: lowerout = out.lower() if 'mingw' in lowerout or 'msys' in lowerout or 'mingw' in compiler.lower(): diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index e6b7406..a779e99 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -624,7 +624,7 @@ class CompilerHolder(InterpreterObject): if not isinstance(testname, str): raise InterpreterException('Testname argument must be a string.') extra_args = self.determine_args(kwargs) - result = self.compiler.run(code, extra_args) + result = self.compiler.run(code, self.environment, extra_args) if len(testname) > 0: if not result.compiled: h = mlog.red('DID NOT COMPILE') @@ -648,7 +648,7 @@ class CompilerHolder(InterpreterObject): if not isinstance(prefix, str): raise InterpreterException('Prefix argument of has_function must be a string.') extra_args = self.determine_args(kwargs) - had = self.compiler.has_member(typename, membername, prefix, extra_args) + had = self.compiler.has_member(typename, membername, prefix, self.environment, extra_args) if had: hadtxt = mlog.green('YES') else: @@ -683,7 +683,7 @@ class CompilerHolder(InterpreterObject): if not isinstance(prefix, str): raise InterpreterException('Prefix argument of has_type must be a string.') extra_args = self.determine_args(kwargs) - had = self.compiler.has_type(typename, prefix, extra_args) + had = self.compiler.has_type(typename, prefix, self.environment, extra_args) if had: hadtxt = mlog.green('YES') else: @@ -713,7 +713,7 @@ class CompilerHolder(InterpreterObject): if not isinstance(testname, str): raise InterpreterException('Testname argument must be a string.') extra_args = self.determine_args(kwargs) - result = self.compiler.compiles(code, extra_args) + result = self.compiler.compiles(code, self.environment, extra_args) if len(testname) > 0: if result: h = mlog.green('YES') @@ -731,7 +731,7 @@ class CompilerHolder(InterpreterObject): if not isinstance(testname, str): raise InterpreterException('Testname argument must be a string.') extra_args = self.determine_args(kwargs) - result = self.compiler.links(code, extra_args) + result = self.compiler.links(code, self.environment, extra_args) if len(testname) > 0: if result: h = mlog.green('YES') @@ -746,7 +746,7 @@ class CompilerHolder(InterpreterObject): check_stringlist(args) string = args[0] extra_args = self.determine_args(kwargs) - haz = self.compiler.has_header(string, extra_args) + haz = self.compiler.has_header(string, self.environment, extra_args) if haz: h = mlog.green('YES') else: @@ -764,7 +764,7 @@ class CompilerHolder(InterpreterObject): if not isinstance(prefix, str): raise InterpreterException('Prefix argument of has_function must be a string.') extra_args = self.determine_args(kwargs) - haz = self.compiler.has_header_symbol(hname, symbol, prefix, extra_args) + haz = self.compiler.has_header_symbol(hname, symbol, prefix, self.environment, extra_args) if haz: h = mlog.green('YES') else: @@ -785,7 +785,7 @@ class CompilerHolder(InterpreterObject): for i in search_dirs: if not os.path.isabs(i): raise InvalidCode('Search directory %s is not an absolute path.' % i) - linkargs = self.compiler.find_library(libname, search_dirs) + linkargs = self.compiler.find_library(libname, self.environment, search_dirs) if required and linkargs is None: raise InterpreterException('Library {} not found'.format(libname)) lib = dependencies.ExternalLibrary(libname, linkargs) @@ -795,7 +795,7 @@ class CompilerHolder(InterpreterObject): args = mesonlib.stringlistify(args) if len(args) != 1: raise InterpreterException('Has_arg takes exactly one argument.') - result = self.compiler.has_argument(args[0]) + result = self.compiler.has_argument(args[0], self.environment) if result: h = mlog.green('YES') else: @@ -805,7 +805,7 @@ class CompilerHolder(InterpreterObject): def first_supported_argument_method(self, args, kwargs): for i in mesonlib.stringlistify(args): - if self.compiler.has_argument(i): + if self.compiler.has_argument(i, self.environment): mlog.log('First supported argument:', mlog.bold(i)) return [i] mlog.log('First supported argument:', mlog.red('None')) @@ -1557,10 +1557,10 @@ class Interpreter(): # cross_comp = self.environment.detect_fortran_compiler(True) else: raise InvalidCode('Tried to use unknown language "%s".' % lang) - comp.sanity_check(self.environment.get_scratch_dir()) + comp.sanity_check(self.environment.get_scratch_dir(), self.environment) self.coredata.compilers[lang] = comp if cross_comp is not None: - cross_comp.sanity_check(self.environment.get_scratch_dir()) + cross_comp.sanity_check(self.environment.get_scratch_dir(), self.environment) self.coredata.cross_compilers[lang] = cross_comp new_options = comp.get_options() optprefix = lang + '_' diff --git a/mesonbuild/scripts/__init__.py b/mesonbuild/scripts/__init__.py index e69de29..19c4fc7 100644 --- a/mesonbuild/scripts/__init__.py +++ b/mesonbuild/scripts/__init__.py @@ -0,0 +1,22 @@ +#!/usr/bin/env python3 + +# Copyright 2016 The Meson development team + +# 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. + +def destdir_join(d1, d2): + # c:\destdir + c:\prefix must produce c:\destdir\prefix + if len(d1) > 1 and d1[1] == ':' and \ + len(d2) > 1 and d2[1] == ':': + return d1 + d2[2:] + return d1 + d2 diff --git a/mesonbuild/scripts/gettext.py b/mesonbuild/scripts/gettext.py index d8b2a9c..4677d5f 100644 --- a/mesonbuild/scripts/gettext.py +++ b/mesonbuild/scripts/gettext.py @@ -15,6 +15,7 @@ # limitations under the License. import os, subprocess, shutil +from mesonbuild.scripts import destdir_join def run_potgen(src_sub, pkgname, args): listfile = os.path.join(src_sub, 'POTFILES') @@ -56,7 +57,8 @@ def run(args): langs = args[4:] src_sub = os.path.join(os.environ['MESON_SOURCE_ROOT'], subdir) bld_sub = os.path.join(os.environ['MESON_BUILD_ROOT'], subdir) - dest = os.environ.get('DESTDIR') + os.path.join(os.environ['MESON_INSTALL_PREFIX'], instsubdir) + destdir = os.environ.get('DESTDIR', '') + dest = destdir_join(destdir, os.path.join(os.environ['MESON_INSTALL_PREFIX'], instsubdir)) if gen_gmo(src_sub, bld_sub, langs) != 0: return 1 do_install(src_sub, bld_sub, dest, pkgname, langs) diff --git a/mesonbuild/scripts/gtkdochelper.py b/mesonbuild/scripts/gtkdochelper.py index d920b61..cc06f7b 100644 --- a/mesonbuild/scripts/gtkdochelper.py +++ b/mesonbuild/scripts/gtkdochelper.py @@ -17,6 +17,7 @@ import sys, os import subprocess import shutil import argparse +from mesonbuild.scripts import destdir_join parser = argparse.ArgumentParser() @@ -113,10 +114,8 @@ def run(args): fixxrefargs) if 'MESON_INSTALL_PREFIX' in os.environ: - if 'DESTDIR' in os.environ: - installdir = os.environ['DESTDIR'] + os.environ['MESON_INSTALL_PREFIX'] - else: - installdir = os.environ['MESON_INSTALL_PREFIX'] + destdir = os.environ.get('DESTDIR', '') + installdir = destdir_join(destdir, os.environ['MESON_INSTALL_PREFIX']) install_gtkdoc(options.builddir, options.subdir, installdir, diff --git a/mesonbuild/scripts/meson_install.py b/mesonbuild/scripts/meson_install.py index 0be1e18..3a87f2d 100644 --- a/mesonbuild/scripts/meson_install.py +++ b/mesonbuild/scripts/meson_install.py @@ -17,6 +17,7 @@ import sys, pickle, os, shutil, subprocess, gzip, platform from glob import glob from mesonbuild.scripts import depfixer +from mesonbuild.scripts import destdir_join def do_copy(from_file, to_file): try: @@ -27,21 +28,10 @@ def do_copy(from_file, to_file): shutil.copyfile(from_file, to_file) shutil.copystat(from_file, to_file) -def destdir_join(d1, d2): - # c:\destdir + c:\prefix must produce c:\destdir\prefix - if len(d1) > 1 and d1[1] == ':' and \ - len(d2) > 1 and d2[1] == ':': - return d1 + d2[2:] - return d1 + d2 - def do_install(datafilename): ifile = open(datafilename, 'rb') d = pickle.load(ifile) - destdir_var = 'DESTDIR' - if destdir_var in os.environ: - d.destdir = os.environ[destdir_var] - else: - d.destdir = '' + d.destdir = os.environ.get('DESTDIR', '') d.fullprefix = destdir_join(d.destdir, d.prefix) install_subdirs(d) # Must be first, because it needs to delete the old subtree. diff --git a/run_tests.py b/run_tests.py index 1c6ae11..5fdfce9 100755 --- a/run_tests.py +++ b/run_tests.py @@ -406,7 +406,7 @@ def generate_prebuilt_object(): else: raise RuntimeError("Could not find C compiler.") cmd = [cmd, '-c', source, '-o', objectfile] - subprocess.check_call(cmd) + subprocess.check_call(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) return objectfile if __name__ == '__main__': @@ -431,7 +431,7 @@ if __name__ == '__main__': print('\nTotal passed tests:', passing_tests) print('Total failed tests:', failing_tests) print('Total skipped tests:', skipped_tests) - if failing_tests > 0 and 'TRAVIS' in os.environ: + if failing_tests > 0 and ('TRAVIS' in os.environ or 'APPVEYOR' in os.environ): # Cat because it can have stuff of unknown encodings mixed. subprocess.call(['cat', 'meson-test-run.txt']) sys.exit(failing_tests) diff --git a/test cases/common/103 manygen/subdir/manygen.py b/test cases/common/103 manygen/subdir/manygen.py index 3c692ee..4411183 100755 --- a/test cases/common/103 manygen/subdir/manygen.py +++ b/test cases/common/103 manygen/subdir/manygen.py @@ -13,7 +13,15 @@ if not os.path.isdir(outdir): print('Outdir does not exist.') sys.exit(1) -if shutil.which('cl'): +# Emulate the environment.detect_c_compiler() logic +compiler = os.environ.get('CC', None) +if not compiler: + compiler = shutil.which('cl') or \ + shutil.which('gcc') or \ + shutil.which('clang') or \ + shutil.which('cc') + +if 'cl' in os.path.basename(compiler): libsuffix = '.lib' is_vs = True compiler = 'cl' @@ -22,11 +30,6 @@ else: libsuffix = '.a' is_vs = False linker = 'ar' - compiler = shutil.which('gcc') - if compiler is None: - compiler = shutil.which('clang') - if compiler is None: - compiler = shutil.which('cc') if compiler is None: print('No known compilers found.') sys.exit(1) diff --git a/test cases/common/86 same basename/meson.build b/test cases/common/86 same basename/meson.build index ba88dfd..e320f95 100644 --- a/test cases/common/86 same basename/meson.build +++ b/test cases/common/86 same basename/meson.build @@ -3,9 +3,13 @@ project('same basename', 'c') # Use the same source file to check that each top level target # has its own unique working directory. If they don't # then the .o files will clobber each other. -stlib = static_library('name', 'lib.c', c_args : '-DSTAT') shlib = shared_library('name', 'lib.c', c_args : '-DSHAR') +# On Windows a static lib is a foo.lib but a share library +# is both a foo.dll and a foo.lib. Put static in subdir to avoid +# name clashes. +subdir('sub') + exe1 = executable('name', 'exe1.c', link_with : stlib) exe2 = executable('name2', 'exe2.c', link_with : shlib) diff --git a/test cases/common/86 same basename/sub/meson.build b/test cases/common/86 same basename/sub/meson.build new file mode 100644 index 0000000..07250a5 --- /dev/null +++ b/test cases/common/86 same basename/sub/meson.build @@ -0,0 +1 @@ +stlib = static_library('name', '../lib.c', c_args : '-DSTAT') |