Merge pull request #803 from centricular/generated-sources-header-deps
ninja backend: Fix header deps of generated source compiles
This commit is contained in:
commit
6ec1e99043
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
import shutil
|
||||
|
||||
shutil.copyfile(sys.argv[1], sys.argv[2])
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
#include"bob.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllexport)
|
||||
#endif
|
||||
const char* get_bob() {
|
||||
return "bob";
|
||||
}
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
__declspec(dllimport)
|
||||
#endif
|
||||
const char* get_bob();
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
with open(sys.argv[1], 'w') as f:
|
||||
f.write('')
|
|
@ -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)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#include"bob.h"
|
||||
#include"genbob.h"
|
||||
#include<string.h>
|
||||
#include<stdio.h>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue