diff options
-rw-r--r-- | docs/markdown/Build-options.md | 13 | ||||
-rw-r--r-- | docs/markdown/Unit-tests.md | 18 | ||||
-rw-r--r-- | docs/markdown/i18n-module.md | 2 | ||||
-rwxr-xr-x | ghwt.py | 5 | ||||
-rwxr-xr-x | meson.py | 2 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 2 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 2 | ||||
-rw-r--r-- | mesonbuild/build.py | 49 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 2 | ||||
-rw-r--r-- | mesonbuild/modules/i18n.py | 27 | ||||
-rw-r--r--[-rwxr-xr-x] | mesonbuild/rewriter.py | 0 | ||||
-rw-r--r--[-rwxr-xr-x] | msi/License.rtf | 0 | ||||
-rw-r--r-- | test cases/common/146 C and CPP link/dummy.c | 0 | ||||
-rw-r--r-- | test cases/common/146 C and CPP link/meson.build | 36 | ||||
-rw-r--r-- | test cases/common/146 C and CPP link/sub.c | 19 | ||||
-rw-r--r-- | test cases/common/146 C and CPP link/sub.h | 16 | ||||
-rw-r--r-- | test cases/common/98 gen extra/meson.build | 17 | ||||
-rw-r--r-- | test cases/common/98 gen extra/name.l | 3 | ||||
-rw-r--r-- | test cases/common/98 gen extra/srcgen2.py | 32 |
19 files changed, 207 insertions, 38 deletions
diff --git a/docs/markdown/Build-options.md b/docs/markdown/Build-options.md index 54905d5..cb7b19e 100644 --- a/docs/markdown/Build-options.md +++ b/docs/markdown/Build-options.md @@ -42,11 +42,16 @@ prefix = get_option('prefix') ``` It should be noted that you can not set option values in your Meson -scripts. They have to be set externally with the `mesonconf` command -line tool. Running `mesonconf` without arguments in a build dir shows -you all options you can set. To change their values use the `-D` +scripts. They have to be set externally with the `meson configure` command +line tool. Running `meson configure` without arguments in a build dir shows +you all options you can set. + +To change their values use the `-D` option: ```console -$ mesonconf -Doption=newvalue +$ meson configure -Doption=newvalue ``` + + +**NOTE:** If you cannot call `meson configure` you likely have a old version of Meson. In that case you can call `mesonconf` instead, but that is deprecated in newer versions diff --git a/docs/markdown/Unit-tests.md b/docs/markdown/Unit-tests.md index 7949522..6ded714 100644 --- a/docs/markdown/Unit-tests.md +++ b/docs/markdown/Unit-tests.md @@ -57,42 +57,42 @@ Sometimes a test can only determine at runtime that it can not be run. The GNU s ## Testing tool -In version 0.37.0 a new tool called `mesontest` was added. The goal of this tool is to provide a simple way to run tests in a variety of different ways. The tool is designed to be run in the build directory. +The goal of the meson test tool is to provide a simple way to run tests in a variety of different ways. The tool is designed to be run in the build directory. The simplest thing to do is just to run all tests, which is equivalent to running `ninja test`. ```console -$ mesontest +$ meson test ``` You can also run only a single test by giving its name: ```console -$ mesontest testname +$ meson test testname ``` Sometimes you need to run the tests multiple times, which is done like this: ```console -$ mesontest --repeat=10 +$ meson test --repeat=10 ``` Invoking tests via a helper executable such as Valgrind can be done with the `--wrap` argument ```console -$ mesontest --wrap=valgrind testname +$ meson test --wrap=valgrind testname ``` Arguments to the wrapper binary can be given like this: ```console -$ mesontest --wrap='valgrind --tool=helgrind' testname +$ meson test --wrap='valgrind --tool=helgrind' testname ``` Meson also supports running the tests under GDB. Just doing this: ```console -$ mesontest --gdb testname +$ meson test --gdb testname ``` Mesontest will launch `gdb` all set up to run the test. Just type `run` in the GDB command prompt to start the program. @@ -100,9 +100,11 @@ Mesontest will launch `gdb` all set up to run the test. Just type `run` in the G The second use case is a test that segfaults only rarely. In this case you can invoke the following command: ```console -$ mesontest --gdb --repeat=10000 testname +$ meson test --gdb --repeat=10000 testname ``` This runs the test up to 10 000 times under GDB automatically. If the program crashes, GDB will halt and the user can debug the application. Note that testing timeouts are disabled in this case so mesontest will not kill `gdb` while the developer is still debugging it. The downside is that if the test binary freezes, the test runner will wait forever. For further information see the command line help of Mesontest by running `mesontest -h`. + +**NOTE:** If `meson test` does not work for you, you likely have a old version of Meson. In that case you should call `mesontest` instead. If `mesontest` doesn't work either you have a very old version prior to 0.37.0 and should upgrade. diff --git a/docs/markdown/i18n-module.md b/docs/markdown/i18n-module.md index 5e6004a..1144e29 100644 --- a/docs/markdown/i18n-module.md +++ b/docs/markdown/i18n-module.md @@ -32,6 +32,8 @@ argument which is the name of the gettext module. [source](https://github.com/mesonbuild/meson/blob/master/mesonbuild/modules/i18n.py) for for their value +* `install`: (*Added 0.43.0*) if false, do not install the built translations. + This function also defines targets for maintainers to use: **Note**: These output to the source directory @@ -14,6 +14,11 @@ # See the License for the specific language governing permissions and # limitations under the License. +# ghwt - GitHub WrapTool +# +# An emergency wraptool(1) replacement downloader that downloads +# directly from GitHub in case wrapdb.mesonbuild.com is down. + import urllib.request, json, sys, os, shutil, subprocess import configparser, hashlib @@ -24,7 +24,7 @@ def main(): # encoding, so we can just warn about it. e = locale.getpreferredencoding() if e.upper() != 'UTF-8' and not mesonlib.is_windows(): - print('Warning: You are using {!r} which is not a a Unicode-compatible ' + print('Warning: You are using {!r} which is not a Unicode-compatible ' 'locale.'.format(e), file=sys.stderr) print('You might see errors if you use UTF-8 strings as ' 'filenames, as strings, or as file contents.', file=sys.stderr) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index e9fc041..41b93cb 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1784,7 +1784,6 @@ rule FORTRAN_DEP_HACK exe_arr = self.exe_object_to_cmd_array(exe) infilelist = genlist.get_inputs() outfilelist = genlist.get_outputs() - base_args = generator.get_arglist() extra_dependencies = [os.path.join(self.build_to_src, i) for i in genlist.extra_depends] source_target_dir = self.get_target_source_dir(target) for i in range(len(infilelist)): @@ -1794,6 +1793,7 @@ rule FORTRAN_DEP_HACK sole_output = '' curfile = infilelist[i] infilename = curfile.rel_to_builddir(self.build_to_src) + base_args = generator.get_arglist(infilename) outfiles = genlist.get_outputs_for(curfile) outfiles = [os.path.join(self.get_target_private_dir(target), of) for of in outfiles] if generator.depfile is None: diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index 88bab36..22c1779 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -105,7 +105,6 @@ class Vs2010Backend(backends.Backend): infilelist = genlist.get_inputs() outfilelist = genlist.get_outputs() exe_arr = self.exe_object_to_cmd_array(exe) - base_args = generator.get_arglist() idgroup = ET.SubElement(parent_node, 'ItemGroup') for i in range(len(infilelist)): if len(infilelist) == len(outfilelist): @@ -114,6 +113,7 @@ class Vs2010Backend(backends.Backend): sole_output = '' curfile = infilelist[i] infilename = os.path.join(down, curfile.rel_to_builddir(self.build_to_src)) + base_args = generator.get_arglist(infilename) outfiles_rel = genlist.get_outputs_for(curfile) outfiles = [os.path.join(target_private_dir, of) for of in outfiles_rel] generator_output_files += outfiles diff --git a/mesonbuild/build.py b/mesonbuild/build.py index 281b060..c54abbd 100644 --- a/mesonbuild/build.py +++ b/mesonbuild/build.py @@ -359,6 +359,7 @@ class BuildTarget(Target): self.check_unknown_kwargs(kwargs) if not self.sources and not self.generated and not self.objects: raise InvalidArguments('Build target %s has no sources.' % name) + self.process_compilers_late() self.validate_sources() self.validate_cross_install(environment) @@ -439,6 +440,39 @@ class BuildTarget(Target): removed = True return removed + def process_compilers_late(self): + """Processes additional compilers after kwargs have been evaluated. + + This can add extra compilers that might be required by keyword + arguments, such as link_with or dependencies. It will also try to guess + which compiler to use if one hasn't been selected already. + """ + # Populate list of compilers + if self.is_cross: + compilers = self.environment.coredata.cross_compilers + else: + compilers = self.environment.coredata.compilers + + # If this library is linked against another library we need to consider + # the languages of those libraries as well. + if self.link_targets or self.link_whole_targets: + extra = set() + for t in itertools.chain(self.link_targets, self.link_whole_targets): + for name, compiler in t.compilers.items(): + if name in clike_langs: + extra.add((name, compiler)) + for name, compiler in sorted(extra, key=lambda p: sort_clike(p[0])): + self.compilers[name] = compiler + + if not self.compilers: + # No source files or parent targets, target consists of only object + # files of unknown origin. Just add the first clike compiler + # that we have and hope that it can link these objects + for lang in clike_langs: + if lang in compilers: + self.compilers[lang] = compilers[lang] + break + def process_compilers(self): ''' Populate self.compilers, which is the list of compilers that this @@ -487,14 +521,7 @@ class BuildTarget(Target): # Re-sort according to clike_langs self.compilers = OrderedDict(sorted(self.compilers.items(), key=lambda t: sort_clike(t[0]))) - else: - # No source files, target consists of only object files of unknown - # origin. Just add the first clike compiler that we have and hope - # that it can link these objects - for lang in clike_langs: - if lang in compilers: - self.compilers[lang] = compilers[lang] - break + # If all our sources are Vala, our target also needs the C compiler but # it won't get added above. if 'vala' in self.compilers and 'c' not in self.compilers: @@ -1048,8 +1075,10 @@ class Generator: basename = os.path.splitext(plainname)[0] return self.depfile.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) - def get_arglist(self): - return self.arglist + def get_arglist(self, inname): + plainname = os.path.split(inname)[1] + basename = os.path.splitext(plainname)[0] + return [x.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) for x in self.arglist] def process_files(self, name, files, state, extra_args=[]): output = GeneratedList(self, extra_args=extra_args) diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 51b8202..5d854d9 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -2018,7 +2018,7 @@ class Interpreter(InterpreterBase): if progobj is None: progobj = self.program_from_system(args) if required and (progobj is None or not progobj.found()): - raise InvalidArguments('Program "%s" not found or not executable' % exename) + raise InvalidArguments('Program "%s" not found or not executable' % args[0]) if progobj is None: return ExternalProgramHolder(dependencies.ExternalProgram('nonexistingprogram')) return progobj diff --git a/mesonbuild/modules/i18n.py b/mesonbuild/modules/i18n.py index d8d539c..c1dd837 100644 --- a/mesonbuild/modules/i18n.py +++ b/mesonbuild/modules/i18n.py @@ -82,7 +82,7 @@ class I18nModule(ExtensionModule): ct = build.CustomTarget(kwargs['output'] + '_merge', state.subdir, kwargs) return ModuleReturnValue(ct, [ct]) - @permittedKwargs({'po_dir', 'data_dirs', 'type', 'languages', 'args', 'preset'}) + @permittedKwargs({'po_dir', 'data_dirs', 'type', 'languages', 'args', 'preset', 'install'}) def gettext(self, state, args, kwargs): if len(args) != 1: raise coredata.MesonException('Gettext requires one positional argument (package name).') @@ -127,16 +127,21 @@ class I18nModule(ExtensionModule): updatepoargs.append(extra_args) updatepotarget = build.RunTarget(packagename + '-update-po', updatepoargs[0], updatepoargs[1:], [], state.subdir) - script = state.environment.get_build_command() - args = ['--internal', 'gettext', 'install', - '--subdir=' + state.subdir, - '--localedir=' + state.environment.coredata.get_builtin_option('localedir'), - pkg_arg] - if lang_arg: - args.append(lang_arg) - iscript = build.RunScript(script, args) - - return ModuleReturnValue(None, [pottarget, gmotarget, iscript, updatepotarget]) + targets = [pottarget, gmotarget, updatepotarget] + + install = kwargs.get('install', True) + if install: + script = state.environment.get_build_command() + args = ['--internal', 'gettext', 'install', + '--subdir=' + state.subdir, + '--localedir=' + state.environment.coredata.get_builtin_option('localedir'), + pkg_arg] + if lang_arg: + args.append(lang_arg) + iscript = build.RunScript(script, args) + targets.append(iscript) + + return ModuleReturnValue(None, targets) def initialize(): return I18nModule() diff --git a/mesonbuild/rewriter.py b/mesonbuild/rewriter.py index b88c5ef..b88c5ef 100755..100644 --- a/mesonbuild/rewriter.py +++ b/mesonbuild/rewriter.py diff --git a/msi/License.rtf b/msi/License.rtf index 9b58df9..9b58df9 100755..100644 --- a/msi/License.rtf +++ b/msi/License.rtf diff --git a/test cases/common/146 C and CPP link/dummy.c b/test cases/common/146 C and CPP link/dummy.c new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test cases/common/146 C and CPP link/dummy.c diff --git a/test cases/common/146 C and CPP link/meson.build b/test cases/common/146 C and CPP link/meson.build index db84445..2dd3364 100644 --- a/test cases/common/146 C and CPP link/meson.build +++ b/test cases/common/146 C and CPP link/meson.build @@ -65,10 +65,44 @@ libfoo = shared_library( # # VS2010 lacks the /WHOLEARCHIVE option that later versions of MSVC support, so # don't run this tests on that backend. -if meson.backend() != 'vs2010' +if not (cxx.get_id() == 'msvc' and cxx.version().version_compare('<19')) libfoowhole = shared_library( 'foowhole', ['foobar.c', 'foobar.h'], link_whole : [libc, libcpp], ) endif + +# Test sublinking (linking C and C++, then linking that to C) +libfoo_static = static_library( + 'foo_static', + ['foobar.c', 'foobar.h'], + link_with : [libc, libcpp], +) + +libsub = shared_library( + 'sub', + ['sub.c', 'sub.h'], + link_with : libfoo_static, +) + +if not (cxx.get_id() == 'msvc' and cxx.version().version_compare('<19')) + libsubwhole = shared_library( + 'subwhole', + ['sub.c', 'sub.h'], + link_whole : libfoo_static, + ) +endif + +# Test that it really is recursive +libsub_static = static_library( + 'sub_static', + ['sub.c', 'sub.h'], + link_with : libfoo_static, +) + +libsubsub = shared_library( + 'subsub', + ['dummy.c'], + link_with : libsub_static, +) diff --git a/test cases/common/146 C and CPP link/sub.c b/test cases/common/146 C and CPP link/sub.c new file mode 100644 index 0000000..7c078f8 --- /dev/null +++ b/test cases/common/146 C and CPP link/sub.c @@ -0,0 +1,19 @@ +/* Copyright © 2017 Dylan Baker + * + * 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. + */ +#include "sub.h" + +float a_half(void) { + return .5; +} diff --git a/test cases/common/146 C and CPP link/sub.h b/test cases/common/146 C and CPP link/sub.h new file mode 100644 index 0000000..5b02e17 --- /dev/null +++ b/test cases/common/146 C and CPP link/sub.h @@ -0,0 +1,16 @@ +/* Copyright © 2017 Dylan Baker + * + * 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. + */ + +float a_half(void); diff --git a/test cases/common/98 gen extra/meson.build b/test cases/common/98 gen extra/meson.build index 52ed847..772f52e 100644 --- a/test cases/common/98 gen extra/meson.build +++ b/test cases/common/98 gen extra/meson.build @@ -11,3 +11,20 @@ g2 = gen.process('name.dat', extra_args: '--upper') test('basic', executable('basic', 'plain.c', g1)) test('upper', executable('upper', 'upper.c', g2)) + +prog2 = find_program('srcgen2.py') +basename_gen = generator(prog2, + output : ['@BASENAME@.tab.c', '@BASENAME@.tab.h'], + arguments : ['@BUILD_DIR@', '@BASENAME@', '@INPUT@']) + +basename_src = basename_gen.process('name.l') + +test('basename', executable('basename', basename_src)) + +plainname_gen = generator(prog2, + output : ['@PLAINNAME@.tab.c', '@PLAINNAME@.tab.h'], + arguments : ['@BUILD_DIR@', '@PLAINNAME@', '@INPUT@']) + +plainname_src = plainname_gen.process('name.l') + +test('plainname', executable('plainname', plainname_src)) diff --git a/test cases/common/98 gen extra/name.l b/test cases/common/98 gen extra/name.l new file mode 100644 index 0000000..3adda4f --- /dev/null +++ b/test cases/common/98 gen extra/name.l @@ -0,0 +1,3 @@ +int main() { +return 0; +} diff --git a/test cases/common/98 gen extra/srcgen2.py b/test cases/common/98 gen extra/srcgen2.py new file mode 100644 index 0000000..9cdf12d --- /dev/null +++ b/test cases/common/98 gen extra/srcgen2.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python3 + +import os +import sys +import argparse + +parser = argparse.ArgumentParser() +parser.add_argument('target_dir', + help='the target dir') +parser.add_argument('stem', + help='the stem') +parser.add_argument('input', + help='the input file') + +options = parser.parse_args(sys.argv[1:]) + +with open(options.input) as f: + content = f.read() + + +output_c = os.path.join(options.target_dir, options.stem + ".tab.c") +with open(output_c, 'w') as f: + f.write(content) + + +output_h = os.path.join(options.target_dir, options.stem + ".tab.h") +h_content = '''#pragma once + +int myfun(void); +''' +with open(output_h, 'w') as f: + f.write(h_content) |