|
|
|
@ -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) |
|
|
|
|