diff --git a/backends.py b/backends.py index 2c8810eda..4d311eec8 100644 --- a/backends.py +++ b/backends.py @@ -148,6 +148,16 @@ class Backend(): os.makedirs(os.path.join(self.environment.get_build_dir(), dirname), exist_ok=True) return dirname + def generate_unity_files(self, target, unity_src): + outfilename = os.path.join(self.get_target_private_dir(target), target.name + '.c') + outfileabs = os.path.join(self.environment.get_build_dir(), outfilename) + outfile = open(outfileabs, 'w') + for src in unity_src: + outfile.write('#include<%s>\n' % src) + outfile.close() + return [outfilename] + + def generate_target(self, target, outfile): name = target.get_basename() if name in self.processed_targets: @@ -157,23 +167,36 @@ class Backend(): self.generate_custom_generator_rules(target, outfile) outname = self.get_target_filename(target) obj_list = [] - if self.environment.coredata.use_pch and target.has_pch(): + use_pch = self.environment.coredata.use_pch + is_unity = self.environment.coredata.unity + if use_pch and target.has_pch(): self.generate_pch(target, outfile) header_deps = gen_other_deps + unity_src = [] for genlist in target.get_generated_sources(): for src in genlist.get_outfilelist(): if not self.environment.is_header(src): - obj_list.append(self.generate_single_compile(target, outfile, src, True)) + if is_unity: + unity_src.append(src) + else: + obj_list.append(self.generate_single_compile(target, outfile, src, True)) else: header_deps.append(src) src_list = [] for src in gen_src_deps: src_list.append(src) - obj_list.append(self.generate_single_compile(target, outfile, src, True)) + if is_unity: + unity_src.append(src) + else: + obj_list.append(self.generate_single_compile(target, outfile, src, True)) for src in target.get_sources(): if not self.environment.is_header(src): src_list.append(src) - obj_list.append(self.generate_single_compile(target, outfile, src, False, header_deps)) + if is_unity: + abs_src = os.path.join(self.environment.get_source_dir(), src) + unity_src.append(abs_src) + else: + obj_list.append(self.generate_single_compile(target, outfile, src, False, header_deps)) for obj in target.get_objects(): if isinstance(obj, str): o = os.path.join(self.build_to_src, target.get_subdir(), obj) @@ -182,6 +205,9 @@ class Backend(): obj_list += self.determine_ext_objs(obj) else: raise MesonException('Unknown data type in object list.') + if is_unity: + for src in self.generate_unity_files(target, unity_src): + obj_list.append(self.generate_single_compile(target, outfile, src, True)) linker = self.determine_linker(target, src_list) elem = self.generate_link(target, outfile, outname, obj_list, linker) self.generate_shlib_aliases(target, self.get_target_dir(target), outfile, elem) diff --git a/coredata.py b/coredata.py index dcf7101e4..64eca6656 100644 --- a/coredata.py +++ b/coredata.py @@ -35,6 +35,7 @@ class CoreData(): self.buildtype = options.buildtype self.strip = options.strip self.use_pch = options.use_pch + self.unity = options.unity self.coverage = options.coverage self.user_options = {} if options.cross_file is not None: diff --git a/meson.py b/meson.py index d96dffca6..f72e3faef 100755 --- a/meson.py +++ b/meson.py @@ -60,6 +60,8 @@ parser.add_option('--enable-gcov', action='store_true', dest='coverage', default help='measure test coverage') parser.add_option('--disable-pch', action='store_false', dest='use_pch', default=True,\ help='do not use precompiled headers') +parser.add_option('--unity', action='store_true', dest='unity', default=True,\ + help='unity build') parser.add_option('--cross-file', default=None, dest='cross_file', help='file describing cross compilation environment')