I'd like to clarify changes: - support building Wine with LTO is enabled via `--enable-lto` option for "./configure" script - "./configure" script appends `-D__WINE_LTO_BUILD` to CFLAGS (this may be useful somehow in future) - support for generating Makefile with LTO flags is done by `-L` option for "tools/makedep" (passed by "./configure --enable-lto") - "winebuild" and "winegcc" support `-flto` / `-fno-lto` options - all modified tools ("tools/makedep", "winebuild" and "winegcc") will pass at least `-flto` / `-fno-lto` to subsequent tools (see notes on environment variables below) --- Environment variables for toolchain LTO flags: `WINE_LTO_FLAGS` - flags to be passed for targets to be built with LTO; defaults to "-flto" if unspecified or empty. `WINE_LTO_SKIP_FLAGS` - flags to be passed for targets to be built without LTO; defaults to "-fno-lto" if unspecified or empty. Environment variables for tools: `WINE_LTO_AR`, `WINE_LTO_NM`, `WINE_LTO_RANLIB` (used by "winebuild") - first priority tool for `ar`, `nm` and `ranlib` respectively. For GCC-based toolchain the one should specify "gcc-ar", "gcc-nm" and "gcc-ranlib" accordingly; for LLVM-based toolchain these are "llvm-ar", "llvm-nm" and "llvm-ranlib". `WINE_LTO_DEBUG` (used by "winebuild" and "winegcc") - boolean switch to enable verbose mode without specifying command-line options; accepts "`1`", "`t`", "`true`", "`y`" and "`yes`" in all letter case variants. These environment variables are used only if LTO switch was specified: `-L` for "tools/makedep" and `-flto` / `-fno-lto` for "winebuild" and "winegcc". --- Hovewer, some sources/targets can't be built with LTO (due to current toolchain limitations). There're two ways to build source without LTO: 1. via target's `Makefile.in`: specify file name in `LTO_SKIP_SRC` (for all architectures) or `${arch}_LTO_SKIP_SRC` variable, e.g. ```diff --- a/dlls/kernelbase/Makefile.in +++ b/dlls/kernelbase/Makefile.in @@ -26,3 +26,8 @@ SOURCES = \ version.c \ volume.c \ winerror.mc + +LTO_SKIP_SRC = debug.c thread.c +i386_LTO_SKIP_SRC = sync.c +x86_64_LTO_SKIP_SRC = loader.c +arm64ec_LTO_SKIP_SRC = loader.c ``` 2. via `tools/makedep`-related skiplists (plain-text files, one file path per line) - `tools/makedep.lto-skip.any.list` (for all architectures) or `tools/makedep.lto-skip.${arch}.list`, e.g. `tools/makedep.lto-skip.any.list`: ``` dlls/msvcrt/except_arm.c dlls/msvcrt/except_arm64.c dlls/msvcrt/except_arm64ec.c dlls/msvcrt/except_i386.c dlls/msvcrt/except_x86_64.c dlls/msvcrt/math.c ``` To build whole target without LTO, the one should add `LTO_SKIP` (for all architectures) or `${arch}_LTO_SKIP` boolean variable to target's `Makefile.in`, e.g.: ```diff --- a/programs/rundll32/Makefile.in +++ b/programs/rundll32/Makefile.in @@ -5,3 +5,5 @@ EXTRADLLFLAGS = -mwindows -municode SOURCES = \ rundll32.c + +i386_LTO_SKIP = yes ``` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/7111#note_91611