diff options
-rw-r--r-- | mesonbuild/backend/backends.py | 13 | ||||
-rw-r--r-- | mesonbuild/backend/ninjabackend.py | 127 |
2 files changed, 86 insertions, 54 deletions
diff --git a/mesonbuild/backend/backends.py b/mesonbuild/backend/backends.py index 1f16778..0eb4c6e 100644 --- a/mesonbuild/backend/backends.py +++ b/mesonbuild/backend/backends.py @@ -140,6 +140,19 @@ class Backend(): dirname = os.path.join(self.environment.get_build_dir(), self.get_target_private_dir(target)) return dirname + def get_target_generated_dir(self, target, gensrc, src): + """ + Takes a BuildTarget, a generator source (CustomTarget or GeneratedList), + and a generated source filename. + Returns the full path of the generated source relative to the build root + """ + # CustomTarget generators output to the build dir of the CustomTarget + if isinstance(gensrc, build.CustomTarget): + return os.path.join(self.get_target_dir(gensrc), src) + # GeneratedList generators output to the private build directory of the + # target that the GeneratedList is used in + return os.path.join(self.get_target_private_dir(target), src) + def generate_unity_files(self, target, unity_src): langlist = {} abs_files = [] diff --git a/mesonbuild/backend/ninjabackend.py b/mesonbuild/backend/ninjabackend.py index 7a7b681..a3c36c2 100644 --- a/mesonbuild/backend/ninjabackend.py +++ b/mesonbuild/backend/ninjabackend.py @@ -35,6 +35,10 @@ def ninja_quote(text): return text.replace(' ', '$ ').replace(':', '$:') class RawFilename(): + """ + Used when a filename is already relative to the root build directory, so + that we know not to add the target's private build directory to it. + """ def __init__(self, fname): self.fname = fname @@ -216,17 +220,44 @@ int dummy; # we need to add an order dependency to them. def get_generated_headers(self, target): header_deps = [] - for gensource in target.get_generated_sources(): - if isinstance(gensource, build.CustomTarget): + # XXX: Why don't we add deps to CustomTarget headers here? + for genlist in target.get_generated_sources(): + if isinstance(genlist, build.CustomTarget): continue - for src in gensource.get_outputs(): + for src in genlist.get_outputs(): if self.environment.is_header(src): - header_deps.append(os.path.join(self.get_target_private_dir(target), src)) + header_deps.append(self.get_target_generated_dir(target, genlist, src)) + # Recurse and find generated headers for dep in target.link_targets: if isinstance(dep, (build.StaticLibrary, build.SharedLibrary)): header_deps += self.get_generated_headers(dep) return header_deps + def get_target_generated_sources(self, target): + """ + Returns a dictionary with the keys being the path to the file + (relative to the build directory) of that type and the value + being the GeneratorList or CustomTarget that generated it. + """ + srcs = {} + for gensrc in target.get_generated_sources(): + for s in gensrc.get_outputs(): + f = self.get_target_generated_dir(target, gensrc, s) + srcs[f] = s + return srcs + + def get_target_sources(self, target): + srcs = {} + for s in target.get_sources(): + # BuildTarget sources are always mesonlib.File files which are + # either in the source root, or generated with configure_file and + # in the build root + if not isinstance(s, File): + raise InvalidArguments('All sources in target {!r} must be of type mesonlib.File'.format(t)) + f = s.rel_to_builddir(self.build_to_src) + srcs[f] = s + return srcs + def generate_target(self, target, outfile): if isinstance(target, build.CustomTarget): self.generate_custom_target(target, outfile) @@ -253,8 +284,15 @@ int dummy; if 'swift' in target.compilers: self.generate_swift_target(target, outfile) return + + # Pre-existing target C/C++ sources to be built + target_sources = [] + # GeneratedList and CustomTarget sources to be built + generated_sources = [] if 'vala' in target.compilers: vala_gen_sources = self.generate_vala_compile(target, outfile) + target_sources = self.get_target_sources(target) + generated_sources = self.get_target_generated_sources(target) self.scan_fortran_module_outputs(target) # Generate rules for GeneratedLists self.generate_generator_list_rules(target, outfile) @@ -282,41 +320,24 @@ int dummy; # 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) - 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: - generated_source_files.append(RawFilename(src)) - elif self.environment.is_object(src): - obj_list.append(src) - elif self.environment.is_library(src): - pass - else: - # Assume anything not specifically a source file is a header. This is because - # people generate files with weird suffixes (.inc, .fh) that they then include - # in their source files. - header_deps.append(RawFilename(src)) + for rel_src, gensrc in generated_sources.items(): + generated_output_sources.append(rel_src) + if self.environment.is_source(rel_src) and not self.environment.is_header(rel_src): + if is_unity: + unity_deps.append(rel_src) + abs_src = os.path.join(self.environment.get_build_dir(), rel_src) + unity_src.append(abs_src) + else: + generated_source_files.append(RawFilename(rel_src)) + elif self.environment.is_object(rel_src): + obj_list.append(rel_src) + elif self.environment.is_library(rel_src): + pass else: - for src in gensource.get_outputs(): - 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): - if is_unity: - if self.has_dir_part(src): - rel_src = src - else: - rel_src = os.path.join(self.get_target_private_dir(target), src) - unity_deps.append(rel_src) - abs_src = os.path.join(self.environment.get_build_dir(), rel_src) - unity_src.append(abs_src) - else: - generated_source_files.append(src) + # Assume anything not specifically a source file is a header. This is because + # people generate files with weird suffixes (.inc, .fh) that they then include + # in their source files. + header_deps.append(RawFilename(rel_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. @@ -341,9 +362,12 @@ int dummy; if self.environment.is_header(src): header_deps.append(src) else: + # Passing 'vala' here signifies that we want the compile + # arguments to be specialized for C code generated by + # valac. For instance, no warnings should be emitted. obj_list.append(self.generate_single_compile(target, outfile, src, 'vala', [], header_deps)) # Generate compile targets for all the pre-existing sources for this target - for src in target.get_sources(): + for f, src in target_sources.items(): if src.endswith('.vala'): continue if not self.environment.is_header(src): @@ -1015,16 +1039,7 @@ int dummy; return result def split_swift_generated_sources(self, target): - all_srcs = [] - for genlist in target.get_generated_sources(): - if isinstance(genlist, build.CustomTarget): - for ifile in genlist.get_filename(): - rel = os.path.join(self.get_target_dir(genlist), ifile) - all_srcs.append(rel) - else: - for ifile in genlist.get_outputs(): - rel = os.path.join(self.get_target_private_dir(target), ifile) - all_srcs.append(rel) + all_srcs = self.get_target_generated_sources(target) srcs = [] others = [] for i in all_srcs: @@ -1590,6 +1605,9 @@ rule FORTRAN_DEP_HACK return linker.get_link_debugfile_args(outname) def generate_single_compile(self, target, outfile, src, is_generated=False, header_deps=[], order_deps=[]): + """ + Compiles only C/C++ and ObjC/ObjC++ sources + """ if(isinstance(src, str) and src.endswith('.h')): raise RuntimeError('Fug') if isinstance(src, RawFilename) and src.fname.endswith('.h'): @@ -1670,11 +1688,12 @@ rule FORTRAN_DEP_HACK arr.append(i) pch_dep = arr custom_target_include_dirs = [] - for i in target.generated: - if isinstance(i, build.CustomTarget): - idir = self.get_target_dir(i) - if idir not in custom_target_include_dirs: - custom_target_include_dirs.append(idir) + for i in target.get_generated_sources(): + if not isinstance(i, build.CustomTarget): + continue + idir = self.get_target_dir(i) + if idir not in custom_target_include_dirs: + custom_target_include_dirs.append(idir) for i in custom_target_include_dirs: commands+= compiler.get_include_args(i, False) if self.environment.coredata.base_options.get('b_pch', False): |