diff options
author | Jussi Pakkanen <jpakkane@gmail.com> | 2016-10-01 15:41:46 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-01 15:41:46 -0400 |
commit | 6ec1e990430a1958a35401a2b2e82e28edeb3b48 (patch) | |
tree | 305387c4d1978a102fcf344c6855ad80289f2523 /mesonbuild/backend | |
parent | da57f77394d72c1103da84037312617a9ee7b99f (diff) | |
parent | 3be01a7e7b13f2bb759b32c77f35db576c3cff9a (diff) | |
download | meson-6ec1e990430a1958a35401a2b2e82e28edeb3b48.zip meson-6ec1e990430a1958a35401a2b2e82e28edeb3b48.tar.gz meson-6ec1e990430a1958a35401a2b2e82e28edeb3b48.tar.bz2 |
Merge pull request #803 from centricular/generated-sources-header-deps
ninja backend: Fix header deps of generated source compiles
Diffstat (limited to 'mesonbuild/backend')
-rw-r--r-- | mesonbuild/backend/backends.py | 1 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 87 |
2 files changed, 42 insertions, 46 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index ec897aa..d5af056 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 14aa496..6b6b4ea 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 '<RawFilename: {0}>'.format(self.fname) + def split(self, c): return self.fname.split(c) @@ -246,9 +252,6 @@ int dummy; vala_output_files = self.generate_vala_compile(target, outfile) gen_src_deps += vala_output_files 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) @@ -259,22 +262,30 @@ 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) - generator_output_sources = [] # Needed to determine the linker + src_list = [] + + # 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): @@ -286,7 +297,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): @@ -299,9 +310,16 @@ 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)) - src_list = [] + 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: + 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) for src in gen_src_deps: src_list.append(src) if is_unity: @@ -317,6 +335,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 @@ -332,7 +351,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) @@ -1898,36 +1917,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(), @@ -1939,8 +1928,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) |