diff options
| author | Sam James <sam@gentoo.org> | 2025-11-08 02:13:31 +0000 |
|---|---|---|
| committer | Jussi Pakkanen <jussi.pakkanen@mailbox.org> | 2025-11-09 12:37:40 +0200 |
| commit | 66f648d0870286540511846f69a101e24dbe92c1 (patch) | |
| tree | c8614c5c1c33c5395aa51d4f920d73887c1ed8ec | |
| parent | 8f3458dc849392f364899336433afdd8f11a06c6 (diff) | |
| download | meson-66f648d0870286540511846f69a101e24dbe92c1.tar.gz | |
compilers: support GCC incremental LTO
GCC 15 supports incremental LTO (caching). It's the same feature as
Clang's ThinLTO caching.
Unfortunately, for the Clang ThinLTO cache support, we chose a pretty
vendor-specific option name, and I don't want to worry about deprecating
that (-Db_thinlto_cache and -Db_thinlto_cache_dir) at this time, so...
Wire -Db_thinlto_cache and -Db_thinlto_cache_dir for GCC in the obvious
and natural way.
Other notes:
* GCC, unlike Clang, requires the cache dir to exist. If the
user passes an invalid directory, that's on them, but for our default
in meson-private, we should os.mkdir() it, so we do that now too.
* I did wonder about adding -flto-partition=cache, but when I asked about
this last year [0], the response was that it has too many caveats. Though
Honza did recently [1] suggest it has some utility, so I don't know. I'll
ask about it.
[0] https://inbox.sourceware.org/gcc-patches/vjeanwm7b2jnedzmbwww4cy6jf4prty6ypxvz7x5d463xw2mys@bxzxuvgfaplf/
[1] https://inbox.sourceware.org/gcc-patches/aLnAGpln6SXbjV7e@kam.mff.cuni.cz/
Closes: https://github.com/mesonbuild/meson/issues/14428
| -rw-r--r-- | docs/markdown/snippets/gcc_incremental_lto.md | 4 | ||||
| -rw-r--r-- | mesonbuild/compilers/compilers.py | 1 | ||||
| -rw-r--r-- | mesonbuild/compilers/mixins/gnu.py | 20 |
3 files changed, 22 insertions, 3 deletions
diff --git a/docs/markdown/snippets/gcc_incremental_lto.md b/docs/markdown/snippets/gcc_incremental_lto.md new file mode 100644 index 000000000..50bb21837 --- /dev/null +++ b/docs/markdown/snippets/gcc_incremental_lto.md @@ -0,0 +1,4 @@ +## `-Db_thinlto_cache` now supported for GCC + +`-Db_thinlto_cache` is now supported for GCC 15's incremental LTO, as is +`-Db_thinlto_cache_dir`.
\ No newline at end of file diff --git a/mesonbuild/compilers/compilers.py b/mesonbuild/compilers/compilers.py index 4432f198a..bd283ed32 100644 --- a/mesonbuild/compilers/compilers.py +++ b/mesonbuild/compilers/compilers.py @@ -351,6 +351,7 @@ def get_base_link_args(target: 'BuildTarget', thinlto_cache_dir = get_option_value_for_target(env, target, OptionKey('b_thinlto_cache_dir'), '') if thinlto_cache_dir == '': thinlto_cache_dir = os.path.join(build_dir, 'meson-private', 'thinlto-cache') + os.mkdir(thinlto_cache_dir) num_threads = get_option_value_for_target(env, target, OptionKey('b_lto_threads'), 0) lto_mode = get_option_value_for_target(env, target, OptionKey('b_lto_mode'), 'default') args.extend(linker.get_lto_link_args( diff --git a/mesonbuild/compilers/mixins/gnu.py b/mesonbuild/compilers/mixins/gnu.py index 90492bf82..fb97d0278 100644 --- a/mesonbuild/compilers/mixins/gnu.py +++ b/mesonbuild/compilers/mixins/gnu.py @@ -550,15 +550,18 @@ class GnuCompiler(GnuLikeCompiler): _COLOR_VERSION = '>=4.9.0' _WPEDANTIC_VERSION = '>=4.8.0' _LTO_AUTO_VERSION = '>=10.0' + _LTO_CACHE_VERSION = '>=15.1' _USE_MOLD_VERSION = '>=12.0.1' def __init__(self, defines: T.Optional[T.Dict[str, str]]): super().__init__() self.defines = defines or {} - self.base_options.update({OptionKey('b_colorout'), OptionKey('b_lto_threads')}) + self.base_options.update({OptionKey('b_colorout'), OptionKey('b_lto_threads'), + OptionKey('b_thinlto_cache'), OptionKey('b_thinlto_cache_dir')}) self._has_color_support = mesonlib.version_compare(self.version, self._COLOR_VERSION) self._has_wpedantic_support = mesonlib.version_compare(self.version, self._WPEDANTIC_VERSION) self._has_lto_auto_support = mesonlib.version_compare(self.version, self._LTO_AUTO_VERSION) + self._has_lto_cache_support = mesonlib.version_compare(self.version, self._LTO_CACHE_VERSION) def get_colorout_args(self, colortype: str) -> T.List[str]: if self._has_color_support: @@ -619,7 +622,8 @@ class GnuCompiler(GnuLikeCompiler): def get_prelink_args(self, prelink_name: str, obj_list: T.List[str]) -> T.Tuple[T.List[str], T.List[str]]: return [prelink_name], ['-r', '-o', prelink_name] + obj_list - def get_lto_compile_args(self, *, threads: int = 0, mode: str = 'default') -> T.List[str]: + def get_lto_compile_args(self, *, threads: int = 0, mode: str = 'default', + thinlto_cache_dir: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] if threads == 0: @@ -634,8 +638,18 @@ class GnuCompiler(GnuLikeCompiler): else: args.extend(super().get_lto_compile_args(threads=threads)) + if thinlto_cache_dir is not None: + # We check for ThinLTO linker support above in get_lto_compile_args, and all of them support + # get_thinlto_cache_args as well + args.extend(self.get_thinlto_cache_args(thinlto_cache_dir)) + return args + def get_thinlto_cache_args(self, path: str) -> T.List[str]: + # Unlike the ThinLTO support for Clang, everything is handled in GCC + # and the linker has no direct involvement other than the usual w/ LTO. + return [f'-flto-incremental={path}'] + @classmethod def use_linker_args(cls, linker: str, version: str) -> T.List[str]: if linker == 'mold' and mesonlib.version_compare(version, cls._USE_MOLD_VERSION): @@ -645,7 +659,7 @@ class GnuCompiler(GnuLikeCompiler): def get_lto_link_args(self, *, threads: int = 0, mode: str = 'default', thinlto_cache_dir: T.Optional[str] = None) -> T.List[str]: args: T.List[str] = [] - args.extend(self.get_lto_compile_args(threads=threads)) + args.extend(self.get_lto_compile_args(threads=threads, thinlto_cache_dir=thinlto_cache_dir)) return args def get_profile_use_args(self) -> T.List[str]: |
