diff options
-rw-r--r-- | authors.txt | 1 | ||||
-rw-r--r-- | mesonbuild/backend/backends.py | 6 | ||||
-rw-r--r-- | mesonbuild/backend/vs2010backend.py | 47 | ||||
-rw-r--r-- | mesonbuild/environment.py | 15 | ||||
-rw-r--r-- | mesonbuild/interpreter.py | 2 | ||||
-rw-r--r-- | mesonbuild/mconf.py | 1 | ||||
-rw-r--r-- | mesonbuild/mesonmain.py | 30 | ||||
-rwxr-xr-x | run_tests.py | 8 | ||||
-rw-r--r-- | test cases/common/106 subproject subdir/meson.build | 6 | ||||
-rw-r--r-- | test cases/common/106 subproject subdir/prog.c | 5 | ||||
-rw-r--r-- | test cases/common/106 subproject subdir/subprojects/sub/lib/meson.build | 2 | ||||
-rw-r--r-- | test cases/common/106 subproject subdir/subprojects/sub/lib/sub.c | 5 | ||||
-rw-r--r-- | test cases/common/106 subproject subdir/subprojects/sub/lib/sub.h | 6 | ||||
-rw-r--r-- | test cases/common/106 subproject subdir/subprojects/sub/meson.build | 2 | ||||
-rwxr-xr-x | test cases/common/59 object generator/obj_generator.py | 2 |
15 files changed, 102 insertions, 36 deletions
diff --git a/authors.txt b/authors.txt index 68bdb24..4552b23 100644 --- a/authors.txt +++ b/authors.txt @@ -29,3 +29,4 @@ Martin Ejdestig Rémi Nicole Damián Nohales Nirbheek Chauhan +Nicolas Schneider diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 8256cee..d2176c7 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -125,6 +125,9 @@ class Backend(): outfileabs = os.path.join(self.environment.get_build_dir(), outfilename) outfileabs_tmp = outfileabs + '.tmp' abs_files.append(outfileabs) + outfileabs_tmp_dir = os.path.dirname(outfileabs_tmp) + if not os.path.exists(outfileabs_tmp_dir): + os.makedirs(outfileabs_tmp_dir) outfile = open(outfileabs_tmp, 'w') langlist[language] = outfile result.append(outfilename) @@ -241,8 +244,7 @@ class Backend(): def generate_basic_compiler_args(self, target, compiler): commands = [] commands += compiler.get_always_args() - if self.environment.coredata.get_builtin_option('buildtype') != 'plain': - commands += compiler.get_warn_args(self.environment.coredata.get_builtin_option('warning_level')) + commands += compiler.get_warn_args(self.environment.coredata.get_builtin_option('warning_level')) commands += compiler.get_option_compile_args(self.environment.coredata.compiler_options) commands += self.build.get_global_args(compiler) commands += self.environment.coredata.external_args[compiler.get_language()] diff --git a/mesonbuild/backend/vs2010backend.py b/mesonbuild/backend/vs2010backend.py index c9fe09f..9b80edd 100644 --- a/mesonbuild/backend/vs2010backend.py +++ b/mesonbuild/backend/vs2010backend.py @@ -37,8 +37,10 @@ class Vs2010Backend(backends.Backend): self.source_suffix_in_obj = False def generate_custom_generator_commands(self, target, parent_node): - idgroup = ET.SubElement(parent_node, 'ItemDefinitionGroup') all_output_files = [] + commands = [] + inputs = [] + outputs = [] for genlist in target.get_generated_sources(): if isinstance(genlist, build.CustomTarget): all_output_files += [os.path.join(self.get_target_dir(genlist), i) for i in genlist.output] @@ -50,7 +52,7 @@ class Vs2010Backend(backends.Backend): if isinstance(exe, build.BuildTarget): exe_file = os.path.join(self.environment.get_build_dir(), self.get_target_filename(exe)) else: - exe_file = exe.get_command() + exe_file = exe.get_command()[0] base_args = generator.get_arglist() for i in range(len(infilelist)): if len(infilelist) == len(outfilelist): @@ -67,13 +69,18 @@ class Vs2010Backend(backends.Backend): args = [x.replace("@SOURCE_DIR@", self.environment.get_source_dir()).replace("@BUILD_DIR@", self.get_target_private_dir(target)) for x in args] fullcmd = [exe_file] + args - cbs = ET.SubElement(idgroup, 'CustomBuildStep') - ET.SubElement(cbs, 'Command').text = ' '.join(self.special_quote(fullcmd)) - ET.SubElement(cbs, 'Inputs').text = infilename - ET.SubElement(cbs, 'Outputs').text = ';'.join(outfiles) - ET.SubElement(cbs, 'Message').text = 'Generating sources from %s.' % infilename - pg = ET.SubElement(parent_node, 'PropertyGroup') - ET.SubElement(pg, 'CustomBuildBeforeTargets').text = 'ClCompile' + commands.append(' '.join(self.special_quote(fullcmd))) + inputs.append(infilename) + outputs.extend(outfiles) + if len(commands) > 0: + idgroup = ET.SubElement(parent_node, 'ItemDefinitionGroup') + cbs = ET.SubElement(idgroup, 'CustomBuildStep') + ET.SubElement(cbs, 'Command').text = '\r\n'.join(commands) + ET.SubElement(cbs, 'Inputs').text = ";".join(inputs) + ET.SubElement(cbs, 'Outputs').text = ';'.join(outputs) + ET.SubElement(cbs, 'Message').text = 'Generating custom sources.' + pg = ET.SubElement(parent_node, 'PropertyGroup') + ET.SubElement(pg, 'CustomBuildBeforeTargets').text = 'ClCompile' return all_output_files def generate(self, interp): @@ -206,21 +213,22 @@ class Vs2010Backend(backends.Backend): def split_sources(self, srclist): sources = [] headers = [] + objects = [] for i in srclist: if self.environment.is_header(i): headers.append(i) + elif self.environment.is_object(i): + objects.append(i) else: sources.append(i) - return (sources, headers) + return (sources, headers, objects) def target_to_build_root(self, target): if target.subdir == '': return '' - directories = os.path.split(target.subdir) - directories = list(filter(bool,directories)) #Filter out empty strings - - return '/'.join(['..']*len(directories)) + directories = os.path.normpath(target.subdir).split(os.sep) + return os.sep.join(['..']*len(directories)) def special_quote(self, arr): return ['"%s"' % i for i in arr] @@ -323,7 +331,7 @@ class Vs2010Backend(backends.Backend): down = self.target_to_build_root(target) proj_to_src_root = os.path.join(down, self.build_to_src) proj_to_src_dir = os.path.join(proj_to_src_root, target.subdir) - (sources, headers) = self.split_sources(target.sources) + (sources, headers, objects) = self.split_sources(target.sources) buildtype = self.buildtype project_name = target.name target_name = target.name @@ -356,7 +364,7 @@ class Vs2010Backend(backends.Backend): ET.SubElement(type_config, 'UseDebugLibraries').text = 'true' ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.props') generated_files = self.generate_custom_generator_commands(target, root) - (gen_src, gen_hdrs) = self.split_sources(generated_files) + (gen_src, gen_hdrs, gen_objs) = self.split_sources(generated_files) direlem = ET.SubElement(root, 'PropertyGroup') fver = ET.SubElement(direlem, '_ProjectFileVersion') fver.text = self.project_file_version @@ -483,6 +491,13 @@ class Vs2010Backend(backends.Backend): for s in gen_src: relpath = self.relpath(s, target.subdir) ET.SubElement(inc_src, 'CLCompile', Include=relpath) + if len(objects) > 0: + # Do not add gen_objs to project file. Those are automatically used by MSBuild, because they are part of + # the CustomBuildStep Outputs. + inc_objs = ET.SubElement(root, 'ItemGroup') + for s in objects: + relpath = s.rel_to_builddir(proj_to_src_root) + ET.SubElement(inc_objs, 'Object', Include=relpath) ET.SubElement(root, 'Import', Project='$(VCTargetsPath)\Microsoft.Cpp.targets') # Reference the regen target. ig = ET.SubElement(root, 'ItemGroup') diff --git a/mesonbuild/environment.py b/mesonbuild/environment.py index c43c5e1..369ca20 100644 --- a/mesonbuild/environment.py +++ b/mesonbuild/environment.py @@ -58,7 +58,7 @@ class Environment(): log_dir = 'meson-logs' coredata_file = os.path.join(private_dir, 'coredata.dat') version_regex = '\d+(\.\d+)+(-[a-zA-Z0-9]+)?' - def __init__(self, source_dir, build_dir, main_script_file, options): + def __init__(self, source_dir, build_dir, main_script_file, options, original_cmd_line_args): assert(os.path.isabs(main_script_file)) assert(not os.path.islink(main_script_file)) self.source_dir = source_dir @@ -80,6 +80,7 @@ class Environment(): else: self.cross_info = None self.cmd_line_options = options + self.original_cmd_line_args = original_cmd_line_args # List of potential compilers. if mesonlib.is_windows(): @@ -153,6 +154,18 @@ class Environment(): def is_library(self, fname): return is_library(fname) + def had_argument_for(self, option): + trial1 = '--' + option + trial2 = '-D' + option + previous_is_plaind = False + for i in self.original_cmd_line_args: + if i.startswith(trial1) or i.startswith(trial2): + return True + if previous_is_plaind and i.startswith(option): + return True + previous_is_plaind = i == '-D' + return False + def merge_options(self, options): for (name, value) in options.items(): if name not in self.coredata.user_options: diff --git a/mesonbuild/interpreter.py b/mesonbuild/interpreter.py index 4d41f1a..b64eb7f 100644 --- a/mesonbuild/interpreter.py +++ b/mesonbuild/interpreter.py @@ -1331,7 +1331,7 @@ class Interpreter(): key, value = option.split('=', 1) builtin_options = self.coredata.builtin_options if key in builtin_options: - if not hasattr(self.environment.cmd_line_options, value): + if not self.environment.had_argument_for(key): self.coredata.set_builtin_option(key, value) # If this was set on the command line, do not override. else: diff --git a/mesonbuild/mconf.py b/mesonbuild/mconf.py index 67f2a91..03cbe55 100644 --- a/mesonbuild/mconf.py +++ b/mesonbuild/mconf.py @@ -123,6 +123,7 @@ class Conf: booleans = '[true, false]' carr.append(['buildtype', 'Build type', self.coredata.get_builtin_option('buildtype'), build_types]) carr.append(['warning_level', 'Warning level', self.coredata.get_builtin_option('warning_level'), warning_levels]) + carr.append(['werror', 'Treat warnings as errors', self.coredata.get_builtin_option('werror'), booleans]) carr.append(['strip', 'Strip on install', self.coredata.get_builtin_option('strip'), booleans]) carr.append(['coverage', 'Coverage report', self.coredata.get_builtin_option('coverage'), booleans]) carr.append(['use_pch', 'Precompiled headers', self.coredata.get_builtin_option('use_pch'), booleans]) diff --git a/mesonbuild/mesonmain.py b/mesonbuild/mesonmain.py index 774502b..1a7b084 100644 --- a/mesonbuild/mesonmain.py +++ b/mesonbuild/mesonmain.py @@ -79,7 +79,7 @@ parser.add_argument('directories', nargs='*') class MesonApp(): - def __init__(self, dir1, dir2, script_file, handshake, options): + def __init__(self, dir1, dir2, script_file, handshake, options, original_cmd_line_args): (self.source_dir, self.build_dir) = self.validate_dirs(dir1, dir2, handshake) if not os.path.isabs(options.prefix): raise RuntimeError('--prefix value \'{0}\' must be an absolute path: '.format(options.prefix)) @@ -92,6 +92,7 @@ class MesonApp(): options.prefix = options.prefix[:-1] self.meson_script_file = script_file self.options = options + self.original_cmd_line_args = original_cmd_line_args def has_build_file(self, dirname): fname = os.path.join(dirname, environment.build_filename) @@ -130,7 +131,7 @@ itself as required.''' return (src_dir, build_dir) def generate(self): - env = environment.Environment(self.source_dir, self.build_dir, self.meson_script_file, self.options) + env = environment.Environment(self.source_dir, self.build_dir, self.meson_script_file, self.options, self.original_cmd_line_args) mlog.initialize(env.get_log_dir()) mlog.debug('Build started at', datetime.datetime.now().isoformat()) mlog.debug('Python binary:', sys.executable) @@ -230,15 +231,22 @@ def run(mainfile, args): return 0 args = options.directories if len(args) == 0 or len(args) > 2: - print('{} <source directory> <build directory>'.format(sys.argv[0])) - print('If you omit either directory, the current directory is substituted.') - print('Run {} --help for more information.'.format(sys.argv[0])) - return 1 - dir1 = args[0] - if len(args) > 1: - dir2 = args[1] + # if there's a meson.build in the dir above, and not in the current + # directory, assume we're in the build directory + if len(args) == 0 and not os.path.exists('meson.build') and os.path.exists('../meson.build'): + dir1 = '..' + dir2 = '.' + else: + print('{} <source directory> <build directory>'.format(sys.argv[0])) + print('If you omit either directory, the current directory is substituted.') + print('Run {} --help for more information.'.format(sys.argv[0])) + return 1 else: - dir2 = '.' + dir1 = args[0] + if len(args) > 1: + dir2 = args[1] + else: + dir2 = '.' while os.path.islink(mainfile): resolved = os.readlink(mainfile) if resolved[0] != '/': @@ -246,7 +254,7 @@ def run(mainfile, args): else: mainfile = resolved try: - app = MesonApp(dir1, dir2, mainfile, handshake, options) + app = MesonApp(dir1, dir2, mainfile, handshake, options, sys.argv) except Exception as e: # Log directory does not exist, so just print # to stdout. diff --git a/run_tests.py b/run_tests.py index 331af7e..e85a6d6 100755 --- a/run_tests.py +++ b/run_tests.py @@ -207,8 +207,8 @@ def run_test(testdir, extra_args, should_succeed): stdout=subprocess.PIPE, stderr=subprocess.PIPE) (o, e) = pc.communicate() build_time = time.time() - build_start - stdo += o.decode('utf-8') - stde += e.decode('utf-8') + stdo += o.decode(sys.stdout.encoding) + stde += e.decode(sys.stdout.encoding) if pc.returncode != 0: return TestResult('Compiling source code failed.', stdo, stde, gen_time, build_time) test_start = time.time() @@ -230,8 +230,8 @@ def run_test(testdir, extra_args, should_succeed): pi = subprocess.Popen(install_commands, cwd=test_build_dir, env=env, stdout=subprocess.PIPE, stderr=subprocess.PIPE) (o, e) = pi.communicate() - stdo += o.decode('utf-8') - stde += e.decode('utf-8') + stdo += o.decode(sys.stdout.encoding) + stde += e.decode(sys.stdout.encoding) if pi.returncode != 0: return TestResult('Running install failed.', stdo, stde, gen_time, build_time, test_time) return TestResult(validate_install(testdir, install_dir), stdo, stde, gen_time, build_time, test_time) diff --git a/test cases/common/106 subproject subdir/meson.build b/test cases/common/106 subproject subdir/meson.build new file mode 100644 index 0000000..ec9fad1 --- /dev/null +++ b/test cases/common/106 subproject subdir/meson.build @@ -0,0 +1,6 @@ +project('proj', 'c') +subproject('sub') +libSub = dependency('sub', fallback: ['sub', 'libSub']) + +exe = executable('prog', 'prog.c', dependencies: libSub) +test('subproject subdir', exe) diff --git a/test cases/common/106 subproject subdir/prog.c b/test cases/common/106 subproject subdir/prog.c new file mode 100644 index 0000000..02ae337 --- /dev/null +++ b/test cases/common/106 subproject subdir/prog.c @@ -0,0 +1,5 @@ +#include <sub.h> + +int main() { + return sub(); +} diff --git a/test cases/common/106 subproject subdir/subprojects/sub/lib/meson.build b/test cases/common/106 subproject subdir/subprojects/sub/lib/meson.build new file mode 100644 index 0000000..731d22b --- /dev/null +++ b/test cases/common/106 subproject subdir/subprojects/sub/lib/meson.build @@ -0,0 +1,2 @@ +lib = static_library('sub', 'sub.c') +libSub = declare_dependency(include_directories: include_directories('.'), link_with: lib) diff --git a/test cases/common/106 subproject subdir/subprojects/sub/lib/sub.c b/test cases/common/106 subproject subdir/subprojects/sub/lib/sub.c new file mode 100644 index 0000000..3291e3c --- /dev/null +++ b/test cases/common/106 subproject subdir/subprojects/sub/lib/sub.c @@ -0,0 +1,5 @@ +#include "sub.h" + +int sub() { + return 0; +} diff --git a/test cases/common/106 subproject subdir/subprojects/sub/lib/sub.h b/test cases/common/106 subproject subdir/subprojects/sub/lib/sub.h new file mode 100644 index 0000000..f1ab0e1 --- /dev/null +++ b/test cases/common/106 subproject subdir/subprojects/sub/lib/sub.h @@ -0,0 +1,6 @@ +#ifndef SUB_H +#define SUB_H + +int sub(); + +#endif diff --git a/test cases/common/106 subproject subdir/subprojects/sub/meson.build b/test cases/common/106 subproject subdir/subprojects/sub/meson.build new file mode 100644 index 0000000..bf69c25 --- /dev/null +++ b/test cases/common/106 subproject subdir/subprojects/sub/meson.build @@ -0,0 +1,2 @@ +project('sub', 'c') +subdir('lib') diff --git a/test cases/common/59 object generator/obj_generator.py b/test cases/common/59 object generator/obj_generator.py index 6960059..204f1eb 100755 --- a/test cases/common/59 object generator/obj_generator.py +++ b/test cases/common/59 object generator/obj_generator.py @@ -12,7 +12,7 @@ if __name__ == '__main__': ifile = sys.argv[2] ofile = sys.argv[3] if compiler.endswith('cl'): - cmd = [compiler, '/nologo', '/Fo'+ofile, '/c', ifile] + cmd = [compiler, '/nologo', '/MDd', '/Fo'+ofile, '/c', ifile] else: cmd = [compiler, '-c', ifile, '-o', ofile] sys.exit(subprocess.call(cmd)) |