Skip to content

Commit 5176252

Browse files
committed
wasi-runtimes 19.1.2 (new formula)
This are the bits necessary to combine with `wasi-libc` that allows us to target WASI.
1 parent c76a73e commit 5176252

File tree

1 file changed

+193
-0
lines changed

1 file changed

+193
-0
lines changed

Formula/w/wasi-runtimes.rb

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
class WasiRuntimes < Formula
2+
desc "Compiler-RT and libc++ runtimes for WASI"
3+
homepage "https://wasi.dev"
4+
url "https://github.com/llvm/llvm-project/releases/download/llvmorg-19.1.2/llvm-project-19.1.2.src.tar.xz"
5+
sha256 "3666f01fc52d8a0b0da83e107d74f208f001717824be0b80007f529453aa1e19"
6+
license "Apache-2.0" => { with: "LLVM-exception" }
7+
head "https://github.com/llvm/llvm-project.git", branch: "main"
8+
9+
livecheck do
10+
formula "llvm"
11+
end
12+
13+
depends_on "cmake" => :build
14+
depends_on "lld" => [:build, :test]
15+
depends_on "wasi-libc" => [:build, :test]
16+
depends_on "wasmtime" => :test
17+
depends_on "llvm"
18+
19+
def targets
20+
# See targets at:
21+
# https://github.com/WebAssembly/wasi-sdk/blob/5e04cd81eb749edb5642537d150ab1ab7aedabe9/CMakeLists.txt#L14-L15
22+
%w[
23+
wasm32-wasi
24+
wasm32-wasip1
25+
wasm32-wasip2
26+
wasm32-wasip1-threads
27+
wasm32-wasi-threads
28+
]
29+
end
30+
31+
def install
32+
wasi_libc = Formula["wasi-libc"]
33+
llvm = Formula["llvm"]
34+
# Compiler flags taken from:
35+
# https://github.com/WebAssembly/wasi-sdk/blob/5e04cd81eb749edb5642537d150ab1ab7aedabe9/cmake/wasi-sdk-sysroot.cmake#L37-L50
36+
common_cmake_args = %W[
37+
-DCMAKE_SYSTEM_NAME=WASI
38+
-DCMAKE_SYSTEM_VERSION=1
39+
-DCMAKE_SYSTEM_PROCESSOR=wasm32
40+
-DCMAKE_BUILD_TYPE=Release
41+
-DCMAKE_AR=#{llvm.opt_bin}/llvm-ar
42+
-DCMAKE_C_COMPILER=#{llvm.opt_bin}/clang
43+
-DCMAKE_CXX_COMPILER=#{llvm.opt_bin}/clang++
44+
-DCMAKE_C_COMPILER_WORKS=ON
45+
-DCMAKE_CXX_COMPILER_WORKS=ON
46+
-DCMAKE_SYSROOT=#{wasi_libc.opt_share}/wasi-sysroot
47+
]
48+
# Compiler flags taken from:
49+
# https://github.com/WebAssembly/wasi-sdk/blob/5e04cd81eb749edb5642537d150ab1ab7aedabe9/cmake/wasi-sdk-sysroot.cmake#L65-L75
50+
compiler_rt_args = %W[
51+
-DCMAKE_INSTALL_PREFIX=#{pkgshare}
52+
-DCOMPILER_RT_BAREMETAL_BUILD=ON
53+
-DCOMPILER_RT_BUILD_XRAY=OFF
54+
-DCOMPILER_RT_INCLUDE_TESTS=OFF
55+
-DCOMPILER_RT_HAS_FPIC_FLAG=OFF
56+
-DCOMPILER_RT_ENABLE_IOS=OFF
57+
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON
58+
-DCMAKE_C_COMPILER_TARGET=wasm32-wasi
59+
-DCOMPILER_RT_OS_DIR=wasi
60+
]
61+
ENV.append_to_cflags "-fdebug-prefix-map=#{buildpath}=wasisdk://v#{wasi_libc.version}"
62+
# Don't use `std_cmake_args`. It sets things like `CMAKE_OSX_SYSROOT`.
63+
system "cmake", "-S", "compiler-rt", "-B", "build-compiler-rt", *compiler_rt_args, *common_cmake_args
64+
system "cmake", "--build", "build-compiler-rt"
65+
system "cmake", "--install", "build-compiler-rt"
66+
(pkgshare/"lib").install_symlink "wasi" => "wasip1"
67+
(pkgshare/"lib").install_symlink "wasi" => "wasip2"
68+
69+
clang_resource_dir = Pathname.new(Utils.safe_popen_read(llvm.opt_bin/"clang", "-print-resource-dir").chomp)
70+
clang_resource_include_dir = clang_resource_dir/"include"
71+
clang_resource_include_dir.find do |pn|
72+
next unless pn.file?
73+
74+
relative_path = pn.relative_path_from(clang_resource_dir)
75+
target = pkgshare/relative_path
76+
next if target.exist?
77+
78+
target.parent.install_symlink pn
79+
end
80+
81+
target_configuration = Hash.new { |h, k| h[k] = {} }
82+
83+
targets.each do |target|
84+
# Configuration taken from:
85+
# https://github.com/WebAssembly/wasi-sdk/blob/5e04cd81eb749edb5642537d150ab1ab7aedabe9/cmake/wasi-sdk-sysroot.cmake#L227-L271
86+
configuration = target_configuration[target]
87+
configuration[:threads] = configuration[:pic] = target.end_with?("-threads") ? "ON" : "OFF"
88+
configuration[:flags] = target.end_with?("-threads") ? ["-pthread"] : []
89+
90+
cflags = ENV.cflags&.split || []
91+
cxxflags = ENV.cxxflags&.split || []
92+
93+
extra_flags = configuration.fetch(:flags)
94+
extra_flags += %W[
95+
--target=#{target}
96+
--sysroot=#{wasi_libc.opt_share}/wasi-sysroot
97+
-resource-dir=#{pkgshare}
98+
]
99+
cflags += extra_flags
100+
cxxflags += extra_flags
101+
102+
# FIXME: Upstream sets the equivalent of
103+
# `-DLIBCXX_ENABLE_SHARED=#{configuration.fetch(:pic)}`
104+
# `-DLIBCXXABI_ENABLE_SHARED=#{configuration.fetch(:pic)}`
105+
# but the build fails with linking errors.
106+
# See: https://github.com/WebAssembly/wasi-sdk/blob/5e04cd81eb749edb5642537d150ab1ab7aedabe9/cmake/wasi-sdk-sysroot.cmake#L227-L271
107+
target_cmake_args = %W[
108+
-DCMAKE_INSTALL_INCLUDEDIR=#{share}/wasi-sysroot/include/#{target}
109+
-DCMAKE_STAGING_PREFIX=#{share}/wasi-sysroot
110+
-DCMAKE_POSITION_INDEPENDENT_CODE=#{configuration.fetch(:pic)}
111+
-DCXX_SUPPORTS_CXX11=ON
112+
-DLIBCXX_ENABLE_THREADS:BOOL=#{configuration.fetch(:threads)}
113+
-DLIBCXX_HAS_PTHREAD_API:BOOL=#{configuration.fetch(:threads)}
114+
-DLIBCXX_HAS_EXTERNAL_THREAD_API:BOOL=OFF
115+
-DLIBCXX_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF
116+
-DLIBCXX_HAS_WIN32_THREAD_API:BOOL=OFF
117+
-DLLVM_COMPILER_CHECKED=ON
118+
-DLIBCXX_ENABLE_SHARED:BOOL=OFF
119+
-DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY:BOOL=OFF
120+
-DLIBCXX_ENABLE_EXCEPTIONS:BOOL=OFF
121+
-DLIBCXX_ENABLE_FILESYSTEM:BOOL=ON
122+
-DLIBCXX_ENABLE_ABI_LINKER_SCRIPT:BOOL=OFF
123+
-DLIBCXX_CXX_ABI=libcxxabi
124+
-DLIBCXX_CXX_ABI_INCLUDE_PATHS=#{testpath}/libcxxabi/include
125+
-DLIBCXX_HAS_MUSL_LIBC:BOOL=ON
126+
-DLIBCXX_ABI_VERSION=2
127+
-DLIBCXXABI_ENABLE_EXCEPTIONS:BOOL=OFF
128+
-DLIBCXXABI_ENABLE_SHARED:BOOL=OFF
129+
-DLIBCXXABI_SILENT_TERMINATE:BOOL=ON
130+
-DLIBCXXABI_ENABLE_THREADS:BOOL=#{configuration.fetch(:threads)}
131+
-DLIBCXXABI_HAS_PTHREAD_API:BOOL=#{configuration.fetch(:threads)}
132+
-DLIBCXXABI_HAS_EXTERNAL_THREAD_API:BOOL=OFF
133+
-DLIBCXXABI_BUILD_EXTERNAL_THREAD_LIBRARY:BOOL=OFF
134+
-DLIBCXXABI_HAS_WIN32_THREAD_API:BOOL=OFF
135+
-DLIBCXXABI_ENABLE_PIC:BOOL=#{configuration.fetch(:pic)}
136+
-DLIBCXXABI_USE_LLVM_UNWINDER:BOOL=OFF
137+
-DUNIX:BOOL=ON
138+
-DCMAKE_C_FLAGS=#{cflags.join(" ")}
139+
-DCMAKE_CXX_FLAGS=#{cxxflags.join(" ")}
140+
-DLIBCXX_LIBDIR_SUFFIX=/#{target}
141+
-DLIBCXXABI_LIBDIR_SUFFIX=/#{target}
142+
-DLIBCXX_INCLUDE_TESTS=OFF
143+
-DLIBCXX_INCLUDE_BENCHMARKS=OFF
144+
-DLLVM_ENABLE_RUNTIMES:STRING=libcxx;libcxxabi
145+
]
146+
147+
# Don't use `std_cmake_args`. It sets things like `CMAKE_OSX_SYSROOT`.
148+
system "cmake", "-S", "runtimes", "-B", "runtimes-#{target}", *target_cmake_args, *common_cmake_args
149+
system "cmake", "--build", "runtimes-#{target}"
150+
system "cmake", "--install", "runtimes-#{target}"
151+
end
152+
(share/"wasi-sysroot/include/c++/v1").mkpath
153+
touch share/"wasi-sysroot/include/c++/v1/.keepme"
154+
end
155+
156+
test do
157+
ENV.remove_macosxsdk if OS.mac?
158+
ENV.remove_cc_etc
159+
160+
(testpath/"test.c").write <<~C
161+
#include <stdio.h>
162+
volatile int x = 42;
163+
int main(void) {
164+
printf("the answer is %d", x);
165+
return 0;
166+
}
167+
C
168+
(testpath/"test.cc").write <<~CPP
169+
#include <iostream>
170+
171+
int main() {
172+
std::cout << "hello from C++ main with cout!" << std::endl;
173+
return 0;
174+
}
175+
CPP
176+
177+
clang = Formula["llvm"].opt_bin/"clang"
178+
wasm_args = %W[
179+
--sysroot=#{HOMEBREW_PREFIX}/share/wasi-sysroot
180+
-resource-dir=#{HOMEBREW_PREFIX}/share/wasi-runtimes
181+
]
182+
targets.each do |target|
183+
# FIXME: Needs a working `wasm-component-ld`.
184+
next if target.include?("wasip2")
185+
186+
system clang, "--target=#{target}", *wasm_args, "-v", "test.c", "-o", "test-#{target}"
187+
assert_equal "the answer is 42", shell_output("wasmtime #{testpath}/test-#{target}")
188+
189+
system "#{clang}++", "--target=#{target}", *wasm_args, "-v", "test.cc", "-o", "test-cxx-#{target}"
190+
assert_equal "hello from C++ main with cout!", shell_output("wasmtime #{testpath}/test-cxx-#{target}").chomp
191+
end
192+
end
193+
end

0 commit comments

Comments
 (0)