]> git.proxmox.com Git - wasi-libc.git/blob - Makefile
2f9e9fdeff12ccdfb1486e20533c8c1167d33f35
[wasi-libc.git] / Makefile
1 # These variables are specifically meant to be overridable via the make
2 # command-line.
3 # ?= doesn't work for CC and AR because make has a default value for them.
4 ifeq ($(origin CC), default)
5 CC := clang
6 endif
7 NM ?= $(patsubst %clang,%llvm-nm,$(filter-out ccache sccache,$(CC)))
8 ifeq ($(origin AR), default)
9 AR = $(patsubst %clang,%llvm-ar,$(filter-out ccache sccache,$(CC)))
10 endif
11 EXTRA_CFLAGS ?= -O2 -DNDEBUG
12 # The directory where we build the sysroot.
13 SYSROOT ?= $(CURDIR)/sysroot
14 # A directory to install to for "make install".
15 INSTALL_DIR ?= /usr/local
16 # single or posix; note that pthread support is still a work-in-progress.
17 THREAD_MODEL ?= single
18 # p1 or p2; the latter is not (yet) compatible with multithreading
19 WASI_SNAPSHOT ?= p1
20 # dlmalloc or none
21 MALLOC_IMPL ?= dlmalloc
22 # yes or no
23 BUILD_LIBC_TOP_HALF ?= yes
24 # yes or no
25 BUILD_LIBSETJMP ?= yes
26 # The directory where we will store intermediate artifacts.
27 OBJDIR ?= build/$(TARGET_TRIPLE)
28 # The directory where we store files and tools for generating WASIp2 bindings
29 BINDING_WORK_DIR ?= build/bindings
30 # URL from which to retrieve the WIT files used to generate the WASIp2 bindings
31 WASI_CLI_URL ?= https://github.com/WebAssembly/wasi-cli/archive/refs/tags/v0.2.0.tar.gz
32 # URL from which to retrieve the `wit-bindgen` command used to generate the
33 # WASIp2 bindings.
34 WIT_BINDGEN_URL ?= https://github.com/bytecodealliance/wit-bindgen/releases/download/wit-bindgen-cli-0.17.0/wit-bindgen-v0.17.0-x86_64-linux.tar.gz
35
36 # When the length is no larger than this threshold, we consider the
37 # overhead of bulk memory opcodes to outweigh the performance benefit,
38 # and fall back to the original musl implementation. See
39 # https://github.com/WebAssembly/wasi-libc/pull/263 for relevant
40 # discussion
41 BULK_MEMORY_THRESHOLD ?= 32
42
43 # Variables from this point on are not meant to be overridable via the
44 # make command-line.
45
46 # Set the default WASI target triple.
47 TARGET_TRIPLE = wasm32-wasi
48
49 # Threaded version necessitates a different target, as objects from different
50 # targets can't be mixed together while linking.
51 ifeq ($(THREAD_MODEL), posix)
52 TARGET_TRIPLE = wasm32-wasi-threads
53 endif
54
55 ifeq ($(WASI_SNAPSHOT), p2)
56 TARGET_TRIPLE = wasm32-wasip2
57 endif
58
59 BUILTINS_LIB ?= $(shell ${CC} --print-libgcc-file-name)
60
61 # These variables describe the locations of various files and directories in
62 # the source tree.
63 DLMALLOC_DIR = dlmalloc
64 DLMALLOC_SRC_DIR = $(DLMALLOC_DIR)/src
65 DLMALLOC_SOURCES = $(DLMALLOC_SRC_DIR)/dlmalloc.c
66 DLMALLOC_INC = $(DLMALLOC_DIR)/include
67 EMMALLOC_DIR = emmalloc
68 EMMALLOC_SOURCES = $(EMMALLOC_DIR)/emmalloc.c
69 LIBC_BOTTOM_HALF_DIR = libc-bottom-half
70 LIBC_BOTTOM_HALF_CLOUDLIBC_SRC = $(LIBC_BOTTOM_HALF_DIR)/cloudlibc/src
71 LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_INC = $(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/include
72 LIBC_BOTTOM_HALF_HEADERS_PUBLIC = $(LIBC_BOTTOM_HALF_DIR)/headers/public
73 LIBC_BOTTOM_HALF_HEADERS_PRIVATE = $(LIBC_BOTTOM_HALF_DIR)/headers/private
74 LIBC_BOTTOM_HALF_SOURCES = $(LIBC_BOTTOM_HALF_DIR)/sources
75 LIBC_BOTTOM_HALF_ALL_SOURCES = \
76 $(sort \
77 $(shell find $(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC) -name \*.c) \
78 $(shell find $(LIBC_BOTTOM_HALF_SOURCES) -name \*.c))
79
80 ifeq ($(WASI_SNAPSHOT), p1)
81 # Omit source files not relevant to WASIp1. As we introduce files
82 # supporting `wasi-sockets` for `wasm32-wasip2`, we'll add those files to
83 # this list.
84 LIBC_BOTTOM_HALF_OMIT_SOURCES := \
85 $(LIBC_BOTTOM_HALF_SOURCES)/wasip2.c \
86 $(LIBC_BOTTOM_HALF_SOURCES)/descriptor_table.c \
87 $(LIBC_BOTTOM_HALF_SOURCES)/connect.c \
88 $(LIBC_BOTTOM_HALF_SOURCES)/socket.c \
89 $(LIBC_BOTTOM_HALF_SOURCES)/send.c \
90 $(LIBC_BOTTOM_HALF_SOURCES)/recv.c \
91 $(LIBC_BOTTOM_HALF_SOURCES)/sockets_utils.c \
92 $(LIBC_BOTTOM_HALF_SOURCES)/bind.c \
93 $(LIBC_BOTTOM_HALF_SOURCES)/listen.c \
94 $(LIBC_BOTTOM_HALF_SOURCES)/accept-wasip2.c \
95 $(LIBC_BOTTOM_HALF_SOURCES)/shutdown.c \
96 $(LIBC_BOTTOM_HALF_SOURCES)/sockopt.c \
97 $(LIBC_BOTTOM_HALF_SOURCES)/poll-wasip2.c \
98 $(LIBC_BOTTOM_HALF_SOURCES)/getsockpeername.c \
99 $(LIBC_BOTTOM_HALF_SOURCES)/netdb.c
100 LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
101 # Omit p2-specific headers from include-all.c test.
102 # for exception-handling.
103 INCLUDE_ALL_CLAUSES := -not -name wasip2.h -not -name descriptor_table.h
104 endif
105
106 ifeq ($(WASI_SNAPSHOT), p2)
107 # Omit source files not relevant to WASIp2.
108 LIBC_BOTTOM_HALF_OMIT_SOURCES := \
109 $(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/send.c \
110 $(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/recv.c \
111 $(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/shutdown.c \
112 $(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)/libc/sys/socket/getsockopt.c \
113 $(LIBC_BOTTOM_HALF_SOURCES)/accept-wasip1.c
114 LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_OMIT_SOURCES),$(LIBC_BOTTOM_HALF_ALL_SOURCES))
115 endif
116
117 # FIXME(https://reviews.llvm.org/D85567) - due to a bug in LLD the weak
118 # references to a function defined in `chdir.c` only work if `chdir.c` is at the
119 # end of the archive, but once that LLD review lands and propagates into LLVM
120 # then we don't have to do this.
121 LIBC_BOTTOM_HALF_ALL_SOURCES := $(filter-out $(LIBC_BOTTOM_HALF_SOURCES)/chdir.c,$(LIBC_BOTTOM_HALF_ALL_SOURCES))
122 LIBC_BOTTOM_HALF_ALL_SOURCES := $(LIBC_BOTTOM_HALF_ALL_SOURCES) $(LIBC_BOTTOM_HALF_SOURCES)/chdir.c
123
124 LIBWASI_EMULATED_MMAN_SOURCES = \
125 $(sort $(shell find $(LIBC_BOTTOM_HALF_DIR)/mman -name \*.c))
126 LIBWASI_EMULATED_PROCESS_CLOCKS_SOURCES = \
127 $(sort $(shell find $(LIBC_BOTTOM_HALF_DIR)/clocks -name \*.c))
128 LIBWASI_EMULATED_GETPID_SOURCES = \
129 $(sort $(shell find $(LIBC_BOTTOM_HALF_DIR)/getpid -name \*.c))
130 LIBWASI_EMULATED_SIGNAL_SOURCES = \
131 $(sort $(shell find $(LIBC_BOTTOM_HALF_DIR)/signal -name \*.c))
132 LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES = \
133 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/signal/psignal.c \
134 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/string/strsignal.c
135 LIBDL_SOURCES = $(LIBC_TOP_HALF_MUSL_SRC_DIR)/misc/dl.c
136 LIBSETJMP_SOURCES = $(LIBC_TOP_HALF_MUSL_SRC_DIR)/setjmp/wasm32/rt.c
137 LIBC_BOTTOM_HALF_CRT_SOURCES = $(wildcard $(LIBC_BOTTOM_HALF_DIR)/crt/*.c)
138 LIBC_TOP_HALF_DIR = libc-top-half
139 LIBC_TOP_HALF_MUSL_DIR = $(LIBC_TOP_HALF_DIR)/musl
140 LIBC_TOP_HALF_MUSL_SRC_DIR = $(LIBC_TOP_HALF_MUSL_DIR)/src
141 LIBC_TOP_HALF_MUSL_INC = $(LIBC_TOP_HALF_MUSL_DIR)/include
142 LIBC_TOP_HALF_MUSL_SOURCES = \
143 $(addprefix $(LIBC_TOP_HALF_MUSL_SRC_DIR)/, \
144 misc/a64l.c \
145 misc/basename.c \
146 misc/dirname.c \
147 misc/ffs.c \
148 misc/ffsl.c \
149 misc/ffsll.c \
150 misc/fmtmsg.c \
151 misc/getdomainname.c \
152 misc/gethostid.c \
153 misc/getopt.c \
154 misc/getopt_long.c \
155 misc/getsubopt.c \
156 misc/realpath.c \
157 misc/uname.c \
158 misc/nftw.c \
159 errno/strerror.c \
160 network/htonl.c \
161 network/htons.c \
162 network/ntohl.c \
163 network/ntohs.c \
164 network/inet_ntop.c \
165 network/inet_pton.c \
166 network/inet_aton.c \
167 network/in6addr_any.c \
168 network/in6addr_loopback.c \
169 fenv/fenv.c \
170 fenv/fesetround.c \
171 fenv/feupdateenv.c \
172 fenv/fesetexceptflag.c \
173 fenv/fegetexceptflag.c \
174 fenv/feholdexcept.c \
175 exit/exit.c \
176 exit/atexit.c \
177 exit/assert.c \
178 exit/quick_exit.c \
179 exit/at_quick_exit.c \
180 time/strftime.c \
181 time/asctime.c \
182 time/asctime_r.c \
183 time/ctime.c \
184 time/ctime_r.c \
185 time/wcsftime.c \
186 time/strptime.c \
187 time/difftime.c \
188 time/timegm.c \
189 time/ftime.c \
190 time/gmtime.c \
191 time/gmtime_r.c \
192 time/timespec_get.c \
193 time/getdate.c \
194 time/localtime.c \
195 time/localtime_r.c \
196 time/mktime.c \
197 time/__tm_to_secs.c \
198 time/__month_to_secs.c \
199 time/__secs_to_tm.c \
200 time/__year_to_secs.c \
201 time/__tz.c \
202 fcntl/creat.c \
203 dirent/alphasort.c \
204 dirent/versionsort.c \
205 env/__stack_chk_fail.c \
206 env/clearenv.c \
207 env/getenv.c \
208 env/putenv.c \
209 env/setenv.c \
210 env/unsetenv.c \
211 unistd/posix_close.c \
212 stat/futimesat.c \
213 legacy/getpagesize.c \
214 thread/thrd_sleep.c \
215 ) \
216 $(filter-out %/procfdname.c %/syscall.c %/syscall_ret.c %/vdso.c %/version.c, \
217 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal/*.c)) \
218 $(filter-out %/flockfile.c %/funlockfile.c %/__lockfile.c %/ftrylockfile.c \
219 %/rename.c \
220 %/tmpnam.c %/tmpfile.c %/tempnam.c \
221 %/popen.c %/pclose.c \
222 %/remove.c \
223 %/gets.c, \
224 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdio/*.c)) \
225 $(filter-out %/strsignal.c, \
226 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/string/*.c)) \
227 $(filter-out %/dcngettext.c %/textdomain.c %/bind_textdomain_codeset.c, \
228 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/locale/*.c)) \
229 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdlib/*.c) \
230 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/search/*.c) \
231 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/multibyte/*.c) \
232 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/regex/*.c) \
233 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/prng/*.c) \
234 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/conf/*.c) \
235 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/ctype/*.c) \
236 $(filter-out %/__signbit.c %/__signbitf.c %/__signbitl.c \
237 %/__fpclassify.c %/__fpclassifyf.c %/__fpclassifyl.c \
238 %/ceilf.c %/ceil.c \
239 %/floorf.c %/floor.c \
240 %/truncf.c %/trunc.c \
241 %/rintf.c %/rint.c \
242 %/nearbyintf.c %/nearbyint.c \
243 %/sqrtf.c %/sqrt.c \
244 %/fabsf.c %/fabs.c \
245 %/copysignf.c %/copysign.c \
246 %/fminf.c %/fmaxf.c \
247 %/fmin.c %/fmax.c, \
248 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/math/*.c)) \
249 $(filter-out %/crealf.c %/creal.c %creall.c \
250 %/cimagf.c %/cimag.c %cimagl.c, \
251 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/complex/*.c)) \
252 $(wildcard $(LIBC_TOP_HALF_MUSL_SRC_DIR)/crypt/*.c)
253
254 ifeq ($(WASI_SNAPSHOT), p2)
255 LIBC_TOP_HALF_MUSL_SOURCES += \
256 $(addprefix $(LIBC_TOP_HALF_MUSL_SRC_DIR)/, \
257 network/gai_strerror.c \
258 )
259 endif
260
261 ifeq ($(THREAD_MODEL), posix)
262 LIBC_TOP_HALF_MUSL_SOURCES += \
263 $(addprefix $(LIBC_TOP_HALF_MUSL_SRC_DIR)/, \
264 env/__init_tls.c \
265 stdio/__lockfile.c \
266 stdio/flockfile.c \
267 stdio/ftrylockfile.c \
268 stdio/funlockfile.c \
269 thread/__lock.c \
270 thread/__wait.c \
271 thread/__timedwait.c \
272 thread/default_attr.c \
273 thread/pthread_attr_destroy.c \
274 thread/pthread_attr_get.c \
275 thread/pthread_attr_init.c \
276 thread/pthread_attr_setstack.c \
277 thread/pthread_attr_setdetachstate.c \
278 thread/pthread_attr_setstacksize.c \
279 thread/pthread_barrier_destroy.c \
280 thread/pthread_barrier_init.c \
281 thread/pthread_barrier_wait.c \
282 thread/pthread_cleanup_push.c \
283 thread/pthread_cond_broadcast.c \
284 thread/pthread_cond_destroy.c \
285 thread/pthread_cond_init.c \
286 thread/pthread_cond_signal.c \
287 thread/pthread_cond_timedwait.c \
288 thread/pthread_cond_wait.c \
289 thread/pthread_condattr_destroy.c \
290 thread/pthread_condattr_init.c \
291 thread/pthread_condattr_setclock.c \
292 thread/pthread_condattr_setpshared.c \
293 thread/pthread_create.c \
294 thread/pthread_detach.c \
295 thread/pthread_equal.c \
296 thread/pthread_getattr_np.c \
297 thread/pthread_getspecific.c \
298 thread/pthread_join.c \
299 thread/pthread_key_create.c \
300 thread/pthread_mutex_consistent.c \
301 thread/pthread_mutex_destroy.c \
302 thread/pthread_mutex_init.c \
303 thread/pthread_mutex_getprioceiling.c \
304 thread/pthread_mutex_lock.c \
305 thread/pthread_mutex_timedlock.c \
306 thread/pthread_mutex_trylock.c \
307 thread/pthread_mutex_unlock.c \
308 thread/pthread_mutexattr_destroy.c \
309 thread/pthread_mutexattr_init.c \
310 thread/pthread_mutexattr_setprotocol.c \
311 thread/pthread_mutexattr_setpshared.c \
312 thread/pthread_mutexattr_setrobust.c \
313 thread/pthread_mutexattr_settype.c \
314 thread/pthread_once.c \
315 thread/pthread_rwlock_destroy.c \
316 thread/pthread_rwlock_init.c \
317 thread/pthread_rwlock_rdlock.c \
318 thread/pthread_rwlock_timedrdlock.c \
319 thread/pthread_rwlock_timedwrlock.c \
320 thread/pthread_rwlock_tryrdlock.c \
321 thread/pthread_rwlock_trywrlock.c \
322 thread/pthread_rwlock_unlock.c \
323 thread/pthread_rwlock_wrlock.c \
324 thread/pthread_rwlockattr_destroy.c \
325 thread/pthread_rwlockattr_init.c \
326 thread/pthread_rwlockattr_setpshared.c \
327 thread/pthread_setcancelstate.c \
328 thread/pthread_setspecific.c \
329 thread/pthread_self.c \
330 thread/pthread_spin_destroy.c \
331 thread/pthread_spin_init.c \
332 thread/pthread_spin_lock.c \
333 thread/pthread_spin_trylock.c \
334 thread/pthread_spin_unlock.c \
335 thread/pthread_testcancel.c \
336 thread/sem_destroy.c \
337 thread/sem_getvalue.c \
338 thread/sem_init.c \
339 thread/sem_post.c \
340 thread/sem_timedwait.c \
341 thread/sem_trywait.c \
342 thread/sem_wait.c \
343 thread/wasm32/wasi_thread_start.s \
344 )
345 endif
346
347 MUSL_PRINTSCAN_SOURCES = \
348 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal/floatscan.c \
349 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdio/vfprintf.c \
350 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdio/vfwprintf.c \
351 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdio/vfscanf.c \
352 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdlib/strtod.c \
353 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/stdlib/wcstod.c
354 BULK_MEMORY_SOURCES = \
355 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/string/memcpy.c \
356 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/string/memmove.c \
357 $(LIBC_TOP_HALF_MUSL_SRC_DIR)/string/memset.c
358 LIBC_TOP_HALF_HEADERS_PRIVATE = $(LIBC_TOP_HALF_DIR)/headers/private
359 LIBC_TOP_HALF_SOURCES = $(LIBC_TOP_HALF_DIR)/sources
360 LIBC_TOP_HALF_ALL_SOURCES = \
361 $(LIBC_TOP_HALF_MUSL_SOURCES) \
362 $(sort $(shell find $(LIBC_TOP_HALF_SOURCES) -name \*.[cs]))
363
364 # Add any extra flags
365 CFLAGS = $(EXTRA_CFLAGS)
366 # Set the target.
367 CFLAGS += --target=$(TARGET_TRIPLE)
368 ASMFLAGS += --target=$(TARGET_TRIPLE)
369 # WebAssembly floating-point match doesn't trap.
370 # TODO: Add -fno-signaling-nans when the compiler supports it.
371 CFLAGS += -fno-trapping-math
372 # Add all warnings, but disable a few which occur in third-party code.
373 CFLAGS += -Wall -Wextra -Werror \
374 -Wno-null-pointer-arithmetic \
375 -Wno-unused-parameter \
376 -Wno-sign-compare \
377 -Wno-unused-variable \
378 -Wno-unused-function \
379 -Wno-ignored-attributes \
380 -Wno-missing-braces \
381 -Wno-ignored-pragmas \
382 -Wno-unused-but-set-variable \
383 -Wno-unknown-warning-option
384
385 # Configure support for threads.
386 ifeq ($(THREAD_MODEL), single)
387 CFLAGS += -mthread-model single
388 endif
389 ifeq ($(THREAD_MODEL), posix)
390 # Specify the tls-model until LLVM 15 is released (which should contain
391 # https://reviews.llvm.org/D130053).
392 CFLAGS += -mthread-model posix -pthread -ftls-model=local-exec
393 ASMFLAGS += -matomics
394
395 # Include cloudlib's directory to access the structure definition of clockid_t
396 CFLAGS += -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)
397 endif
398
399 ifeq ($(WASI_SNAPSHOT), p2)
400 EXTRA_CFLAGS += -D__wasilibc_use_wasip2
401 endif
402
403 # Expose the public headers to the implementation. We use `-isystem` for
404 # purpose for two reasons:
405 #
406 # 1. It only does `<...>` not `"...."` lookup. We are making a libc,
407 # which is a system library, so all public headers should be
408 # accessible via `<...>` and never also need `"..."`. `-isystem` main
409 # purpose is to only effect `<...>` lookup.
410 #
411 # 2. The `-I` for private headers added for specific C files below
412 # should come earlier in the search path, so they can "override"
413 # and/or `#include_next` the public headers. `-isystem` (like
414 # `-idirafter`) comes later in the search path than `-I`.
415 CFLAGS += -isystem "$(SYSROOT_INC)"
416
417 # These variables describe the locations of various files and directories in
418 # the build tree.
419 objs = $(patsubst %.c,$(OBJDIR)/%.o,$(1))
420 asmobjs = $(patsubst %.s,$(OBJDIR)/%.o,$(1))
421 DLMALLOC_OBJS = $(call objs,$(DLMALLOC_SOURCES))
422 EMMALLOC_OBJS = $(call objs,$(EMMALLOC_SOURCES))
423 LIBC_BOTTOM_HALF_ALL_OBJS = $(call objs,$(LIBC_BOTTOM_HALF_ALL_SOURCES))
424 LIBC_TOP_HALF_ALL_OBJS = $(call asmobjs,$(call objs,$(LIBC_TOP_HALF_ALL_SOURCES)))
425 ifeq ($(WASI_SNAPSHOT), p2)
426 LIBC_OBJS += $(OBJDIR)/wasip2_component_type.o
427 endif
428 ifeq ($(MALLOC_IMPL),dlmalloc)
429 LIBC_OBJS += $(DLMALLOC_OBJS)
430 else ifeq ($(MALLOC_IMPL),emmalloc)
431 LIBC_OBJS += $(EMMALLOC_OBJS)
432 else ifeq ($(MALLOC_IMPL),none)
433 # No object files to add.
434 else
435 $(error unknown malloc implementation $(MALLOC_IMPL))
436 endif
437 # Add libc-bottom-half's objects.
438 LIBC_OBJS += $(LIBC_BOTTOM_HALF_ALL_OBJS)
439 ifeq ($(BUILD_LIBC_TOP_HALF),yes)
440 # libc-top-half is musl.
441 LIBC_OBJS += $(LIBC_TOP_HALF_ALL_OBJS)
442 endif
443 MUSL_PRINTSCAN_OBJS = $(call objs,$(MUSL_PRINTSCAN_SOURCES))
444 MUSL_PRINTSCAN_LONG_DOUBLE_OBJS = $(patsubst %.o,%.long-double.o,$(MUSL_PRINTSCAN_OBJS))
445 MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS = $(patsubst %.o,%.no-floating-point.o,$(MUSL_PRINTSCAN_OBJS))
446 BULK_MEMORY_OBJS = $(call objs,$(BULK_MEMORY_SOURCES))
447 LIBWASI_EMULATED_MMAN_OBJS = $(call objs,$(LIBWASI_EMULATED_MMAN_SOURCES))
448 LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS = $(call objs,$(LIBWASI_EMULATED_PROCESS_CLOCKS_SOURCES))
449 LIBWASI_EMULATED_GETPID_OBJS = $(call objs,$(LIBWASI_EMULATED_GETPID_SOURCES))
450 LIBWASI_EMULATED_SIGNAL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_SOURCES))
451 LIBWASI_EMULATED_SIGNAL_MUSL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES))
452 LIBDL_OBJS = $(call objs,$(LIBDL_SOURCES))
453 LIBSETJMP_OBJS = $(call objs,$(LIBSETJMP_SOURCES))
454 LIBC_BOTTOM_HALF_CRT_OBJS = $(call objs,$(LIBC_BOTTOM_HALF_CRT_SOURCES))
455
456 # These variables describe the locations of various files and
457 # directories in the generated sysroot tree.
458 SYSROOT_LIB := $(SYSROOT)/lib/$(TARGET_TRIPLE)
459 SYSROOT_INC = $(SYSROOT)/include/$(TARGET_TRIPLE)
460 SYSROOT_SHARE = $(SYSROOT)/share/$(TARGET_TRIPLE)
461
462 # Files from musl's include directory that we don't want to install in the
463 # sysroot's include directory.
464 MUSL_OMIT_HEADERS :=
465
466 # Remove files which aren't headers (we generate alltypes.h below).
467 MUSL_OMIT_HEADERS += \
468 "bits/syscall.h.in" \
469 "bits/alltypes.h.in" \
470 "alltypes.h.in"
471
472 # Use the compiler's version of these headers.
473 MUSL_OMIT_HEADERS += \
474 "stdarg.h" \
475 "stddef.h"
476
477 # Use the WASI errno definitions.
478 MUSL_OMIT_HEADERS += \
479 "bits/errno.h"
480
481 # Remove headers that aren't supported yet or that aren't relevant for WASI.
482 MUSL_OMIT_HEADERS += \
483 "sys/procfs.h" \
484 "sys/user.h" \
485 "sys/kd.h" "sys/vt.h" "sys/soundcard.h" "sys/sem.h" \
486 "sys/shm.h" "sys/msg.h" "sys/ipc.h" "sys/ptrace.h" \
487 "sys/statfs.h" \
488 "bits/kd.h" "bits/vt.h" "bits/soundcard.h" "bits/sem.h" \
489 "bits/shm.h" "bits/msg.h" "bits/ipc.h" "bits/ptrace.h" \
490 "bits/statfs.h" \
491 "sys/vfs.h" \
492 "syslog.h" "sys/syslog.h" \
493 "wait.h" "sys/wait.h" \
494 "ucontext.h" "sys/ucontext.h" \
495 "paths.h" \
496 "utmp.h" "utmpx.h" \
497 "lastlog.h" \
498 "sys/acct.h" \
499 "sys/cachectl.h" \
500 "sys/epoll.h" "sys/reboot.h" "sys/swap.h" \
501 "sys/sendfile.h" "sys/inotify.h" \
502 "sys/quota.h" \
503 "sys/klog.h" \
504 "sys/fsuid.h" \
505 "sys/io.h" \
506 "sys/prctl.h" \
507 "sys/mtio.h" \
508 "sys/mount.h" \
509 "sys/fanotify.h" \
510 "sys/personality.h" \
511 "elf.h" "link.h" "bits/link.h" \
512 "scsi/scsi.h" "scsi/scsi_ioctl.h" "scsi/sg.h" \
513 "sys/auxv.h" \
514 "pwd.h" "shadow.h" "grp.h" \
515 "mntent.h" \
516 "resolv.h" \
517 "pty.h" \
518 "ulimit.h" \
519 "sys/xattr.h" \
520 "wordexp.h" \
521 "spawn.h" \
522 "sys/membarrier.h" \
523 "sys/signalfd.h" \
524 "termios.h" \
525 "sys/termios.h" \
526 "bits/termios.h" \
527 "net/if.h" \
528 "net/if_arp.h" \
529 "net/ethernet.h" \
530 "net/route.h" \
531 "netinet/if_ether.h" \
532 "netinet/ether.h" \
533 "sys/timerfd.h" \
534 "libintl.h" \
535 "sys/sysmacros.h" \
536 "aio.h"
537
538 ifeq ($(WASI_SNAPSHOT), p1)
539 MUSL_OMIT_HEADERS += "netdb.h"
540 endif
541
542 ifeq ($(THREAD_MODEL), single)
543 # Remove headers not supported in single-threaded mode.
544 MUSL_OMIT_HEADERS += "pthread.h"
545 endif
546
547 default: finish
548
549 LIBC_SO_OBJS = $(patsubst %.o,%.pic.o,$(filter-out $(MUSL_PRINTSCAN_OBJS),$(LIBC_OBJS)))
550 MUSL_PRINTSCAN_LONG_DOUBLE_SO_OBJS = $(patsubst %.o,%.pic.o,$(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS))
551 LIBWASI_EMULATED_MMAN_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_MMAN_OBJS))
552 LIBWASI_EMULATED_PROCESS_CLOCKS_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS))
553 LIBWASI_EMULATED_GETPID_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_GETPID_OBJS))
554 LIBWASI_EMULATED_SIGNAL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_SIGNAL_OBJS))
555 LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS))
556 LIBDL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBDL_OBJS))
557 LIBSETJMP_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBSETJMP_OBJS))
558 BULK_MEMORY_SO_OBJS = $(patsubst %.o,%.pic.o,$(BULK_MEMORY_OBJS))
559 DLMALLOC_SO_OBJS = $(patsubst %.o,%.pic.o,$(DLMALLOC_OBJS))
560 LIBC_BOTTOM_HALF_ALL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBC_BOTTOM_HALF_ALL_OBJS))
561 LIBC_TOP_HALF_ALL_SO_OBJS = $(patsubst %.o,%.pic.o,$(LIBC_TOP_HALF_ALL_OBJS))
562
563 PIC_OBJS = \
564 $(LIBC_SO_OBJS) \
565 $(MUSL_PRINTSCAN_LONG_DOUBLE_SO_OBJS) \
566 $(LIBWASI_EMULATED_MMAN_SO_OBJS) \
567 $(LIBWASI_EMULATED_PROCESS_CLOCKS_SO_OBJS) \
568 $(LIBWASI_EMULATED_GETPID_SO_OBJS) \
569 $(LIBWASI_EMULATED_SIGNAL_SO_OBJS) \
570 $(LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS) \
571 $(LIBDL_SO_OBJS) \
572 $(LIBSETJMP_SO_OBJS) \
573 $(BULK_MEMORY_SO_OBJS) \
574 $(DLMALLOC_SO_OBJS) \
575 $(LIBC_BOTTOM_HALF_ALL_SO_OBJS) \
576 $(LIBC_TOP_HALF_ALL_SO_OBJS) \
577 $(LIBC_BOTTOM_HALF_CRT_OBJS)
578
579 # TODO: Specify SDK version, e.g. libc.so.wasi-sdk-21, as SO_NAME once `wasm-ld`
580 # supports it.
581 #
582 # Note that we collect the object files for each shared library into a .a and
583 # link that using `--whole-archive` rather than pass the object files directly
584 # to CC. This is a workaround for a Windows command line size limitation. See
585 # the `%.a` rule below for details.
586 $(SYSROOT_LIB)/%.so: $(OBJDIR)/%.so.a $(BUILTINS_LIB)
587 $(CC) --target=$(TARGET_TRIPLE) -nodefaultlibs -shared --sysroot=$(SYSROOT) \
588 -o $@ -Wl,--whole-archive $< -Wl,--no-whole-archive $(BUILTINS_LIB)
589
590 $(OBJDIR)/libc.so.a: $(LIBC_SO_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_SO_OBJS)
591
592 $(OBJDIR)/libwasi-emulated-mman.so.a: $(LIBWASI_EMULATED_MMAN_SO_OBJS)
593
594 $(OBJDIR)/libwasi-emulated-process-clocks.so.a: $(LIBWASI_EMULATED_PROCESS_CLOCKS_SO_OBJS)
595
596 $(OBJDIR)/libwasi-emulated-getpid.so.a: $(LIBWASI_EMULATED_GETPID_SO_OBJS)
597
598 $(OBJDIR)/libwasi-emulated-signal.so.a: $(LIBWASI_EMULATED_SIGNAL_SO_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS)
599
600 $(OBJDIR)/libdl.so.a: $(LIBDL_SO_OBJS)
601
602 $(OBJDIR)/libsetjmp.so.a: $(LIBSETJMP_SO_OBJS)
603
604 $(SYSROOT_LIB)/libc.a: $(LIBC_OBJS)
605
606 $(SYSROOT_LIB)/libc-printscan-long-double.a: $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS)
607
608 $(SYSROOT_LIB)/libc-printscan-no-floating-point.a: $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS)
609
610 $(SYSROOT_LIB)/libwasi-emulated-mman.a: $(LIBWASI_EMULATED_MMAN_OBJS)
611
612 $(SYSROOT_LIB)/libwasi-emulated-process-clocks.a: $(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS)
613
614 $(SYSROOT_LIB)/libwasi-emulated-getpid.a: $(LIBWASI_EMULATED_GETPID_OBJS)
615
616 $(SYSROOT_LIB)/libwasi-emulated-signal.a: $(LIBWASI_EMULATED_SIGNAL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS)
617
618 $(SYSROOT_LIB)/libdl.a: $(LIBDL_OBJS)
619
620 $(SYSROOT_LIB)/libsetjmp.a: $(LIBSETJMP_OBJS)
621
622 %.a:
623 @mkdir -p "$(@D)"
624 # On Windows, the commandline for the ar invocation got too long, so it needs to be split up.
625 $(AR) crs $@ $(wordlist 1, 199, $(sort $^))
626 $(AR) crs $@ $(wordlist 200, 399, $(sort $^))
627 $(AR) crs $@ $(wordlist 400, 599, $(sort $^))
628 $(AR) crs $@ $(wordlist 600, 799, $(sort $^))
629 # This might eventually overflow again, but at least it'll do so in a loud way instead of
630 # silently dropping the tail.
631 $(AR) crs $@ $(wordlist 800, 100000, $(sort $^))
632
633 $(PIC_OBJS): CFLAGS += -fPIC -fvisibility=default
634
635 $(MUSL_PRINTSCAN_OBJS): CFLAGS += \
636 -D__wasilibc_printscan_no_long_double \
637 -D__wasilibc_printscan_full_support_option="\"add -lc-printscan-long-double to the link command\""
638
639 $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS): CFLAGS += \
640 -D__wasilibc_printscan_no_floating_point \
641 -D__wasilibc_printscan_floating_point_support_option="\"remove -lc-printscan-no-floating-point from the link command\""
642
643 # TODO: apply -mbulk-memory globally, once
644 # https://github.com/llvm/llvm-project/issues/52618 is resolved
645 $(BULK_MEMORY_OBJS) $(BULK_MEMORY_SO_OBJS): CFLAGS += \
646 -mbulk-memory
647
648 $(BULK_MEMORY_OBJS) $(BULK_MEMORY_SO_OBJS): CFLAGS += \
649 -DBULK_MEMORY_THRESHOLD=$(BULK_MEMORY_THRESHOLD)
650
651 $(LIBSETJMP_OBJS) $(LIBSETJMP_SO_OBJS): CFLAGS += \
652 -mllvm -wasm-enable-sjlj
653
654 $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS): CFLAGS += \
655 -D_WASI_EMULATED_SIGNAL
656
657 $(OBJDIR)/%.long-double.pic.o: %.c include_dirs
658 @mkdir -p "$(@D)"
659 $(CC) $(CFLAGS) -MD -MP -o $@ -c $<
660
661 $(OBJDIR)/wasip2_component_type.pic.o $(OBJDIR)/wasip2_component_type.o: $(LIBC_BOTTOM_HALF_SOURCES)/wasip2_component_type.o
662 @mkdir -p "$(@D)"
663 cp $< $@
664
665 $(OBJDIR)/%.pic.o: %.c include_dirs
666 @mkdir -p "$(@D)"
667 $(CC) $(CFLAGS) -MD -MP -o $@ -c $<
668
669 $(OBJDIR)/%.long-double.o: %.c include_dirs
670 @mkdir -p "$(@D)"
671 $(CC) $(CFLAGS) -MD -MP -o $@ -c $<
672
673 $(OBJDIR)/%.no-floating-point.o: %.c include_dirs
674 @mkdir -p "$(@D)"
675 $(CC) $(CFLAGS) -MD -MP -o $@ -c $<
676
677 $(OBJDIR)/%.o: %.c include_dirs
678 @mkdir -p "$(@D)"
679 $(CC) $(CFLAGS) -MD -MP -o $@ -c $<
680
681 $(OBJDIR)/%.o: %.s include_dirs
682 @mkdir -p "$(@D)"
683 $(CC) $(ASMFLAGS) -o $@ -c $<
684
685 -include $(shell find $(OBJDIR) -name \*.d)
686
687 $(DLMALLOC_OBJS) $(DLMALLOC_SO_OBJS): CFLAGS += \
688 -I$(DLMALLOC_INC)
689
690 startup_files $(LIBC_BOTTOM_HALF_ALL_OBJS) $(LIBC_BOTTOM_HALF_ALL_SO_OBJS): CFLAGS += \
691 -I$(LIBC_BOTTOM_HALF_HEADERS_PRIVATE) \
692 -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC_INC) \
693 -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC) \
694 -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/include \
695 -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal
696
697 $(LIBC_TOP_HALF_ALL_OBJS) $(LIBC_TOP_HALF_ALL_SO_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_OBJS) $(MUSL_PRINTSCAN_LONG_DOUBLE_SO_OBJS) $(MUSL_PRINTSCAN_NO_FLOATING_POINT_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS) $(LIBWASI_EMULATED_SIGNAL_MUSL_SO_OBJS) $(LIBDL_OBJS) $(LIBDL_SO_OBJS) $(LIBSETJMP_OBJS) $(LIBSETJMP_SO_OBJS): CFLAGS += \
698 -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/include \
699 -I$(LIBC_TOP_HALF_MUSL_SRC_DIR)/internal \
700 -I$(LIBC_TOP_HALF_MUSL_DIR)/arch/wasm32 \
701 -I$(LIBC_TOP_HALF_MUSL_DIR)/arch/generic \
702 -I$(LIBC_TOP_HALF_HEADERS_PRIVATE) \
703 -Wno-parentheses \
704 -Wno-shift-op-parentheses \
705 -Wno-bitwise-op-parentheses \
706 -Wno-logical-op-parentheses \
707 -Wno-string-plus-int \
708 -Wno-dangling-else \
709 -Wno-unknown-pragmas
710
711 $(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS) $(LIBWASI_EMULATED_PROCESS_CLOCKS_SO_OBJS): CFLAGS += \
712 -I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)
713
714 # emmalloc uses a lot of pointer type-punning, which is UB under strict aliasing,
715 # and this was found to have real miscompilations in wasi-libc#421.
716 $(EMMALLOC_OBJS): CFLAGS += \
717 -fno-strict-aliasing
718
719 include_dirs:
720 #
721 # Install the include files.
722 #
723 mkdir -p "$(SYSROOT_INC)"
724 cp -r "$(LIBC_BOTTOM_HALF_HEADERS_PUBLIC)"/* "$(SYSROOT_INC)"
725
726 # Generate musl's bits/alltypes.h header.
727 mkdir -p "$(SYSROOT_INC)/bits"
728 sed -f $(LIBC_TOP_HALF_MUSL_DIR)/tools/mkalltypes.sed \
729 $(LIBC_TOP_HALF_MUSL_DIR)/arch/wasm32/bits/alltypes.h.in \
730 $(LIBC_TOP_HALF_MUSL_DIR)/include/alltypes.h.in \
731 > "$(SYSROOT_INC)/bits/alltypes.h"
732
733 # Copy in the bulk of musl's public header files.
734 cp -r "$(LIBC_TOP_HALF_MUSL_INC)"/* "$(SYSROOT_INC)"
735 # Copy in the musl's "bits" header files.
736 cp -r "$(LIBC_TOP_HALF_MUSL_DIR)"/arch/generic/bits/* "$(SYSROOT_INC)/bits"
737 cp -r "$(LIBC_TOP_HALF_MUSL_DIR)"/arch/wasm32/bits/* "$(SYSROOT_INC)/bits"
738
739 # Remove selected header files.
740 $(RM) $(patsubst %,$(SYSROOT_INC)/%,$(MUSL_OMIT_HEADERS))
741 ifeq ($(WASI_SNAPSHOT), p2)
742 printf '#ifndef __wasilibc_use_wasip2\n#define __wasilibc_use_wasip2\n#endif\n' \
743 > "$(SYSROOT_INC)/__wasi_snapshot.h"
744 endif
745
746 startup_files: include_dirs $(LIBC_BOTTOM_HALF_CRT_OBJS)
747 #
748 # Install the startup files (crt1.o etc).
749 #
750 mkdir -p "$(SYSROOT_LIB)" && \
751 cp $(LIBC_BOTTOM_HALF_CRT_OBJS) "$(SYSROOT_LIB)"
752
753 # TODO: As of this writing, wasi_thread_start.s uses non-position-independent
754 # code, and I'm not sure how to make it position-independent. Once we've done
755 # that, we can enable libc.so for the wasi-threads build.
756 ifneq ($(THREAD_MODEL), posix)
757 LIBC_SO = \
758 $(SYSROOT_LIB)/libc.so \
759 $(SYSROOT_LIB)/libwasi-emulated-mman.so \
760 $(SYSROOT_LIB)/libwasi-emulated-process-clocks.so \
761 $(SYSROOT_LIB)/libwasi-emulated-getpid.so \
762 $(SYSROOT_LIB)/libwasi-emulated-signal.so \
763 $(SYSROOT_LIB)/libdl.so
764 ifeq ($(BUILD_LIBSETJMP),yes)
765 LIBC_SO += \
766 $(SYSROOT_LIB)/libsetjmp.so
767 endif
768 endif
769
770 libc_so: include_dirs $(LIBC_SO)
771
772 STATIC_LIBS = \
773 $(SYSROOT_LIB)/libc.a \
774 $(SYSROOT_LIB)/libc-printscan-long-double.a \
775 $(SYSROOT_LIB)/libc-printscan-no-floating-point.a \
776 $(SYSROOT_LIB)/libwasi-emulated-mman.a \
777 $(SYSROOT_LIB)/libwasi-emulated-process-clocks.a \
778 $(SYSROOT_LIB)/libwasi-emulated-getpid.a \
779 $(SYSROOT_LIB)/libwasi-emulated-signal.a \
780 $(SYSROOT_LIB)/libdl.a
781 ifeq ($(BUILD_LIBSETJMP),yes)
782 STATIC_LIBS += \
783 $(SYSROOT_LIB)/libsetjmp.a
784 endif
785
786 libc: include_dirs $(STATIC_LIBS)
787
788 finish: startup_files libc
789 #
790 # Create empty placeholder libraries.
791 #
792 for name in m rt pthread crypt util xnet resolv; do \
793 $(AR) crs "$(SYSROOT_LIB)/lib$${name}.a"; \
794 done
795
796 #
797 # The build succeeded! The generated sysroot is in $(SYSROOT).
798 #
799
800 # The check for defined and undefined symbols expects there to be a heap
801 # alloctor (providing malloc, calloc, free, etc). Skip this step if the build
802 # is done without a malloc implementation.
803 ifneq ($(MALLOC_IMPL),none)
804 finish: check-symbols
805 endif
806
807 DEFINED_SYMBOLS = $(SYSROOT_SHARE)/defined-symbols.txt
808 UNDEFINED_SYMBOLS = $(SYSROOT_SHARE)/undefined-symbols.txt
809
810 ifeq ($(WASI_SNAPSHOT),p2)
811 EXPECTED_TARGET_DIR = expected/wasm32-wasip2
812 else
813 ifeq ($(THREAD_MODEL),posix)
814 EXPECTED_TARGET_DIR = expected/wasm32-wasip1-threads
815 else
816 EXPECTED_TARGET_DIR = expected/wasm32-wasip1
817 endif
818 endif
819
820
821 check-symbols: startup_files libc
822 #
823 # Collect metadata on the sysroot and perform sanity checks.
824 #
825 mkdir -p "$(SYSROOT_SHARE)"
826
827 #
828 # Collect symbol information.
829 #
830 @# TODO: Use llvm-nm --extern-only instead of grep. This is blocked on
831 @# LLVM PR40497, which is fixed in 9.0, but not in 8.0.
832 @# Ignore certain llvm builtin symbols such as those starting with __mul
833 @# since these dependencies can vary between llvm versions.
834 "$(NM)" --defined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libwasi-emulated-*.a "$(SYSROOT_LIB)"/*.o \
835 |grep ' [[:upper:]] ' |sed 's/.* [[:upper:]] //' |LC_ALL=C sort |uniq > "$(DEFINED_SYMBOLS)"
836 for undef_sym in $$("$(NM)" --undefined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libc-*.a "$(SYSROOT_LIB)"/*.o \
837 |grep ' U ' |sed 's/.* U //' |LC_ALL=C sort |uniq); do \
838 grep -q '\<'$$undef_sym'\>' "$(DEFINED_SYMBOLS)" || echo $$undef_sym; \
839 done | grep -E -v "^__mul|__memory_base" > "$(UNDEFINED_SYMBOLS)"
840 grep '^_*imported_wasi_' "$(UNDEFINED_SYMBOLS)" \
841 > "$(SYSROOT_LIB)/libc.imports"
842
843 #
844 # Generate a test file that includes all public C header files.
845 #
846 # setjmp.h is excluded because it requires a different compiler option
847 #
848 cd "$(SYSROOT_INC)" && \
849 for header in $$(find . -type f -not -name mman.h -not -name signal.h -not -name times.h -not -name resource.h -not -name setjmp.h $(INCLUDE_ALL_CLAUSES) |grep -v /bits/ |grep -v /c++/); do \
850 echo '#include <'$$header'>' | sed 's/\.\///' ; \
851 done |LC_ALL=C sort >$(SYSROOT_SHARE)/include-all.c ; \
852 cd - >/dev/null
853
854 #
855 # Test that it compiles.
856 #
857 $(CC) $(CFLAGS) -fsyntax-only "$(SYSROOT_SHARE)/include-all.c" -Wno-\#warnings
858
859 #
860 # Collect all the predefined macros, except for compiler version macros
861 # which we don't need to track here.
862 #
863 @#
864 @# For the __*_ATOMIC_*_LOCK_FREE macros, squash individual compiler names
865 @# to attempt, toward keeping these files compiler-independent.
866 @#
867 @# We have to add `-isystem $(SYSROOT_INC)` because otherwise clang puts
868 @# its builtin include path first, which produces compiler-specific
869 @# output.
870 @#
871 @# TODO: Filter out __NO_MATH_ERRNO_ and a few __*WIDTH__ that are new to clang 14.
872 @# TODO: Filter out __GCC_HAVE_SYNC_COMPARE_AND_SWAP_* that are new to clang 16.
873 @# TODO: Filter out __FPCLASS_* that are new to clang 17.
874 @# TODO: Filter out __FLT128_* that are new to clang 18.
875 @# TODO: Filter out __MEMORY_SCOPE_* that are new to clang 18.
876 @# TODO: clang defined __FLT_EVAL_METHOD__ until clang 15, so we force-undefine it
877 @# for older versions.
878 @# TODO: Undefine __wasm_mutable_globals__ and __wasm_sign_ext__, that are new to
879 @# clang 16 for -mcpu=generic.
880 @# TODO: As of clang 16, __GNUC_VA_LIST is #defined without a value.
881 $(CC) $(CFLAGS) "$(SYSROOT_SHARE)/include-all.c" \
882 -isystem $(SYSROOT_INC) \
883 -std=gnu17 \
884 -E -dM -Wno-\#warnings \
885 -D_ALL_SOURCE \
886 -U__llvm__ \
887 -U__clang__ \
888 -U__clang_major__ \
889 -U__clang_minor__ \
890 -U__clang_patchlevel__ \
891 -U__clang_version__ \
892 -U__clang_literal_encoding__ \
893 -U__clang_wide_literal_encoding__ \
894 -U__wasm_mutable_globals__ \
895 -U__wasm_sign_ext__ \
896 -U__GNUC__ \
897 -U__GNUC_MINOR__ \
898 -U__GNUC_PATCHLEVEL__ \
899 -U__VERSION__ \
900 -U__NO_MATH_ERRNO__ \
901 -U__BITINT_MAXWIDTH__ \
902 -U__FLT_EVAL_METHOD__ -Wno-builtin-macro-redefined \
903 | sed -e 's/__[[:upper:][:digit:]]*_ATOMIC_\([[:upper:][:digit:]_]*\)_LOCK_FREE/__compiler_ATOMIC_\1_LOCK_FREE/' \
904 | sed -e 's/__GNUC_VA_LIST $$/__GNUC_VA_LIST 1/' \
905 | grep -v '^#define __\(BOOL\|INT_\(LEAST\|FAST\)\(8\|16\|32\|64\)\|INT\|LONG\|LLONG\|SHRT\)_WIDTH__' \
906 | grep -v '^#define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_\(1\|2\|4\|8\)' \
907 | grep -v '^#define __FPCLASS_' \
908 | grep -v '^#define __FLT128_' \
909 | grep -v '^#define __MEMORY_SCOPE_' \
910 | grep -v '^#define NDEBUG' \
911 | grep -v '^#define __OPTIMIZE__' \
912 | grep -v '^#define assert' \
913 | grep -v '^#define __NO_INLINE__' \
914 > "$(SYSROOT_SHARE)/predefined-macros.txt"
915
916 # Check that the computed metadata matches the expected metadata.
917 # This ignores whitespace because on Windows the output has CRLF line endings.
918 diff -wur "$(EXPECTED_TARGET_DIR)" "$(SYSROOT_SHARE)"
919
920 install: finish
921 mkdir -p "$(INSTALL_DIR)"
922 cp -r "$(SYSROOT)/lib" "$(SYSROOT)/share" "$(SYSROOT)/include" "$(INSTALL_DIR)"
923
924 $(BINDING_WORK_DIR)/wasi-cli:
925 mkdir -p "$(BINDING_WORK_DIR)"
926 cd "$(BINDING_WORK_DIR)" && \
927 curl -L "$(WASI_CLI_URL)" -o wasi-cli.tar.gz && \
928 tar xf wasi-cli.tar.gz && \
929 mv wasi-cli-* wasi-cli
930
931 $(BINDING_WORK_DIR)/wit-bindgen:
932 mkdir -p "$(BINDING_WORK_DIR)"
933 cd "$(BINDING_WORK_DIR)" && \
934 curl -L "$(WIT_BINDGEN_URL)" -o wit-bindgen.tar.gz && \
935 tar xf wit-bindgen.tar.gz && \
936 mv wit-bindgen-* wit-bindgen
937
938 bindings: $(BINDING_WORK_DIR)/wasi-cli $(BINDING_WORK_DIR)/wit-bindgen
939 cd "$(BINDING_WORK_DIR)" && \
940 ./wit-bindgen/wit-bindgen c \
941 --autodrop-borrows yes \
942 --rename-world wasip2 \
943 --type-section-suffix __wasi_libc \
944 --world wasi:cli/imports@0.2.0 \
945 --rename wasi:clocks/monotonic-clock@0.2.0=monotonic_clock \
946 --rename wasi:clocks/wall-clock@0.2.0=wall_clock \
947 --rename wasi:filesystem/preopens@0.2.0=filesystem_preopens \
948 --rename wasi:filesystem/types@0.2.0=filesystem \
949 --rename wasi:io/error@0.2.0=io_error \
950 --rename wasi:io/poll@0.2.0=poll \
951 --rename wasi:io/streams@0.2.0=streams \
952 --rename wasi:random/insecure-seed@0.2.0=random_insecure_seed \
953 --rename wasi:random/insecure@0.2.0=random_insecure \
954 --rename wasi:random/random@0.2.0=random \
955 --rename wasi:sockets/instance-network@0.2.0=instance_network \
956 --rename wasi:sockets/ip-name-lookup@0.2.0=ip_name_lookup \
957 --rename wasi:sockets/network@0.2.0=network \
958 --rename wasi:sockets/tcp-create-socket@0.2.0=tcp_create_socket \
959 --rename wasi:sockets/tcp@0.2.0=tcp \
960 --rename wasi:sockets/udp-create-socket@0.2.0=udp_create_socket \
961 --rename wasi:sockets/udp@0.2.0=udp \
962 --rename wasi:cli/environment@0.2.0=environment \
963 --rename wasi:cli/exit@0.2.0=exit \
964 --rename wasi:cli/stdin@0.2.0=stdin \
965 --rename wasi:cli/stdout@0.2.0=stdout \
966 --rename wasi:cli/stderr@0.2.0=stderr \
967 --rename wasi:cli/terminal-input@0.2.0=terminal_input \
968 --rename wasi:cli/terminal-output@0.2.0=terminal_output \
969 --rename wasi:cli/terminal-stdin@0.2.0=terminal_stdin \
970 --rename wasi:cli/terminal-stdout@0.2.0=terminal_stdout \
971 --rename wasi:cli/terminal-stderr@0.2.0=terminal_stderr \
972 ./wasi-cli/wit && \
973 mv wasip2.h ../../libc-bottom-half/headers/public/wasi/ && \
974 mv wasip2_component_type.o ../../libc-bottom-half/sources && \
975 sed 's_#include "wasip2\.h"_#include "wasi/wasip2.h"_' \
976 < wasip2.c \
977 > ../../libc-bottom-half/sources/wasip2.c && \
978 rm wasip2.c
979
980
981 clean:
982 $(RM) -r "$(BINDING_WORK_DIR)"
983 $(RM) -r "$(OBJDIR)"
984 $(RM) -r "$(SYSROOT)"
985
986 .PHONY: default startup_files libc libc_so finish install include_dirs clean check-symbols bindings