aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/backend
diff options
context:
space:
mode:
authorJussi Pakkanen <jpakkane@gmail.com>2016-10-01 15:41:46 -0400
committerGitHub <noreply@github.com>2016-10-01 15:41:46 -0400
commit6ec1e990430a1958a35401a2b2e82e28edeb3b48 (patch)
tree305387c4d1978a102fcf344c6855ad80289f2523 /mesonbuild/backend
parentda57f77394d72c1103da84037312617a9ee7b99f (diff)
parent3be01a7e7b13f2bb759b32c77f35db576c3cff9a (diff)
downloadmeson-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.py1
-rw-r--r--mesonbuild/backend/ninjabackend.py87
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)