-
Notifications
You must be signed in to change notification settings - Fork 220
Expand file tree
/
Copy pathwasi-sdk-toolchain.cmake
More file actions
275 lines (245 loc) · 8.92 KB
/
wasi-sdk-toolchain.cmake
File metadata and controls
275 lines (245 loc) · 8.92 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
# Build logic and support for building a Clang toolchain that can target
# WebAssembly and build a WASI sysroot.
set(LLVM_CMAKE_FLAGS "" CACHE STRING "Extra cmake flags to pass to LLVM's build")
set(RUST_TARGET "" CACHE STRING "Target to build Rust code for, if not the host")
set(WASI_SDK_ARTIFACT "" CACHE STRING "Name of the wasi-sdk artifact being produced")
option(WASI_SDK_LLDB "Include a build of LLDB" ON)
set(LIBEDIT_DEFAULT ON)
# I don't want to deal with running a `./configure` script on Windows, disable
# it by default.
if(WIN32)
set(LIBEDIT_DEFAULT OFF)
endif()
# I don't know how to resolve build failures when building libedit for x86_64
# from arm64 on macos, so disable it for now.
if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64" AND LLVM_CMAKE_FLAGS MATCHES "x86_64")
set(LIBEDIT_DEFAULT OFF)
endif()
option(WASI_SDK_LIBEDIT "Whether or not to build libedit for LLDB" ${LIBEDIT_DEFAULT})
string(REGEX REPLACE "[ ]+" ";" llvm_cmake_flags_list "${LLVM_CMAKE_FLAGS}")
set(wasi_tmp_install ${CMAKE_CURRENT_BINARY_DIR}/install)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE MinSizeRel)
endif()
set(default_cmake_args
-DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-DCMAKE_AR=${CMAKE_AR}
-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}
-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}
-DCMAKE_INSTALL_PREFIX=${wasi_tmp_install})
if(CMAKE_C_COMPILER_LAUNCHER)
list(APPEND default_cmake_args -DCMAKE_C_COMPILER_LAUNCHER=${CMAKE_C_COMPILER_LAUNCHER})
endif()
if(CMAKE_CXX_COMPILER_LAUNCHER)
list(APPEND default_cmake_args -DCMAKE_CXX_COMPILER_LAUNCHER=${CMAKE_CXX_COMPILER_LAUNCHER})
endif()
set(links_to_create clang-cl clang-cpp clang++)
foreach(target IN LISTS WASI_SDK_TARGETS)
list(APPEND links_to_create ${target}-clang)
list(APPEND links_to_create ${target}-clang++)
endforeach()
set(projects "lld;clang;clang-tools-extra")
set(tools
clang
clang-format
clang-tidy
clang-apply-replacements
lld
llvm-addr2line
llvm-mc
llvm-ranlib
llvm-strip
llvm-dwarfdump
llvm-dwp
clang-resource-headers
ar
ranlib
strip
nm
size
strings
objdump
objcopy
c++filt
llvm-config
libclang)
# By default link LLVM dynamically to all the various tools. This greatly
# reduces the binary size of all the tools through a shared library rather than
# statically linking LLVM to each individual tool. This requires a few other
# install targets as well to ensure the appropriate libraries are all installed.
#
# Also note that the `-wasi-sdk` version suffix is intended to help prevent
# these dynamic libraries from clashing with other system libraries in case the
# `lib` dir gets put on `LD_LIBRARY_PATH` or similar.
if(NOT WIN32)
list(APPEND default_cmake_args -DLLVM_LINK_LLVM_DYLIB=ON -DLLVM_VERSION_SUFFIX=-wasi-sdk)
list(APPEND tools LLVM clang-cpp)
endif()
# Configure/add LLDB if requested.
#
# Note that LLDB depends on `libedit` which is more-or-less required to get a
# reasonable command-line experience, so this is built custom here to ensure
# that it's available for LLDB.
if(WASI_SDK_LLDB)
list(APPEND projects lldb)
list(APPEND tools lldb liblldb)
list(APPEND default_cmake_args
-DLLDB_INCLUDE_TESTS=OFF
-DLLDB_INCLUDE_UNITTESTS=OFF
-DLLDB_ENABLE_SWIG=OFF
-DLLDB_ENABLE_CURSES=OFF
-DLLDB_ENABLE_LZMA=OFF
-DLLDB_ENABLE_LUA=OFF
-DLLDB_ENABLE_PYTHON=OFF
-DLLDB_ENABLE_LIBXML2=OFF
-DLLDB_ENABLE_FBSDVMCORE=OFF
-DLLDB_ENABLE_LINUXPTY=OFF
)
if (WASI_SDK_LIBEDIT)
include(ProcessorCount)
ProcessorCount(nproc)
find_program(MAKE_EXECUTABLE make REQUIRED)
ExternalProject_Add(libedit
URL https://thrysoee.dk/editline/libedit-20251016-3.1.tar.gz
URL_HASH SHA256=21362b00653bbfc1c71f71a7578da66b5b5203559d43134d2dd7719e313ce041
# Without this the build system tries to find and use `aclocal-1.18` where
# with this it doesn't so turn this on.
DOWNLOAD_EXTRACT_TIMESTAMP ON
CONFIGURE_COMMAND
<SOURCE_DIR>/configure
--prefix=${wasi_tmp_install}
--enable-pic
--disable-examples
CC=${CMAKE_C_COMPILER}
CFLAGS=${libedit_cflags}
LDFLAGS=${libedit_cflags}
BUILD_COMMAND
${MAKE_EXECUTABLE} -j${nproc} V=1
USES_TERMINAL_CONFIGURE ON
USES_TERMINAL_BUILD ON
USES_TERMINAL_INSTALL ON
)
list(APPEND default_cmake_args
-DLLDB_ENABLE_LIBEDIT=ON
-DLibEdit_ROOT=${wasi_tmp_install}
)
else()
list(APPEND default_cmake_args -DLLDB_ENABLE_LIBEDIT=OFF)
add_custom_target(libedit)
endif()
else()
add_custom_target(libedit)
endif()
list(TRANSFORM tools PREPEND --target= OUTPUT_VARIABLE build_targets)
list(TRANSFORM tools PREPEND --target=install- OUTPUT_VARIABLE install_targets)
ExternalProject_Add(llvm-build
SOURCE_DIR "${llvm_proj_dir}/llvm"
CMAKE_ARGS
${default_cmake_args}
-DLLVM_ENABLE_ZLIB=OFF
-DLLVM_ENABLE_ZSTD=OFF
-DLLVM_STATIC_LINK_CXX_STDLIB=ON
-DLLVM_INCLUDE_TESTS=OFF
-DLLVM_INCLUDE_UTILS=OFF
-DLLVM_INCLUDE_BENCHMARKS=OFF
-DLLVM_INCLUDE_EXAMPLES=OFF
-DLLVM_TARGETS_TO_BUILD=WebAssembly
-DLLVM_DEFAULT_TARGET_TRIPLE=wasm32-wasip1
-DLLVM_INSTALL_BINUTILS_SYMLINKS=TRUE
-DLLVM_ENABLE_LIBXML2=OFF
# Pass `-s` to strip symbols by default and shrink the size of the
# distribution
-DCMAKE_EXE_LINKER_FLAGS=-s
${llvm_cmake_flags_list}
# See https://www.scivision.dev/cmake-externalproject-list-arguments/ for
# why this is in `CMAKE_CACHE_ARGS` instead of above
CMAKE_CACHE_ARGS
-DLLVM_ENABLE_PROJECTS:STRING=${projects}
-DCLANG_LINKS_TO_CREATE:STRING=${links_to_create}
BUILD_COMMAND
cmake --build . ${build_targets}
INSTALL_COMMAND
cmake --build . ${install_targets}
USES_TERMINAL_CONFIGURE ON
USES_TERMINAL_BUILD ON
USES_TERMINAL_INSTALL ON
PATCH_COMMAND
${CMAKE_COMMAND} -E chdir .. bash -c
"git apply ${CMAKE_SOURCE_DIR}/src/llvm-pr-185775.patch || git apply ${CMAKE_SOURCE_DIR}/src/llvm-pr-185775.patch -R --check"
)
add_custom_target(build ALL DEPENDS llvm-build)
ExternalProject_Add_StepDependencies(llvm-build configure libedit)
# Installation target for this outer project for installing the toolchain to the
# system.
install(DIRECTORY ${wasi_tmp_install}/bin ${wasi_tmp_install}/lib ${wasi_tmp_install}/share
USE_SOURCE_PERMISSIONS
DESTINATION ${CMAKE_INSTALL_PREFIX})
# Build logic for `wasm-component-ld` installed from Rust code.
set(wasm_component_ld_root ${CMAKE_CURRENT_BINARY_DIR}/wasm-component-ld)
set(wasm_component_ld ${wasm_component_ld_root}/bin/wasm-component-ld${CMAKE_EXECUTABLE_SUFFIX})
set(wasm_component_ld_version 0.5.21)
if(RUST_TARGET)
set(rust_target_flag --target=${RUST_TARGET})
endif()
add_custom_command(
OUTPUT ${wasm_component_ld}
COMMAND
cargo install --root ${wasm_component_ld_root} ${rust_target_flag}
wasm-component-ld@${wasm_component_ld_version}
COMMAND
cmake -E make_directory ${wasi_tmp_install}/bin
COMMAND
cmake -E copy ${wasm_component_ld} ${wasi_tmp_install}/bin
COMMENT "Building `wasm-component-ld` ...")
add_custom_target(wasm-component-ld DEPENDS ${wasm_component_ld})
add_dependencies(build wasm-component-ld)
# Setup installation logic for CMake support files.
add_custom_target(misc-files)
add_dependencies(build misc-files)
function(copy_misc_file src dst_folder)
cmake_path(GET src FILENAME src_filename)
set(dst ${wasi_tmp_install}/share/${dst_folder}/${src_filename})
add_custom_command(
OUTPUT ${dst}
COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${src} ${dst})
add_custom_target(copy-${src_filename} DEPENDS ${dst})
add_dependencies(misc-files copy-${src_filename})
endfunction()
copy_misc_file(src/config/config.sub misc)
copy_misc_file(src/config/config.guess misc)
copy_misc_file(wasi-sdk.cmake cmake)
copy_misc_file(wasi-sdk-pthread.cmake cmake)
copy_misc_file(wasi-sdk-p1.cmake cmake)
copy_misc_file(wasi-sdk-p2.cmake cmake)
copy_misc_file(wasi-sdk-p3.cmake cmake)
copy_misc_file(cmake/Platform/WASI.cmake cmake/Platform)
function(copy_cfg_file compiler)
set(dst ${wasi_tmp_install}/bin/${compiler}.cfg)
add_custom_command(
OUTPUT ${dst}
COMMAND cmake -E copy ${CMAKE_CURRENT_SOURCE_DIR}/clang.cfg ${dst})
add_custom_target(copy-${compiler} DEPENDS ${dst})
add_dependencies(misc-files copy-${compiler})
endfunction()
copy_cfg_file(clang)
copy_cfg_file(clang++)
include(wasi-sdk-dist)
# Figure out the name of the artifact which is either explicitly specified or
# inferred from CMake default variables.
if(WASI_SDK_ARTIFACT)
set(wasi_sdk_artifact ${WASI_SDK_ARTIFACT})
else()
if(APPLE)
set(wasi_sdk_os macos)
else()
string(TOLOWER ${CMAKE_SYSTEM_NAME} wasi_sdk_os)
endif()
set(wasi_sdk_arch ${CMAKE_SYSTEM_PROCESSOR})
set(wasi_sdk_artifact ${wasi_sdk_arch}-${wasi_sdk_os})
endif()
set(dist_dir ${CMAKE_CURRENT_BINARY_DIR}/dist)
wasi_sdk_add_tarball(dist-toolchain
${dist_dir}/wasi-toolchain-${wasi_sdk_version}-${wasi_sdk_artifact}.tar.gz
${wasi_tmp_install})
add_dependencies(dist-toolchain build)
add_custom_target(dist DEPENDS dist-toolchain)