From c0bf3e8d46ff57d334331d9dadb6e4d064b4e1ec Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Thu, 3 Sep 2015 19:52:21 +0300 Subject: Create symlinks only once during configuration. --- ninjabackend.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 064e46c..8e87b13 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -258,7 +258,8 @@ class NinjaBackend(backends.Backend): obj_list.append(self.generate_single_compile(target, outfile, src, True, unity_deps + header_deps)) linker = self.determine_linker(target, src_list) elem = self.generate_link(target, outfile, outname, obj_list, linker, pch_objects) - self.generate_shlib_aliases(target, self.get_target_dir(target), outfile, elem) + self.generate_shlib_aliases(target, self.get_target_dir(target)) + elem.write(outfile) self.processed_targets[name] = True def process_target_dependencies(self, target, outfile): @@ -1376,19 +1377,20 @@ rule FORTRAN_DEP_HACK return os.path.join(self.get_target_private_dir(t), self.get_target_filename(t) + '.symbols') return self.get_target_filename(t) - def generate_shlib_aliases(self, target, outdir, outfile, elem): + def generate_shlib_aliases(self, target, outdir): basename = target.get_filename() aliases = target.get_aliaslist() aliascmd = [] if shutil.which('ln'): for alias in aliases: - aliasfile = os.path.join(outdir, alias) - cmd = ["&&", 'ln', '-s', '-f', basename, aliasfile] - aliascmd += cmd + aliasfile = os.path.join(self.environment.get_build_dir(), outdir, alias) + try: + os.remove(aliasfile) + except Exception: + pass + os.symlink(basename, aliasfile) else: - mlog.log("Library versioning disabled because host does not support symlinks.") - elem.add_item('aliasing', aliascmd) - elem.write(outfile) + mlog.debug("Library versioning disabled because host does not support symlinks.") def generate_gcov_clean(self, outfile): gcno_elem = NinjaBuildElement('clean-gcno', 'CUSTOM_COMMAND', 'PHONY') -- cgit v1.1 From 2c5688445bfc8a98972d380c17227ec9da0588ae Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sat, 5 Sep 2015 01:32:10 +0300 Subject: Created iphone cross file and made it possible to specify compile and link args in the cross file. --- ninjabackend.py | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 8e87b13..be4277d 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -815,11 +815,17 @@ class NinjaBackend(backends.Backend): langname == 'rust' or langname == 'cs': continue crstr = '' + cross_args = [] if is_cross: crstr = '_CROSS' + try: + cross_args = self.environment.cross_info.config['properties'][langname + '_link_args'] + except KeyError: + pass rule = 'rule %s%s_LINKER\n' % (langname, crstr) - command = ' command = %s $ARGS %s $in $LINK_ARGS $aliasing\n' % \ + command = ' command = %s %s $ARGS %s $in $LINK_ARGS $aliasing\n' % \ (' '.join(compiler.get_linker_exelist()),\ + ' '.join(cross_args),\ ' '.join(compiler.get_linker_output_args('$out'))) description = ' description = Linking target $out' outfile.write(rule) @@ -940,8 +946,15 @@ rule FORTRAN_DEP_HACK if d != '$out' and d != '$in': d = qstr % d quoted_depargs.append(d) - command = " command = %s $ARGS %s %s %s $in\n" % \ + cross_args = [] + if is_cross: + try: + cross_args = self.environment.cross_info.config['properties'][langname + '_args'] + except KeyError: + pass + command = " command = %s %s $ARGS %s %s %s $in\n" % \ (' '.join(compiler.get_exelist()),\ + ' '.join(cross_args), ' '.join(quoted_depargs),\ ' '.join(compiler.get_output_args('$out')),\ ' '.join(compiler.get_compile_only_args())) @@ -966,6 +979,13 @@ rule FORTRAN_DEP_HACK crstr = '' rule = 'rule %s%s_PCH\n' % (langname, crstr) depargs = compiler.get_dependency_gen_args('$out', '$DEPFILE') + cross_args = [] + if is_cross: + try: + cross_args = self.environment.cross_info.config['properties'][langname + '_args'] + except KeyError: + pass + quoted_depargs = [] for d in depargs: if d != '$out' and d != '$in': @@ -975,8 +995,9 @@ rule FORTRAN_DEP_HACK output = '' else: output = ' '.join(compiler.get_output_args('$out')) - command = " command = %s $ARGS %s %s %s $in\n" % \ + command = " command = %s %s $ARGS %s %s %s $in\n" % \ (' '.join(compiler.get_exelist()),\ + ' '.join(cross_args),\ ' '.join(quoted_depargs),\ output,\ ' '.join(compiler.get_compile_only_args())) -- cgit v1.1 From 4dd6a85075703733f1f610df650b82879b911be7 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 6 Sep 2015 16:35:55 +0300 Subject: Fix Windows again. --- ninjabackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index be4277d..0bc500d 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -1402,7 +1402,7 @@ rule FORTRAN_DEP_HACK basename = target.get_filename() aliases = target.get_aliaslist() aliascmd = [] - if shutil.which('ln'): + if not mesonlib.is_windows(): for alias in aliases: aliasfile = os.path.join(self.environment.get_build_dir(), outdir, alias) try: -- cgit v1.1 From 776f899e78e88600f34176ef4088c32208802777 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sun, 6 Sep 2015 18:38:27 +0300 Subject: Made boost on windows kinda work. --- ninjabackend.py | 1 - 1 file changed, 1 deletion(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 0bc500d..ebf0a94 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -1401,7 +1401,6 @@ rule FORTRAN_DEP_HACK def generate_shlib_aliases(self, target, outdir): basename = target.get_filename() aliases = target.get_aliaslist() - aliascmd = [] if not mesonlib.is_windows(): for alias in aliases: aliasfile = os.path.join(self.environment.get_build_dir(), outdir, alias) -- cgit v1.1 From 4e8c4035e53dc2fca255b0e80f5e1390a8b40607 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 11 Sep 2015 00:22:56 +0300 Subject: Can have built binaries in run_targets. Closes #264. --- ninjabackend.py | 29 ++++++++++++++++++++++++++--- 1 file changed, 26 insertions(+), 3 deletions(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index ebf0a94..3e15a31 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -312,9 +312,32 @@ class NinjaBackend(backends.Backend): def generate_run_target(self, target, outfile): runnerscript = os.path.join(self.environment.get_script_dir(), 'commandrunner.py') - elem = NinjaBuildElement(target.name, 'CUSTOM_COMMAND', []) - cmd = [sys.executable, runnerscript, self.environment.get_source_dir(), self.environment.get_build_dir(), - target.subdir, target.command] + target.args + deps = [] + arg_strings = [] + for i in target.args: + if isinstance(i, str): + arg_strings.append(i) + elif isinstance(i, build.BuildTarget): + deps.append(self.get_target_filename(i)) + else: + raise MesonException('Unreachable code.') + elem = NinjaBuildElement(target.name, 'CUSTOM_COMMAND', deps) + cmd = [sys.executable, runnerscript, self.environment.get_source_dir(), self.environment.get_build_dir(), target.subdir] + texe = target.command + try: + texe = texe.held_object + except AttributeError: + pass + if isinstance(texe, build.Executable): + deps.append(self.get_target_filename(texe)) + if self.environment.is_cross_build() \ + and wrapper is not self.environment.cross_info.config['binaries'].get('exe_wrapper', None): + cmd += [self.environment.cross_info.config['binaries']['exe_wrapper'], self.get_target_filename(texe)] + else: + cmd += [os.path.join(self.environment.get_build_dir(), self.get_target_filename(texe))] + else: + cmd.append(target.command) + cmd += target.args elem.add_item('COMMAND', cmd) elem.add_item('description', 'Running external command %s.' % target.name) elem.add_item('pool', 'console') -- cgit v1.1 From 840acdd0284984f258987e37bc8cf6b8329a7d2e Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 11 Sep 2015 19:10:28 +0300 Subject: Fix. --- ninjabackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 3e15a31..337528f 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -331,7 +331,7 @@ class NinjaBackend(backends.Backend): if isinstance(texe, build.Executable): deps.append(self.get_target_filename(texe)) if self.environment.is_cross_build() \ - and wrapper is not self.environment.cross_info.config['binaries'].get('exe_wrapper', None): + and self.environment.cross_info.config['binaries'].get('exe_wrapper', None) is not None: cmd += [self.environment.cross_info.config['binaries']['exe_wrapper'], self.get_target_filename(texe)] else: cmd += [os.path.join(self.environment.get_build_dir(), self.get_target_filename(texe))] -- cgit v1.1 From 33217038b4cfe89b0e6f023b268d00182bee2717 Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 11 Sep 2015 22:02:24 +0300 Subject: Put full path to exe_wrapped run targets in case the runner script assumes that the runnable binary needs to be in PATH. --- ninjabackend.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 337528f..0d07dc0 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -329,12 +329,12 @@ class NinjaBackend(backends.Backend): except AttributeError: pass if isinstance(texe, build.Executable): + abs_exe = os.path.join(self.environment.get_build_dir(), self.get_target_filename(texe)) deps.append(self.get_target_filename(texe)) if self.environment.is_cross_build() \ and self.environment.cross_info.config['binaries'].get('exe_wrapper', None) is not None: - cmd += [self.environment.cross_info.config['binaries']['exe_wrapper'], self.get_target_filename(texe)] - else: - cmd += [os.path.join(self.environment.get_build_dir(), self.get_target_filename(texe))] + cmd += [self.environment.cross_info.config['binaries']['exe_wrapper']] + cmd.append(abs_exe) else: cmd.append(target.command) cmd += target.args -- cgit v1.1 From 2e585856be042bf5caa2b45d07557405278ee3ae Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Fri, 11 Sep 2015 23:24:56 +0300 Subject: Prevent generation of Ninja files with target ambiguities. --- ninjabackend.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index 0d07dc0..bf8085a 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -114,6 +114,13 @@ class NinjaBackend(backends.Backend): self.source_suffix_in_objs = True self.ninja_filename = 'build.ninja' self.fortran_deps = {} + self.all_outputs = {} + + def check_outputs(self, elem): + for n in elem.outfilenames: + if n in self.all_outputs: + raise MesonException('Multiple producers for Ninja target "%s". Please rename your targets.' % n) + self.all_outputs[n] = True def generate(self): outfilename = os.path.join(self.environment.get_build_dir(), self.ninja_filename) @@ -308,6 +315,7 @@ class NinjaBackend(backends.Backend): elem.add_item('COMMAND', cmd) elem.add_item('description', 'Generating %s with a custom command.' % target.name) elem.write(outfile) + self.check_outputs(elem) self.processed_targets[target.name + target.type_suffix()] = True def generate_run_target(self, target, outfile): @@ -342,6 +350,7 @@ class NinjaBackend(backends.Backend): elem.add_item('description', 'Running external command %s.' % target.name) elem.add_item('pool', 'console') elem.write(outfile) + self.check_outputs(elem) self.processed_targets[target.name + target.type_suffix()] = True def generate_po(self, outfile): @@ -354,6 +363,7 @@ class NinjaBackend(backends.Backend): elem.add_item('FILELIST', os.path.join(self.environment.get_source_dir(), input_file)) elem.add_item('OUTDIR', os.path.join(self.environment.get_source_dir(), subdir)) elem.write(outfile) + self.check_outputs(elem) for l in languages: infile = os.path.join(self.environment.get_source_dir(), subdir, l + '.po') outfilename = os.path.join(subdir, l + '.gmo') @@ -361,6 +371,7 @@ class NinjaBackend(backends.Backend): lelem.add_item('INFILE', infile) lelem.add_item('OUTFILE', outfilename) lelem.write(outfile) + self.check_outputs(lelem) def generate_coverage_rules(self, outfile): (gcovr_exe, lcov_exe, genhtml_exe) = environment.find_coverage_tools() @@ -377,6 +388,7 @@ class NinjaBackend(backends.Backend): '-o', os.path.join(self.environment.get_log_dir(), 'coverage.txt')]) elem.add_item('DESC', 'Generating text coverage report.') elem.write(outfile) + self.check_outputs(elem) if lcov_exe and genhtml_exe: added_rule = True phony_elem = NinjaBuildElement('coverage-html', 'phony', 'coveragereport/index.html') @@ -390,6 +402,7 @@ class NinjaBackend(backends.Backend): '--legend', '--show-details', 'coverage.info'] elem.add_item('COMMAND', command) elem.add_item('DESC', 'Generating HTML coverage report.') + self.check_outputs(elem) elem.write(outfile) if not added_rule: mlog.log(mlog.red('Warning:'), 'coverage requested but neither gcovr nor lcov/genhtml found.') @@ -417,6 +430,7 @@ class NinjaBackend(backends.Backend): self.generate_custom_install_script(d) self.generate_subdir_install(d) elem.write(outfile) + self.check_outputs(elem) ofile = open(install_data_file, 'wb') pickle.dump(d, ofile) @@ -523,6 +537,7 @@ class NinjaBackend(backends.Backend): elem.add_item('DESC', 'Running test suite.') elem.add_item('pool', 'console') elem.write(outfile) + self.check_outputs(elem) if valgrind: velem = NinjaBuildElement('test-valgrind', 'CUSTOM_COMMAND', ['all', 'PHONY']) @@ -530,6 +545,7 @@ class NinjaBackend(backends.Backend): velem.add_item('DESC', 'Running test suite under Valgrind.') velem.add_item('pool', 'console') velem.write(outfile) + self.check_outputs(elem) def generate_rules(self, outfile): outfile.write('# Rules for compiling.\n\n') @@ -606,6 +622,7 @@ class NinjaBackend(backends.Backend): elem.add_dep([os.path.join(self.get_target_private_dir(target), i) for i in class_list]) elem.add_item('ARGS', commands) elem.write(outfile) + self.check_outputs(elem) def generate_cs_resource_tasks(self, target, outfile): args = [] @@ -621,6 +638,7 @@ class NinjaBackend(backends.Backend): elem.add_item('COMMAND', ['resgen', rel_sourcefile, ofilename]) elem.add_item('DESC', 'Compiling resource %s.' % rel_sourcefile) elem.write(outfile) + self.check_outputs(elem) deps.append(ofilename) a = '-resource:' + ofilename else: @@ -660,6 +678,7 @@ class NinjaBackend(backends.Backend): elem = NinjaBuildElement(outputs, 'cs_COMPILER', rel_srcs) elem.add_dep(deps) elem.add_item('ARGS', commands) + self.check_outputs(elem) elem.write(outfile) def generate_single_java_compile(self, subdir, src, target, compiler, outfile): @@ -672,6 +691,7 @@ class NinjaBackend(backends.Backend): element = NinjaBuildElement(rel_obj, compiler.get_language() + '_COMPILER', rel_src) element.add_item('ARGS', args) element.write(outfile) + self.check_outputs(element) return plain_class_path def generate_java_link(self, outfile): @@ -695,6 +715,7 @@ class NinjaBackend(backends.Backend): element = NinjaBuildElement(rel_vapi, valac.get_language() + '_COMPILER', rel_s) element.add_item('ARGS', args) element.write(outfile) + self.check_outputs(element) fastvapis[s] = (vapibase, rel_vapi) return fastvapis @@ -757,6 +778,7 @@ class NinjaBackend(backends.Backend): element.add_orderdep(vapi_order_deps) element.add_dep(extra_dep_files) element.write(outfile) + self.check_outputs(element) return generated_c def generate_rust_target(self, target, outfile): @@ -796,6 +818,7 @@ class NinjaBackend(backends.Backend): element.add_item('targetdep', depfile) element.add_item('cratetype', cratetype) element.write(outfile) + self.check_outputs(element) def generate_static_link_rules(self, is_cross, outfile): if self.build.has_language('java'): @@ -1113,6 +1136,7 @@ rule FORTRAN_DEP_HACK elem.add_dep(self.get_target_filename(exe)) elem.add_item('COMMAND', cmdlist) elem.write(outfile) + self.check_outputs(elem) def scan_fortran_module_outputs(self, target): compiler = None @@ -1252,6 +1276,7 @@ rule FORTRAN_DEP_HACK if srcfile == src: depelem = NinjaBuildElement(modfile, 'FORTRAN_DEP_HACK', rel_obj) depelem.write(outfile) + self.check_outputs(depelem) commands += compiler.get_module_outdir_args(self.get_target_private_dir(target)) element = NinjaBuildElement(rel_obj, compiler_name, rel_src) @@ -1276,6 +1301,7 @@ rule FORTRAN_DEP_HACK element.add_item('DEPFILE', dep_file) element.add_item('ARGS', commands) element.write(outfile) + self.check_outputs(element) return rel_obj # Fortran is a bit weird (again). When you link against a library, just compiling a source file @@ -1341,6 +1367,7 @@ rule FORTRAN_DEP_HACK elem.add_item('ARGS', commands) elem.add_item('DEPFILE', dep) elem.write(outfile) + self.check_outputs(elem) return pch_objects def generate_shsym(self, outfile, target): @@ -1351,6 +1378,7 @@ rule FORTRAN_DEP_HACK if self.environment.is_cross_build() and self.environment.cross_info.need_cross_compiler(): elem.add_item('CROSS', '--cross-host=' + self.environment.cross_info.config['host_machine']['system']) elem.write(outfile) + self.check_outputs(elem) def generate_link(self, target, outfile, outname, obj_list, linker, extra_args=[]): if isinstance(target, build.StaticLibrary): @@ -1414,6 +1442,7 @@ rule FORTRAN_DEP_HACK elem = NinjaBuildElement(outname, linker_rule, obj_list) elem.add_dep(dep_targets) elem.add_item('LINK_ARGS', commands) + self.check_outputs(elem) return elem def get_dependency_filename(self, t): @@ -1442,6 +1471,7 @@ rule FORTRAN_DEP_HACK gcno_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcno']) gcno_elem.add_item('description', 'Deleting gcno files') gcno_elem.write(outfile) + self.check_outputs(elem, gcno_elem) gcda_elem = NinjaBuildElement('clean-gcda', 'CUSTOM_COMMAND', 'PHONY') script_root = self.environment.get_script_dir() @@ -1449,6 +1479,7 @@ rule FORTRAN_DEP_HACK gcda_elem.add_item('COMMAND', [sys.executable, clean_script, '.', 'gcda']) gcda_elem.add_item('description', 'Deleting gcda files') gcda_elem.write(outfile) + self.check_outputs(gcda_elem) def is_compilable_file(self, filename): if filename.endswith('.cpp') or\ @@ -1474,6 +1505,7 @@ rule FORTRAN_DEP_HACK infilename = os.path.join(self.build_to_src, target.get_source_subdir(), src) elem = NinjaBuildElement(outfilename, rule.name, infilename) elem.write(outfile) + self.check_outputs(elem) if self.is_compilable_file(outfilename): src_deps.append(outfilename) else: @@ -1486,6 +1518,7 @@ rule FORTRAN_DEP_HACK elem = NinjaBuildElement('all', 'phony', targetlist) elem.write(outfile) + self.check_outputs(elem) default = 'default all\n\n' outfile.write(default) @@ -1501,6 +1534,7 @@ rule FORTRAN_DEP_HACK elem.add_dep('clean-gcda') elem.add_dep('clean-gcno') elem.write(outfile) + self.check_outputs(elem) deps = [os.path.join(self.build_to_src, df) \ for df in self.interpreter.get_build_def_files()] @@ -1520,3 +1554,4 @@ rule FORTRAN_DEP_HACK elem = NinjaBuildElement(deps, 'phony', '') elem.write(outfile) + self.check_outputs(elem) -- cgit v1.1 From b8b50020f06cb28f6277b3f75cd52afe6f766dfe Mon Sep 17 00:00:00 2001 From: Jussi Pakkanen Date: Sat, 12 Sep 2015 21:28:29 +0300 Subject: Check correct output element. --- ninjabackend.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ninjabackend.py') diff --git a/ninjabackend.py b/ninjabackend.py index bf8085a..b2d5d00 100644 --- a/ninjabackend.py +++ b/ninjabackend.py @@ -545,7 +545,7 @@ class NinjaBackend(backends.Backend): velem.add_item('DESC', 'Running test suite under Valgrind.') velem.add_item('pool', 'console') velem.write(outfile) - self.check_outputs(elem) + self.check_outputs(velem) def generate_rules(self, outfile): outfile.write('# Rules for compiling.\n\n') -- cgit v1.1