Add unity block size option.
This commit is contained in:
parent
6b5c1a4fc3
commit
47759550e5
|
@ -82,6 +82,7 @@ Using the option as-is with no prefix affects all machines. For example:
|
||||||
| stdsplit | true | Split stdout and stderr in test logs | no |
|
| stdsplit | true | Split stdout and stderr in test logs | no |
|
||||||
| strip | false | Strip targets on install | no |
|
| strip | false | Strip targets on install | no |
|
||||||
| unity {on, off, subprojects} | off | Unity build | no |
|
| unity {on, off, subprojects} | off | Unity build | no |
|
||||||
|
| unity_size {>=2} | 4 | Unity file block size | no |
|
||||||
| warning_level {0, 1, 2, 3} | 1 | Set the warning level. From 0 = none to 3 = highest | no |
|
| warning_level {0, 1, 2, 3} | 1 | Set the warning level. From 0 = none to 3 = highest | no |
|
||||||
| werror | false | Treat warnings as errors | no |
|
| werror | false | Treat warnings as errors | no |
|
||||||
| wrap_mode {default, nofallback,<br>nodownload, forcefallback} | default | Wrap mode to use | no |
|
| wrap_mode {default, nofallback,<br>nodownload, forcefallback} | default | Wrap mode to use | no |
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
## Unity file block size is configurable
|
||||||
|
|
||||||
|
Traditionally the unity files that Meson autogenerates contain all
|
||||||
|
source files that belong to a single target. This is the most
|
||||||
|
efficient setting for full builds but makes incremental builds slow.
|
||||||
|
This release adds a new option `unity_size` which specifies how many
|
||||||
|
source files should be put in each unity file.
|
||||||
|
|
||||||
|
The default value for block size is 4. This means that if you have a
|
||||||
|
target that has eight source files, Meson will generate two unity
|
||||||
|
files each of which includes four source files. The old behaviour can
|
||||||
|
be replicated by setting `unity_size` to a large value, such as 10000.
|
|
@ -243,19 +243,20 @@ class Backend:
|
||||||
# target that the GeneratedList is used in
|
# target that the GeneratedList is used in
|
||||||
return os.path.join(self.get_target_private_dir(target), src)
|
return os.path.join(self.get_target_private_dir(target), src)
|
||||||
|
|
||||||
def get_unity_source_file(self, target, suffix):
|
def get_unity_source_file(self, target, suffix, number):
|
||||||
# There is a potential conflict here, but it is unlikely that
|
# There is a potential conflict here, but it is unlikely that
|
||||||
# anyone both enables unity builds and has a file called foo-unity.cpp.
|
# anyone both enables unity builds and has a file called foo-unity.cpp.
|
||||||
osrc = target.name + '-unity.' + suffix
|
osrc = '{}-unity{}.{}'.format(target.name, number, suffix)
|
||||||
return mesonlib.File.from_built_file(self.get_target_private_dir(target), osrc)
|
return mesonlib.File.from_built_file(self.get_target_private_dir(target), osrc)
|
||||||
|
|
||||||
def generate_unity_files(self, target, unity_src):
|
def generate_unity_files(self, target, unity_src):
|
||||||
abs_files = []
|
abs_files = []
|
||||||
result = []
|
result = []
|
||||||
compsrcs = classify_unity_sources(target.compilers.values(), unity_src)
|
compsrcs = classify_unity_sources(target.compilers.values(), unity_src)
|
||||||
|
unity_size = self.get_option_for_target('unity_size', target)
|
||||||
|
|
||||||
def init_language_file(suffix):
|
def init_language_file(suffix, unity_file_number):
|
||||||
unity_src = self.get_unity_source_file(target, suffix)
|
unity_src = self.get_unity_source_file(target, suffix, unity_file_number)
|
||||||
outfileabs = unity_src.absolute_path(self.environment.get_source_dir(),
|
outfileabs = unity_src.absolute_path(self.environment.get_source_dir(),
|
||||||
self.environment.get_build_dir())
|
self.environment.get_build_dir())
|
||||||
outfileabs_tmp = outfileabs + '.tmp'
|
outfileabs_tmp = outfileabs + '.tmp'
|
||||||
|
@ -266,11 +267,23 @@ class Backend:
|
||||||
result.append(unity_src)
|
result.append(unity_src)
|
||||||
return open(outfileabs_tmp, 'w')
|
return open(outfileabs_tmp, 'w')
|
||||||
|
|
||||||
# For each language, generate a unity source file and return the list
|
# For each language, generate unity source files and return the list
|
||||||
for comp, srcs in compsrcs.items():
|
for comp, srcs in compsrcs.items():
|
||||||
with init_language_file(comp.get_default_suffix()) as ofile:
|
files_in_current = unity_size + 1
|
||||||
for src in srcs:
|
unity_file_number = 0
|
||||||
ofile.write('#include<%s>\n' % src)
|
ofile = None
|
||||||
|
for src in srcs:
|
||||||
|
if files_in_current >= unity_size:
|
||||||
|
if ofile:
|
||||||
|
ofile.close()
|
||||||
|
ofile = init_language_file(comp.get_default_suffix(), unity_file_number)
|
||||||
|
unity_file_number += 1
|
||||||
|
files_in_current = 0
|
||||||
|
ofile.write('#include<%s>\n' % src)
|
||||||
|
files_in_current += 1
|
||||||
|
if ofile:
|
||||||
|
ofile.close()
|
||||||
|
|
||||||
[mesonlib.replace_if_different(x, x + '.tmp') for x in abs_files]
|
[mesonlib.replace_if_different(x, x + '.tmp') for x in abs_files]
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@ -489,16 +502,18 @@ class Backend:
|
||||||
|
|
||||||
targetdir = self.get_target_private_dir(extobj.target)
|
targetdir = self.get_target_private_dir(extobj.target)
|
||||||
|
|
||||||
# With unity builds, there's just one object that contains all the
|
# With unity builds, sources don't map directly to objects,
|
||||||
# sources, and we only support extracting all the objects in this mode,
|
# we only support extracting all the objects in this mode,
|
||||||
# so just return that.
|
# so just return all object files.
|
||||||
if self.is_unity(extobj.target):
|
if self.is_unity(extobj.target):
|
||||||
compsrcs = classify_unity_sources(extobj.target.compilers.values(), sources)
|
compsrcs = classify_unity_sources(extobj.target.compilers.values(), sources)
|
||||||
sources = []
|
sources = []
|
||||||
for comp in compsrcs.keys():
|
unity_size = self.get_option_for_target('unity_size', extobj.target)
|
||||||
osrc = self.get_unity_source_file(extobj.target,
|
for comp, srcs in compsrcs.items():
|
||||||
comp.get_default_suffix())
|
for i in range(len(srcs) // unity_size + 1):
|
||||||
sources.append(osrc)
|
osrc = self.get_unity_source_file(extobj.target,
|
||||||
|
comp.get_default_suffix(), i)
|
||||||
|
sources.append(osrc)
|
||||||
|
|
||||||
for osrc in sources:
|
for osrc in sources:
|
||||||
objname = self.object_filename_from_source(extobj.target, osrc)
|
objname = self.object_filename_from_source(extobj.target, osrc)
|
||||||
|
|
|
@ -1067,6 +1067,7 @@ builtin_options = OrderedDict([
|
||||||
('stdsplit', BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
|
('stdsplit', BuiltinOption(UserBooleanOption, 'Split stdout and stderr in test logs', True)),
|
||||||
('strip', BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
|
('strip', BuiltinOption(UserBooleanOption, 'Strip targets on install', False)),
|
||||||
('unity', BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects'])),
|
('unity', BuiltinOption(UserComboOption, 'Unity build', 'off', choices=['on', 'off', 'subprojects'])),
|
||||||
|
('unity_size', BuiltinOption(UserIntegerOption, 'Unity block size', (2, None, 4))),
|
||||||
('warning_level', BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'])),
|
('warning_level', BuiltinOption(UserComboOption, 'Compiler warning level to use', '1', choices=['0', '1', '2', '3'])),
|
||||||
('werror', BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False)),
|
('werror', BuiltinOption(UserBooleanOption, 'Treat warnings as errors', False)),
|
||||||
('wrap_mode', BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
|
('wrap_mode', BuiltinOption(UserComboOption, 'Wrap mode', 'default', choices=['default', 'nofallback', 'nodownload', 'forcefallback'])),
|
||||||
|
|
|
@ -5305,9 +5305,9 @@ class LinuxlikeTests(BasePlatformTests):
|
||||||
testdir = os.path.join(self.common_test_dir, '45 subproject')
|
testdir = os.path.join(self.common_test_dir, '45 subproject')
|
||||||
self.init(testdir, extra_args='--unity=subprojects')
|
self.init(testdir, extra_args='--unity=subprojects')
|
||||||
simpletest_id = Target.construct_id_from_path('subprojects/sublib', 'simpletest', '@exe')
|
simpletest_id = Target.construct_id_from_path('subprojects/sublib', 'simpletest', '@exe')
|
||||||
self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib', simpletest_id, 'simpletest-unity.c'))
|
self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib', simpletest_id, 'simpletest-unity0.c'))
|
||||||
sublib_id = Target.construct_id_from_path('subprojects/sublib', 'sublib', '@sha')
|
sublib_id = Target.construct_id_from_path('subprojects/sublib', 'sublib', '@sha')
|
||||||
self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib', sublib_id, 'sublib-unity.c'))
|
self.assertPathExists(os.path.join(self.builddir, 'subprojects/sublib', sublib_id, 'sublib-unity0.c'))
|
||||||
self.assertPathDoesNotExist(os.path.join(self.builddir, 'user@exe/user-unity.c'))
|
self.assertPathDoesNotExist(os.path.join(self.builddir, 'user@exe/user-unity.c'))
|
||||||
self.build()
|
self.build()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue