@@ -10,6 +10,7 @@ find_program(MAKE make REQUIRED)
1010option (WASI_SDK_DEBUG_PREFIX_MAP "Pass `-fdebug-prefix-map` for built artifacts" ON )
1111option (WASI_SDK_INCLUDE_TESTS "Whether or not to build tests by default" OFF )
1212option (WASI_SDK_INSTALL_TO_CLANG_RESOURCE_DIR "Whether or not to modify the compiler's resource directory" OFF )
13+ option (WASI_SDK_LTO "Whether or not to build LTO assets" ON )
1314
1415set (wasi_tmp_install ${CMAKE_CURRENT_BINARY_DIR} /install )
1516set (wasi_sysroot ${wasi_tmp_install} /share/wasi-sysroot)
@@ -97,15 +98,27 @@ add_custom_target(compiler-rt DEPENDS compiler-rt-build compiler-rt-post-build)
9798# wasi-libc build logic
9899# =============================================================================
99100
100- function (define_wasi_libc target )
101- set (build_dir ${CMAKE_CURRENT_BINARY_DIR} /wasi-libc-${target} )
101+ function (define_wasi_libc_sub target target_suffix lto )
102+ set (build_dir ${CMAKE_CURRENT_BINARY_DIR} /wasi-libc-${target}${target_suffix} )
102103
103104 if (${target} MATCHES threads)
104- set (extra_make_flags THREAD_MODEL=posix)
105+ if (lto)
106+ set (extra_make_flags LTO=full THREAD_MODEL=posix)
107+ else ()
108+ set (extra_make_flags THREAD_MODEL=posix)
109+ endif ()
105110 elseif (${target} MATCHES p2)
106- set (extra_make_flags WASI_SNAPSHOT=p2 default libc_so)
111+ if (lto)
112+ set (extra_make_flags LTO=full WASI_SNAPSHOT=p2 default)
113+ else ()
114+ set (extra_make_flags WASI_SNAPSHOT=p2 default libc_so)
115+ endif ()
107116 else ()
108- set (extra_make_flags default libc_so)
117+ if (lto)
118+ set (extra_make_flags LTO=full default)
119+ else ()
120+ set (extra_make_flags default libc_so)
121+ endif ()
109122 endif ()
110123
111124 string (TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPER)
@@ -114,7 +127,7 @@ function(define_wasi_libc target)
114127 "${CMAKE_C_FLAGS} ${directory_cflags} ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPER} }" )
115128 list (JOIN extra_cflags_list " " extra_cflags)
116129
117- ExternalProject_Add(wasi-libc-${target}
130+ ExternalProject_Add(wasi-libc-${target}${target_suffix} - build
118131 # Currently wasi-libc doesn't support out-of-tree builds so feigh a
119132 # "download command" which copies the source tree to a different location
120133 # so out-of-tree builds are supported.
@@ -129,7 +142,7 @@ function(define_wasi_libc target)
129142 NM=${CMAKE_NM}
130143 SYSROOT=${wasi_sysroot}
131144 EXTRA_CFLAGS=${extra_cflags}
132- TARGET_TRIPLE=${target}
145+ TARGET_TRIPLE=${target}
133146 ${extra_make_flags}
134147 INSTALL_COMMAND ""
135148 DEPENDS compiler-rt
@@ -140,6 +153,16 @@ function(define_wasi_libc target)
140153 )
141154endfunction ()
142155
156+ function (define_wasi_libc target )
157+ define_wasi_libc_sub (${target} "" OFF )
158+ if (WASI_SDK_LTO)
159+ define_wasi_libc_sub (${target} "-lto" ON )
160+ endif ()
161+
162+ add_custom_target (wasi-libc-${target}
163+ DEPENDS wasi-libc-${target} -build $<$<BOOL :${WASI_SDK_LTO} >:wasi-libc-${target} -lto-build >)
164+ endfunction ()
165+
143166foreach (target IN LISTS WASI_SDK_TARGETS)
144167 define_wasi_libc(${target} )
145168endforeach ()
@@ -148,7 +171,12 @@ endforeach()
148171# libcxx build logic
149172# =============================================================================
150173
151- function (define_libcxx target )
174+ execute_process (
175+ COMMAND ${CMAKE_C_COMPILER} -dumpversion
176+ OUTPUT_VARIABLE llvm_version
177+ OUTPUT_STRIP_TRAILING_WHITESPACE)
178+
179+ function (define_libcxx_sub target target_suffix extra_target_flags extra_libdir_suffix)
152180 if (${target} MATCHES threads)
153181 set (threads ON )
154182 set (pic OFF )
@@ -158,6 +186,10 @@ function(define_libcxx target)
158186 set (pic ON )
159187 set (target_flags "" )
160188 endif ()
189+ if (${target_suffix} MATCHES lto)
190+ set (pic OFF )
191+ endif ()
192+ list (APPEND target_flags ${extra_target_flags} )
161193
162194 set (runtimes "libcxx;libcxxabi" )
163195
@@ -176,7 +208,7 @@ function(define_libcxx target)
176208 set (extra_cxxflags_list ${CMAKE_CXX_FLAGS} ${extra_flags} )
177209 list (JOIN extra_cxxflags_list " " extra_cxxflags)
178210
179- ExternalProject_Add(libcxx-${target} -build
211+ ExternalProject_Add(libcxx-${target}${target_suffix} -build
180212 SOURCE_DIR ${llvm_proj_dir} /runtimes
181213 CMAKE_ARGS
182214 ${default_cmake_args}
@@ -214,8 +246,8 @@ function(define_libcxx target)
214246 -DUNIX:BOOL =ON
215247 -DCMAKE_C_FLAGS=${extra_cflags}
216248 -DCMAKE_CXX_FLAGS=${extra_cxxflags}
217- -DLIBCXX_LIBDIR_SUFFIX=/${target}
218- -DLIBCXXABI_LIBDIR_SUFFIX=/${target}
249+ -DLIBCXX_LIBDIR_SUFFIX=/${target}${extra_libdir_suffix}
250+ -DLIBCXXABI_LIBDIR_SUFFIX=/${target}${extra_libdir_suffix}
219251
220252 # See https://www.scivision.dev/cmake-externalproject-list-arguments/ for
221253 # why this is in `CMAKE_CACHE_ARGS` instead of above
@@ -229,14 +261,23 @@ function(define_libcxx target)
229261 USES_TERMINAL_BUILD ON
230262 USES_TERMINAL_INSTALL ON
231263 )
264+ endfunction ()
265+
266+ function (define_libcxx target )
267+ define_libcxx_sub(${target} "" "" "" )
268+ if (WASI_SDK_LTO)
269+ # Note: clang knows this /llvm-lto/${llvm_version} convention.
270+ # https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/clang/lib/Driver/ToolChains/WebAssembly.cpp#L204-L210
271+ define_libcxx_sub(${target} "-lto" "-flto=full" "/llvm-lto/${llvm_version} " )
272+ endif ()
232273
233274 # As of this writing, `clang++` will ignore the target-specific include dirs
234275 # unless this one also exists:
235276 add_custom_target (libcxx-${target} -extra-dir
236277 COMMAND ${CMAKE_COMMAND} -E make_directory ${wasi_sysroot} /include /c++/v1
237278 COMMENT "creating libcxx-specific header file folder" )
238279 add_custom_target (libcxx-${target}
239- DEPENDS libcxx-${target} -build libcxx-${target} -extra-dir)
280+ DEPENDS libcxx-${target} -build $<$< BOOL : ${WASI_SDK_LTO} >:libcxx- ${target} -lto- build > libcxx-${target} -extra-dir)
240281endfunction ()
241282
242283foreach (target IN LISTS WASI_SDK_TARGETS)
0 commit comments