diff options
-rw-r--r-- | .travis.yml | 4 | ||||
-rw-r--r-- | authors.txt | 1 | ||||
-rw-r--r-- | mesonbuild/backend/backends.py | 6 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 26 | ||||
-rw-r--r-- | mesonbuild/build.py | 8 | ||||
-rw-r--r-- | mesonbuild/compilers.py | 16 | ||||
-rw-r--r-- | mesonbuild/mesonlib.py | 9 | ||||
-rw-r--r-- | mesonbuild/mintro.py | 27 | ||||
-rwxr-xr-x | run_tests.py | 12 | ||||
-rwxr-xr-x | run_unittests.py | 25 | ||||
-rw-r--r-- | test cases/common/5 linkstatic/libfile2.c | 3 | ||||
-rw-r--r-- | test cases/common/5 linkstatic/libfile3.c | 3 | ||||
-rw-r--r-- | test cases/common/5 linkstatic/libfile4.c | 3 | ||||
-rw-r--r-- | test cases/common/5 linkstatic/meson.build | 2 | ||||
-rw-r--r-- | test cases/vala/12 custom output/foo.vala | 0 | ||||
-rw-r--r-- | test cases/vala/12 custom output/meson.build | 9 |
16 files changed, 113 insertions, 41 deletions
diff --git a/.travis.yml b/.travis.yml index fdf82ef..cf3a5a6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,13 +13,13 @@ services: before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install ninja python3; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull jpakkane/mesonci:xenial; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker pull jpakkane/mesonci:yakkety; fi # We need to copy the current checkout inside the Docker container, # because it has the MR id to be tested checked out. script: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM jpakkane/mesonci:xenial > Dockerfile; fi + - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo FROM jpakkane/mesonci:yakkety > Dockerfile; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then echo ADD . /root >> Dockerfile; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker build -t withgit .; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run withgit /bin/sh -c "cd /root && TRAVIS=true ./run_tests.py"; fi diff --git a/authors.txt b/authors.txt index 5931481..f591d13 100644 --- a/authors.txt +++ b/authors.txt @@ -53,3 +53,4 @@ Gautier Pelloux-Prayer Alexandre Foley Jouni Kosonen Aurelien Jarno +Mark Schulte diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index fd71924..e91b44b 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -200,11 +200,15 @@ class Backend(): with open(exe_data, 'wb') as f: if isinstance(exe, dependencies.ExternalProgram): exe_fullpath = exe.fullpath + exe_needs_wrapper = False elif isinstance(exe, (build.BuildTarget, build.CustomTarget)): exe_fullpath = [self.get_target_filename_abs(exe)] + exe_needs_wrapper = exe.is_cross else: exe_fullpath = [exe] - is_cross = self.environment.is_cross_build() and \ + exe_needs_wrapper = False + is_cross = exe_needs_wrapper and \ + self.environment.is_cross_build() and \ self.environment.cross_info.need_cross_compiler() and \ self.environment.cross_info.need_exe_wrapper() if is_cross: diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index f826f89..dd0143c 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -23,6 +23,7 @@ from .backends import InstallData from ..build import InvalidArguments import os, sys, pickle, re import subprocess, shutil +from collections import OrderedDict if mesonlib.is_windows(): quote_char = '"' @@ -239,7 +240,7 @@ int dummy; (relative to the build directory) of that type and the value being the GeneratorList or CustomTarget that generated it. """ - srcs = {} + srcs = OrderedDict() for gensrc in target.get_generated_sources(): for s in gensrc.get_outputs(): f = self.get_target_generated_dir(target, gensrc, s) @@ -247,7 +248,7 @@ int dummy; return srcs def get_target_sources(self, target): - srcs = {} + srcs = OrderedDict() for s in target.get_sources(): # BuildTarget sources are always mesonlib.File files which are # either in the source root, or generated with configure_file and @@ -300,10 +301,10 @@ int dummy; # Pre-existing target C/C++ sources to be built; dict of full path to # source relative to build root and the original File object. - target_sources = {} + target_sources = OrderedDict() # GeneratedList and CustomTarget sources to be built; dict of the full # path to source relative to build root and the generating target/list - generated_sources = {} + generated_sources = OrderedDict() # Array of sources generated by valac that have to be compiled vala_generated_sources = [] if 'vala' in target.compilers: @@ -939,10 +940,10 @@ int dummy; the keys being the path to the file (relative to the build directory) and the value being the object that generated or represents the file. """ - vala = {} - vapi = {} - others = {} - othersgen = {} + vala = OrderedDict() + vapi = OrderedDict() + others = OrderedDict() + othersgen = OrderedDict() # Split pre-existing sources for s in t.get_sources(): # BuildTarget sources are always mesonlib.File files which are @@ -1027,15 +1028,14 @@ int dummy; # Library name args += ['--library=' + target.name] # Outputted header - hname = os.path.join(self.get_target_dir(target), target.name + '.h') + hname = os.path.join(self.get_target_dir(target), target.vala_header) args += ['-H', hname] valac_outputs.append(hname) # Outputted vapi file - base_vapi = target.name + '.vapi' - vapiname = os.path.join(self.get_target_dir(target), base_vapi) + vapiname = os.path.join(self.get_target_dir(target), target.vala_vapi) # Force valac to write the vapi file in the target build dir. # Without this, it will write it inside c_out_dir - args += ['--vapi=../' + base_vapi] + args += ['--vapi', os.path.join('..', target.vala_vapi)] valac_outputs.append(vapiname) if self.environment.coredata.get_builtin_option('werror'): args += valac.get_werror_args() @@ -1088,7 +1088,7 @@ int dummy; args += ['--out-dir', target.subdir] args += ['--emit', 'dep-info', '--emit', 'link'] orderdeps = [os.path.join(t.subdir, t.get_filename()) for t in target.link_targets] - linkdirs = {} + linkdirs = OrderedDict() for d in target.link_targets: linkdirs[d.subdir] = True for d in linkdirs.keys(): diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 0ecc94a..c3867e0 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -55,6 +55,8 @@ known_lib_kwargs.update({'version' : True, # Only for shared libs 'name_prefix' : True, 'name_suffix' : True, 'vs_module_defs' : True, # Only for shared libs + 'vala_header': True, + 'vala_vapi': True, 'pic' : True, # Only for static libs }) @@ -493,6 +495,9 @@ class BuildTarget(): if not isinstance(valalist, list): valalist = [valalist] self.add_compiler_args('vala', valalist) + if not isinstance(self, Executable): + self.vala_header = kwargs.get('vala_header', self.name + '.h') + self.vala_vapi = kwargs.get('vala_vapi', self.name + '.vapi') dlist = stringlistify(kwargs.get('d_args', [])) self.add_compiler_args('d', dlist) self.link_args = kwargs.get('link_args', []) @@ -1262,6 +1267,9 @@ class CustomTarget: def get_outputs(self): return self.output + def get_filename(self): + return self.output[0] + def get_sources(self): return self.sources diff --git a/mesonbuild/compilers.py b/mesonbuild/compilers.py index 2d255dd..94e8a54 100644 --- a/mesonbuild/compilers.py +++ b/mesonbuild/compilers.py @@ -1800,7 +1800,7 @@ class VisualStudioCCompiler(CCompiler): # Translate GNU-style -lfoo library name to the import library elif i.startswith('-l'): name = i[2:] - if name in ('m', 'c'): + if name in ('m', 'c', 'pthread'): # With MSVC, these are provided by the C runtime which is # linked in by default continue @@ -1813,7 +1813,8 @@ class VisualStudioCCompiler(CCompiler): result = [] for i in args: # -mms-bitfields is specific to MinGW-GCC - if i == '-mms-bitfields': + # -pthread is only valid for GCC + if i in ('-mms-bitfields', '-pthread'): continue result.append(i) return result @@ -1974,7 +1975,8 @@ class GnuCCompiler(GnuCompiler, CCompiler): def get_options(self): opts = {'c_std' : coredata.UserComboOption('c_std', 'C language standard to use', - ['none', 'c89', 'c99', 'c11', 'gnu89', 'gnu99', 'gnu11'], + ['none', 'c89', 'c99', 'c11', + 'gnu89', 'gnu99', 'gnu11'], 'none')} if self.gcc_type == GCC_MINGW: opts.update({ @@ -2122,7 +2124,8 @@ class ClangCCompiler(ClangCompiler, CCompiler): def get_options(self): return {'c_std' : coredata.UserComboOption('c_std', 'C language standard to use', - ['none', 'c89', 'c99', 'c11'], + ['none', 'c89', 'c99', 'c11', + 'gnu89', 'gnu99', 'gnu11',], 'none')} def get_option_compile_args(self, options): @@ -2146,8 +2149,9 @@ class ClangCPPCompiler(ClangCompiler, CPPCompiler): def get_options(self): return {'cpp_std' : coredata.UserComboOption('cpp_std', 'C++ language standard to use', - ['none', 'c++03', 'c++11', 'c++14', 'c++1z'], - 'none')} + ['none', 'c++03', 'c++11', 'c++14', 'c++1z', + 'gnu++03', 'gnu++11', 'gnu++14', 'gnu++1z'], + 'none')} def get_option_compile_args(self, options): args = [] diff --git a/mesonbuild/mesonlib.py b/mesonbuild/mesonlib.py index 8133c48..943a23e 100644 --- a/mesonbuild/mesonlib.py +++ b/mesonbuild/mesonlib.py @@ -320,14 +320,17 @@ def dump_conf_header(ofilename, cdata): def replace_if_different(dst, dst_tmp): # If contents are identical, don't touch the file to prevent # unnecessary rebuilds. + different = True try: with open(dst, 'r') as f1, open(dst_tmp, 'r') as f2: if f1.read() == f2.read(): - os.unlink(dst_tmp) - return + different = False except FileNotFoundError: pass - os.replace(dst_tmp, dst) + if different: + os.replace(dst_tmp, dst) + else: + os.unlink(dst_tmp) def stringlistify(item): if isinstance(item, str): diff --git a/mesonbuild/mintro.py b/mesonbuild/mintro.py index a18912e..492bf3f 100644 --- a/mesonbuild/mintro.py +++ b/mesonbuild/mintro.py @@ -20,7 +20,7 @@ Currently only works for the Ninja backend. Others use generated project files and don't need this info.""" import json, pickle -from . import coredata, build, mesonlib +from . import coredata, build import argparse import sys, os @@ -41,7 +41,20 @@ parser.add_argument('--dependencies', action='store_true', dest='dependencies', help='list external dependencies.') parser.add_argument('args', nargs='+') -def list_targets(coredata, builddata): +def determine_installed_path(target, installdata): + install_target = None + for i in installdata.targets: + if os.path.split(i[0])[1] == target.get_filename(): # FIXME, might clash due to subprojects. + install_target = i + break + if install_target is None: + raise RuntimeError('Something weird happened. File a bug.') + fname = i[0] + outdir = i[1] + outname = os.path.join(installdata.prefix, outdir, os.path.split(fname)[-1]) + return outname + +def list_targets(coredata, builddata, installdata): tlist = [] for (idname, target) in builddata.get_targets().items(): t = {} @@ -68,6 +81,7 @@ def list_targets(coredata, builddata): t['type'] = typename if target.should_install(): t['installed'] = True + t['install_filename'] = determine_installed_path(target, installdata) else: t['installed'] = False tlist.append(t) @@ -173,6 +187,7 @@ def run(args): bdir = '' corefile = os.path.join(bdir, 'meson-private/coredata.dat') buildfile = os.path.join(bdir, 'meson-private/build.dat') + installfile = os.path.join(bdir, 'meson-private/install.dat') testfile = os.path.join(bdir, 'meson-private/meson_test_setup.dat') benchmarkfile = os.path.join(bdir, 'meson-private/meson_benchmark_setup.dat') with open(corefile, 'rb') as f: @@ -180,11 +195,13 @@ def run(args): with open(buildfile, 'rb') as f: builddata = pickle.load(f) with open(testfile, 'rb') as f: - testdata = pickle.load(f) + testdata = pickle.load(f) with open(benchmarkfile, 'rb') as f: - benchmarkdata = pickle.load(f) + benchmarkdata = pickle.load(f) + with open(installfile, 'rb') as f: + installdata = pickle.load(f) if options.list_targets: - list_targets(coredata, builddata) + list_targets(coredata, builddata, installdata) elif options.target_files is not None: list_target_files(options.target_files, coredata, builddata) elif options.buildsystem_files: diff --git a/run_tests.py b/run_tests.py index ec8970a..752354e 100755 --- a/run_tests.py +++ b/run_tests.py @@ -21,15 +21,7 @@ from mesonbuild import mesonlib if __name__ == '__main__': returncode = 0 if mesonlib.is_linux(): - myenv = os.environ.copy() - myenv['CC'] = 'gcc' - myenv['CXX'] = 'g++' - print('Running unittests with GCC.\n') - returncode += subprocess.call([sys.executable, 'run_unittests.py', '-v'], env=myenv) - if shutil.which('clang'): - myenv['CC'] = 'clang' - myenv['CXX'] = 'clang++' - print('\nRunning unittests with clang.\n') - returncode += subprocess.call([sys.executable, 'run_unittests.py', '-v'], env=myenv) + print('Running unittests.\n') + returncode += subprocess.call([sys.executable, 'run_unittests.py', '-v']) returncode += subprocess.call([sys.executable, 'run_project_tests.py'] + sys.argv[1:]) sys.exit(returncode) diff --git a/run_unittests.py b/run_unittests.py index b9c1397..0e3b7d5 100755 --- a/run_unittests.py +++ b/run_unittests.py @@ -43,6 +43,7 @@ class LinuxlikeTests(unittest.TestCase): self.builddir = tempfile.mkdtemp() self.meson_command = [sys.executable, os.path.join(src_root, 'meson.py')] self.mconf_command = [sys.executable, os.path.join(src_root, 'mesonconf.py')] + self.mintro_command = [sys.executable, os.path.join(src_root, 'mesonintrospect.py')] self.ninja_command = [detect_ninja(), '-C', self.builddir] self.common_test_dir = os.path.join(src_root, 'test cases/common') self.vala_test_dir = os.path.join(src_root, 'test cases/vala') @@ -67,6 +68,10 @@ class LinuxlikeTests(unittest.TestCase): with open(os.path.join(self.builddir, 'compile_commands.json')) as ifile: return json.load(ifile) + def introspect(self, arg): + out = subprocess.check_output(self.mintro_command + [arg, self.builddir]) + return json.loads(out.decode('utf-8')) + def test_basic_soname(self): testdir = os.path.join(self.common_test_dir, '4 shared') self.init(testdir) @@ -136,5 +141,25 @@ class LinuxlikeTests(unittest.TestCase): self.assertTrue('-Werror' in vala_command) self.assertTrue('-Werror' in c_command) + def test_static_compile_order(self): + testdir = os.path.join(self.common_test_dir, '5 linkstatic') + self.init(testdir) + compdb = self.get_compdb() + # Rules will get written out in this order + self.assertTrue(compdb[0]['file'].endswith("libfile.c")) + self.assertTrue(compdb[1]['file'].endswith("libfile2.c")) + self.assertTrue(compdb[2]['file'].endswith("libfile3.c")) + self.assertTrue(compdb[3]['file'].endswith("libfile4.c")) + # FIXME: We don't have access to the linker command + + def test_install_introspection(self): + testdir = os.path.join(self.common_test_dir, '8 install') + self.init(testdir) + intro = self.introspect('--targets') + if intro[0]['type'] == 'executable': + intro = intro[::-1] + self.assertEqual(intro[0]['install_filename'], '/usr/local/libtest/libstat.a') + self.assertEqual(intro[1]['install_filename'], '/usr/local/bin/prog') + if __name__ == '__main__': unittest.main() diff --git a/test cases/common/5 linkstatic/libfile2.c b/test cases/common/5 linkstatic/libfile2.c new file mode 100644 index 0000000..89780f5 --- /dev/null +++ b/test cases/common/5 linkstatic/libfile2.c @@ -0,0 +1,3 @@ +int func2() { + return 2; +} diff --git a/test cases/common/5 linkstatic/libfile3.c b/test cases/common/5 linkstatic/libfile3.c new file mode 100644 index 0000000..5e0d08b --- /dev/null +++ b/test cases/common/5 linkstatic/libfile3.c @@ -0,0 +1,3 @@ +int func3() { + return 3; +} diff --git a/test cases/common/5 linkstatic/libfile4.c b/test cases/common/5 linkstatic/libfile4.c new file mode 100644 index 0000000..3645c31 --- /dev/null +++ b/test cases/common/5 linkstatic/libfile4.c @@ -0,0 +1,3 @@ +int func4() { + return 4; +} diff --git a/test cases/common/5 linkstatic/meson.build b/test cases/common/5 linkstatic/meson.build index c1cb8b6..1f02a5c 100644 --- a/test cases/common/5 linkstatic/meson.build +++ b/test cases/common/5 linkstatic/meson.build @@ -1,6 +1,6 @@ project('static library linking test', 'c') -lib = build_target('mylib', 'libfile.c', target_type : 'static_library') +lib = build_target('mylib', 'libfile.c', 'libfile2.c', 'libfile3.c', 'libfile4.c', target_type : 'static_library') exe = executable('prog', 'main.c', link_with : lib) test('runtest', exe) diff --git a/test cases/vala/12 custom output/foo.vala b/test cases/vala/12 custom output/foo.vala new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test cases/vala/12 custom output/foo.vala diff --git a/test cases/vala/12 custom output/meson.build b/test cases/vala/12 custom output/meson.build new file mode 100644 index 0000000..ef6dbb5 --- /dev/null +++ b/test cases/vala/12 custom output/meson.build @@ -0,0 +1,9 @@ +project('valatest', 'c', 'vala') + +glib = dependency('glib-2.0') +gobject = dependency('gobject-2.0') + +library('foo-1.0', 'foo.vala', + vala_header: 'foo.h', + vala_vapi: 'foo.vapi', + dependencies: [glib, gobject]) |