aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--authors.txt1
-rw-r--r--mesonbuild/backend/backends.py6
-rw-r--r--mesonbuild/backend/vs2010backend.py47
-rw-r--r--mesonbuild/environment.py15
-rw-r--r--mesonbuild/interpreter.py2
-rw-r--r--mesonbuild/mconf.py1
-rw-r--r--mesonbuild/mesonmain.py30
-rwxr-xr-xrun_tests.py8
-rw-r--r--test cases/common/106 subproject subdir/meson.build6
-rw-r--r--test cases/common/106 subproject subdir/prog.c5
-rw-r--r--test cases/common/106 subproject subdir/subprojects/sub/lib/meson.build2
-rw-r--r--test cases/common/106 subproject subdir/subprojects/sub/lib/sub.c5
-rw-r--r--test cases/common/106 subproject subdir/subprojects/sub/lib/sub.h6
-rw-r--r--test cases/common/106 subproject subdir/subprojects/sub/meson.build2
-rwxr-xr-xtest cases/common/59 object generator/obj_generator.py2
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))