From ca507cdcdf59977ef4304f70dcca8f048bfd4afc Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 23 Sep 2016 06:25:50 +0530 Subject: [PATCH 1/7] ninja: Add a str and repr methods for RawFilename This aids debugging immensely --- mesonbuild/backend/ninjabackend.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 251f7ee6a..e57e9aa69 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -38,6 +38,12 @@ class RawFilename(): def __init__(self, fname): self.fname = fname + def __str__(self): + return self.fname + + def __repr__(self): + return ''.format(self.fname) + def split(self, c): return self.fname.split(c) From cfbffc6ba1dde802a06ab591d53f74cbb274010b Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 23 Sep 2016 06:28:41 +0530 Subject: [PATCH 2/7] ninja: Fix header deps of generated source compiles Because we were iterating over all generated sources of a target in one go, we weren't adding the correct header_deps for generated source compiles. We need to aggregate the header_deps first before generating source compile targets for generated source files. --- mesonbuild/backend/ninjabackend.py | 31 ++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index e57e9aa69..8663dfe33 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -270,18 +270,25 @@ int dummy; unity_src = [] unity_deps = [] # Generated sources that must be built before compiling a Unity target. header_deps += self.get_generated_headers(target) - generator_output_sources = [] # Needed to determine the linker + + # Get a list of all generated *sources* (sources files, headers, + # objects, etc). Needed to determine the linker. + generated_output_sources = [] + # Get a list of all generated headers that will be needed while building + # this target's sources (generated sources and pre-existing sources). + # This will be set as dependencies of all the target's sources. At the + # same time, also deal with generated sources that need to be compiled. + generated_source_files = [] for gensource in target.get_generated_sources(): if isinstance(gensource, build.CustomTarget): for src in gensource.output: src = os.path.join(self.get_target_dir(gensource), src) - generator_output_sources.append(src) + generated_output_sources.append(src) if self.environment.is_source(src) and not self.environment.is_header(src): if is_unity: unity_deps.append(os.path.join(self.environment.get_build_dir(), RawFilename(src))) else: - obj_list.append(self.generate_single_compile(target, outfile, RawFilename(src), True, - header_deps)) + generated_source_files.append(RawFilename(src)) elif self.environment.is_object(src): obj_list.append(src) elif self.environment.is_library(src): @@ -293,7 +300,7 @@ int dummy; header_deps.append(RawFilename(src)) else: for src in gensource.get_outfilelist(): - generator_output_sources.append(src) + generated_output_sources.append(src) if self.environment.is_object(src): obj_list.append(os.path.join(self.get_target_private_dir(target), src)) elif not self.environment.is_header(src): @@ -306,8 +313,15 @@ int dummy; abs_src = os.path.join(self.environment.get_build_dir(), rel_src) unity_src.append(abs_src) else: - obj_list.append(self.generate_single_compile(target, outfile, src, True, - header_deps=header_deps)) + generated_source_files.append(src) + # These are the generated source files that need to be built for use by + # this target. We create the Ninja build file elements for this here + # because we need `header_deps` to be fully generated in the above loop. + for src in generated_source_files: + obj_list.append(self.generate_single_compile(target, outfile, src, True, + header_deps=header_deps)) + # Generate compilation targets for sources belonging to this target that + # are generated by other rules (this is only used for Vala right now) src_list = [] for src in gen_src_deps: src_list.append(src) @@ -324,6 +338,7 @@ int dummy; header_deps.append(src) else: obj_list.append(self.generate_single_compile(target, outfile, src, True, [], header_deps)) + # Generate compile targets for all the pre-existing sources for this target for src in target.get_sources(): if src.endswith('.vala'): continue @@ -339,7 +354,7 @@ int dummy; if is_unity: for src in self.generate_unity_files(target, unity_src): obj_list.append(self.generate_single_compile(target, outfile, src, True, unity_deps + header_deps)) - linker = self.determine_linker(target, src_list + generator_output_sources) + linker = self.determine_linker(target, src_list + generated_output_sources) elem = self.generate_link(target, outfile, outname, obj_list, linker, pch_objects) self.generate_shlib_aliases(target, self.get_target_dir(target)) elem.write(outfile) From f5caf40f661485c3a814907f10ef630129300d57 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 23 Sep 2016 06:56:09 +0530 Subject: [PATCH 3/7] ninja: Also add generated sources to the source list The generated sources should also be used for determining the linker --- mesonbuild/backend/ninjabackend.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 8663dfe33..71b37cf41 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -270,6 +270,7 @@ int dummy; unity_src = [] unity_deps = [] # Generated sources that must be built before compiling a Unity target. header_deps += self.get_generated_headers(target) + src_list = [] # Get a list of all generated *sources* (sources files, headers, # objects, etc). Needed to determine the linker. @@ -318,11 +319,11 @@ int dummy; # this target. We create the Ninja build file elements for this here # because we need `header_deps` to be fully generated in the above loop. for src in generated_source_files: + src_list.append(src) obj_list.append(self.generate_single_compile(target, outfile, src, True, header_deps=header_deps)) # Generate compilation targets for sources belonging to this target that # are generated by other rules (this is only used for Vala right now) - src_list = [] for src in gen_src_deps: src_list.append(src) if is_unity: From e713aca1d13116a1b951925f5e7d86532a0ed305 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 23 Sep 2016 06:57:20 +0530 Subject: [PATCH 4/7] backends: Remove self.dep_rules dead code self.dep_rules is not set anywhere by anything, so this code always results in a no-op. If it didn't result in a no-op, it would need to be seriously rewritten because it has bitrotten and makes no sense anymore. --- mesonbuild/backend/backends.py | 1 - mesonbuild/backend/ninjabackend.py | 35 +----------------------------- 2 files changed, 1 insertion(+), 35 deletions(-) diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 4139aceba..efddf7bc8 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -72,7 +72,6 @@ class Backend(): self.build = build self.environment = build.environment self.processed_targets = {} - self.dep_rules = {} self.build_to_src = os.path.relpath(self.environment.get_source_dir(), self.environment.get_build_dir()) for t in self.build.targets: diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 71b37cf41..b54fc759d 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -253,9 +253,6 @@ int dummy; self.generate_swift_target(target, outfile) return self.scan_fortran_module_outputs(target) - # The following deals with C/C++ compilation. - (gen_src, gen_other_deps) = self.process_dep_gens(outfile, target) - gen_src_deps += gen_src self.process_target_dependencies(target, outfile) self.generate_custom_generator_rules(target, outfile) outname = self.get_target_filename(target) @@ -266,7 +263,7 @@ int dummy; pch_objects = self.generate_pch(target, outfile) else: pch_objects = [] - header_deps = gen_other_deps + header_deps = [] unity_src = [] unity_deps = [] # Generated sources that must be built before compiling a Unity target. header_deps += self.get_generated_headers(target) @@ -1912,36 +1909,6 @@ rule FORTRAN_DEP_HACK gcda_elem.add_item('description', 'Deleting gcda files') gcda_elem.write(outfile) - def is_compilable_file(self, filename): - if filename.endswith('.cpp') or\ - filename.endswith('.c') or\ - filename.endswith('.cxx') or\ - filename.endswith('.cc') or\ - filename.endswith('.C'): - return True - return False - - def process_dep_gens(self, outfile, target): - src_deps = [] - other_deps = [] - for rule in self.dep_rules.values(): - srcs = target.get_original_kwargs().get(rule.src_keyword, []) - if isinstance(srcs, str): - srcs = [srcs] - for src in srcs: - plainname = os.path.split(src)[1] - basename = plainname.split('.')[0] - outname = rule.name_templ.replace('@BASENAME@', basename).replace('@PLAINNAME@', plainname) - outfilename = os.path.join(self.get_target_private_dir(target), outname) - infilename = os.path.join(self.build_to_src, target.get_source_subdir(), src) - elem = NinjaBuildElement(self.all_outputs, outfilename, rule.name, infilename) - elem.write(outfile) - if self.is_compilable_file(outfilename): - src_deps.append(outfilename) - else: - other_deps.append(outfilename) - return (src_deps, other_deps) - # For things like scan-build and other helper tools we might have. def generate_utils(self, outfile): cmd = [sys.executable, self.environment.get_build_command(), From 9d1aeebc27c5077ede5f47463e66f184529c03f0 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 23 Sep 2016 14:18:21 +0530 Subject: [PATCH 5/7] ninja: Don't add every CustomTarget to 'all' Otherwise they are built regardless of whether they are actually used by anything else. Only build them if they're going to be installed or always-built. Ideally, we should also do this with all BuildTargets, and provide a mechanism for people to specify which targets they want built with 'all', and a way for people to add them to custom targets.. Without this, things like tests and examples are *always* built with no way to turn that off. For now, we just do this because it also with tests that check for dependency issues. Including all CustomTargets in `all` results in dangling targets to also be built, which hides the problem and makes it racy. --- mesonbuild/backend/ninjabackend.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index b54fc759d..930d37f9e 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -1920,8 +1920,16 @@ rule FORTRAN_DEP_HACK elem.write(outfile) def generate_ending(self, outfile): - targetlist = [self.get_target_filename(t) for t in self.build.get_targets().values()\ - if not isinstance(t, build.RunTarget)] + targetlist = [] + for t in self.build.get_targets().values(): + # RunTargets are meant to be invoked manually + if isinstance(t, build.RunTarget): + continue + # CustomTargets that aren't installed should only be built if they + # are used by something else or are meant to be always built + if isinstance(t, build.CustomTarget) and not (t.install or t.build_always): + continue + targetlist.append(self.get_target_filename(t)) elem = NinjaBuildElement(self.all_outputs, 'all', 'phony', targetlist) elem.write(outfile) From d3e73e0dbc28939953cc5c7e3f928e05557838a1 Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 23 Sep 2016 14:39:11 +0530 Subject: [PATCH 6/7] tests/7 gnome: Add a dependency on the compiled schemas The executable needs to pull in the compiled schemas or they won't be compiled. --- test cases/frameworks/7 gnome/schemas/meson.build | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test cases/frameworks/7 gnome/schemas/meson.build b/test cases/frameworks/7 gnome/schemas/meson.build index b4765b6ec..194760480 100644 --- a/test cases/frameworks/7 gnome/schemas/meson.build +++ b/test cases/frameworks/7 gnome/schemas/meson.build @@ -1,8 +1,8 @@ -gnome.compile_schemas() +compiled = gnome.compile_schemas() install_data('com.github.meson.gschema.xml', install_dir : 'share/glib-2.0/schemas') -schemaexe = executable('schemaprog', 'schemaprog.c', +schemaexe = executable('schemaprog', 'schemaprog.c', compiled, dependencies : gio) test('schema test', schemaexe) From 3be01a7e7b13f2bb759b32c77f35db576c3cff9a Mon Sep 17 00:00:00 2001 From: Nirbheek Chauhan Date: Fri, 23 Sep 2016 08:02:11 +0530 Subject: [PATCH 7/7] Add a test for generated header deps of generated sources --- test cases/common/95 dep fallback/gensrc.py | 6 ++++++ test cases/common/95 dep fallback/meson.build | 11 ++++++++++- .../common/95 dep fallback/subprojects/boblib/bob.c | 3 +++ .../common/95 dep fallback/subprojects/boblib/bob.h | 3 +++ .../95 dep fallback/subprojects/boblib/genbob.py | 7 +++++++ .../95 dep fallback/subprojects/boblib/meson.build | 11 ++++++++++- test cases/common/95 dep fallback/tester.c | 1 + 7 files changed, 40 insertions(+), 2 deletions(-) create mode 100644 test cases/common/95 dep fallback/gensrc.py create mode 100644 test cases/common/95 dep fallback/subprojects/boblib/genbob.py diff --git a/test cases/common/95 dep fallback/gensrc.py b/test cases/common/95 dep fallback/gensrc.py new file mode 100644 index 000000000..da503e27c --- /dev/null +++ b/test cases/common/95 dep fallback/gensrc.py @@ -0,0 +1,6 @@ +#!/usr/bin/env python + +import sys +import shutil + +shutil.copyfile(sys.argv[1], sys.argv[2]) diff --git a/test cases/common/95 dep fallback/meson.build b/test cases/common/95 dep fallback/meson.build index 4cf0577ae..13541f2af 100644 --- a/test cases/common/95 dep fallback/meson.build +++ b/test cases/common/95 dep fallback/meson.build @@ -6,5 +6,14 @@ if not bob.found() endif jimmy = dependency('jimmylib', fallback : ['jimmylib', 'jimmy_dep'], required: false) -exe = executable('bobtester', 'tester.c', dependencies : bob) +gensrc_py = find_program('gensrc.py') +gensrc = custom_target('gensrc.c', + input : 'tester.c', + output : 'gensrc.c', + command : [gensrc_py, '@INPUT@', '@OUTPUT@']) + +exe = executable('bobtester', + [gensrc], + dependencies : bob) + test('bobtester', exe) diff --git a/test cases/common/95 dep fallback/subprojects/boblib/bob.c b/test cases/common/95 dep fallback/subprojects/boblib/bob.c index b483a555a..ae0f394d5 100644 --- a/test cases/common/95 dep fallback/subprojects/boblib/bob.c +++ b/test cases/common/95 dep fallback/subprojects/boblib/bob.c @@ -1,5 +1,8 @@ #include"bob.h" +#ifdef _MSC_VER +__declspec(dllexport) +#endif const char* get_bob() { return "bob"; } diff --git a/test cases/common/95 dep fallback/subprojects/boblib/bob.h b/test cases/common/95 dep fallback/subprojects/boblib/bob.h index bc170efca..f874ae7c1 100644 --- a/test cases/common/95 dep fallback/subprojects/boblib/bob.h +++ b/test cases/common/95 dep fallback/subprojects/boblib/bob.h @@ -1,3 +1,6 @@ #pragma once +#ifdef _MSC_VER +__declspec(dllimport) +#endif const char* get_bob(); diff --git a/test cases/common/95 dep fallback/subprojects/boblib/genbob.py b/test cases/common/95 dep fallback/subprojects/boblib/genbob.py new file mode 100644 index 000000000..824194b0d --- /dev/null +++ b/test cases/common/95 dep fallback/subprojects/boblib/genbob.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python + +import os +import sys + +with open(sys.argv[1], 'w') as f: + f.write('') diff --git a/test cases/common/95 dep fallback/subprojects/boblib/meson.build b/test cases/common/95 dep fallback/subprojects/boblib/meson.build index 8dc1f3a1b..bb250e42f 100644 --- a/test cases/common/95 dep fallback/subprojects/boblib/meson.build +++ b/test cases/common/95 dep fallback/subprojects/boblib/meson.build @@ -1,7 +1,16 @@ project('bob', 'c') -boblib = static_library('bob', 'bob.c') +gensrc_py = find_program('genbob.py') +genbob_h = custom_target('genbob.h', + output : 'genbob.h', + command : [gensrc_py, '@OUTPUT@']) +genbob_c = custom_target('genbob.c', + output : 'genbob.c', + command : [gensrc_py, '@OUTPUT@']) + +boblib = library('bob', ['bob.c', genbob_c]) bobinc = include_directories('.') bob_dep = declare_dependency(link_with : boblib, + sources : [genbob_h], include_directories : bobinc) diff --git a/test cases/common/95 dep fallback/tester.c b/test cases/common/95 dep fallback/tester.c index 59e16352b..e6651d961 100644 --- a/test cases/common/95 dep fallback/tester.c +++ b/test cases/common/95 dep fallback/tester.c @@ -1,4 +1,5 @@ #include"bob.h" +#include"genbob.h" #include #include