Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,44 +13,45 @@ jobs:
with:
submodules: true

- name: Install clang (Windows)
- name: Install LLVM tools (Windows)
shell: bash
run: |
curl -fsSLO https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/LLVM-10.0.0-win64.exe
7z x LLVM-10.0.0-win64.exe -y -o"llvm"
echo "$(pwd)/llvm/bin" >> $GITHUB_PATH
echo "WASM_AR=$(pwd)/llvm/bin/llvm-ar.exe" >> $GITHUB_ENV
curl -fsSLO https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/LLVM-10.0.0-win64.exe
7z x LLVM-10.0.0-win64.exe -y -o"llvm"
echo "$(pwd)/llvm/bin" >> $GITHUB_PATH
echo "CC=$(pwd)/llvm/bin/clang.exe" >> $GITHUB_ENV
echo "AR=$(pwd)/llvm/bin/llvm-ar.exe" >> $GITHUB_ENV
echo "NM=$(pwd)/llvm/bin/llvm-nm.exe" >> $GITHUB_ENV
if: matrix.os == 'windows-latest'

- name: Install llvm-nm (Windows)
- name: Override llvm-nm with one from rustup (Windows)
run: |
rustup update stable
rustup default stable
rustup component add llvm-tools-preview
echo "NM=$(rustc --print sysroot|sed 's|C:|/c|'|sed 's|\\|/|g')/lib/rustlib/x86_64-pc-windows-msvc/bin/llvm-nm.exe" >> $GITHUB_ENV
if: matrix.os == 'windows-latest'

- name: Register llvm-nm in environment (Windows)
shell: bash
run: |
echo "WASM_NM=$(rustc --print sysroot|sed 's|C:|/c|'|sed 's|\\|/|g')/lib/rustlib/x86_64-pc-windows-msvc/bin/llvm-nm.exe" >> $GITHUB_ENV
if: matrix.os == 'windows-latest'

- name: Install clang (MacOS)
- name: Install LLVM tools (MacOS)
shell: bash
run: |
curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-apple-darwin.tar.xz | tar xJf -
export CLANG_DIR=`pwd`/clang+llvm-10.0.0-x86_64-apple-darwin/bin
echo "$CLANG_DIR" >> $GITHUB_PATH
echo "WASM_CC=$CLANG_DIR/clang" >> $GITHUB_ENV
echo "CC=$CLANG_DIR/clang" >> $GITHUB_ENV
echo "AR=$CLANG_DIR/llvm-ar" >> $GITHUB_ENV
echo "NM=$CLANG_DIR/llvm-nm" >> $GITHUB_ENV
if: matrix.os == 'macos-latest'

- name: Install clang (Linux)
- name: Install LLVM tools (Linux)
shell: bash
run: |
curl -sSfL https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz | tar xJf -
export CLANG_DIR=`pwd`/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04/bin
echo "$CLANG_DIR" >> $GITHUB_PATH
echo "WASM_CC=$CLANG_DIR/clang" >> $GITHUB_ENV
echo "CC=$CLANG_DIR/clang" >> $GITHUB_ENV
echo "AR=$CLANG_DIR/llvm-ar" >> $GITHUB_ENV
echo "NM=$CLANG_DIR/llvm-nm" >> $GITHUB_ENV
if: matrix.os == 'ubuntu-latest'

- name: Build libc
Expand Down
93 changes: 60 additions & 33 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
# These variables are specifically meant to be overridable via the make
# command-line.
WASM_CC ?= clang
WASM_NM ?= $(patsubst %clang,%llvm-nm,$(filter-out ccache sccache,$(WASM_CC)))
WASM_AR ?= $(patsubst %clang,%llvm-ar,$(filter-out ccache sccache,$(WASM_CC)))
WASM_CFLAGS ?= -O2 -DNDEBUG
# The directory where we build the sysroot.
CC ?= clang
NM ?= $(patsubst %clang,%llvm-nm,$(filter-out ccache sccache,$(CC)))
AR ?= $(patsubst %clang,%llvm-ar,$(filter-out ccache sccache,$(CC)))
EXTRA_CFLAGS ?= -O2 -DNDEBUG
# These variables describe the locations of various files and
# directories to install.
#
# `SYSROOT` is just used to define the defaults, and in the install
# rule. That means you should not override `SYSROOT_*` if you are going
# to run `make install`, but if you don't need to, you are free to move
# the `SYSROOT_*` directories around freely, not preserving their
# default locations relative `SYSROOT`.
SYSROOT ?= $(CURDIR)/sysroot
SYSROOT_LIB ?= $(SYSROOT)/lib/$(MULTIARCH_TRIPLE)
SYSROOT_INC ?= $(SYSROOT)/include
SYSROOT_SHARE ?= $(SYSROOT)/share/$(MULTIARCH_TRIPLE)
# A directory to install to for "make install".
INSTALL_DIR ?= /usr/local
# single or posix
Expand Down Expand Up @@ -184,8 +194,10 @@ LIBC_TOP_HALF_ALL_SOURCES = \
$(LIBC_TOP_HALF_MUSL_SOURCES) \
$(shell find $(LIBC_TOP_HALF_SOURCES) -name \*.c)

# Add any extra flags
CFLAGS = $(EXTRA_CFLAGS)
# Set the target.
CFLAGS = $(WASM_CFLAGS) --target=$(TARGET_TRIPLE)
CFLAGS += --target=$(TARGET_TRIPLE)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone overwrites CFLAGS on the make command line, does it override the --target=$(TARGET_TRIPLE) part too, or just the -O2 -DNDEBUG part?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think just the O2 -DNDEBUG part, but will check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@sunfishcode I tested it, and it indeed the CLI was overriding everything. I added a bunch of override so that this is no longer the case, and just the -O2 -DNDEBUG part gets overridden.

# WebAssembly floating-point match doesn't trap.
# TODO: Add -fno-signaling-nans when the compiler supports it.
CFLAGS += -fno-trapping-math
Expand Down Expand Up @@ -252,12 +264,6 @@ LIBWASI_EMULATED_GETPID_OBJS = $(call objs,$(LIBWASI_EMULATED_GETPID_SOURCES))
LIBWASI_EMULATED_SIGNAL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_SOURCES))
LIBWASI_EMULATED_SIGNAL_MUSL_OBJS = $(call objs,$(LIBWASI_EMULATED_SIGNAL_MUSL_SOURCES))

# These variables describe the locations of various files and
# directories in the generated sysroot tree.
SYSROOT_LIB := $(SYSROOT)/lib/$(MULTIARCH_TRIPLE)
SYSROOT_INC = $(SYSROOT)/include
SYSROOT_SHARE = $(SYSROOT)/share/$(MULTIARCH_TRIPLE)

# Files from musl's include directory that we don't want to install in the
# sysroot's include directory.
MUSL_OMIT_HEADERS :=
Expand Down Expand Up @@ -361,13 +367,13 @@ $(SYSROOT_LIB)/libwasi-emulated-signal.a: $(LIBWASI_EMULATED_SIGNAL_OBJS) $(LIBW
%.a:
@mkdir -p "$(@D)"
# On Windows, the commandline for the ar invocation got too long, so it needs to be split up.
$(WASM_AR) crs $@ $(wordlist 1, 199, $^)
$(WASM_AR) crs $@ $(wordlist 200, 399, $^)
$(WASM_AR) crs $@ $(wordlist 400, 599, $^)
$(WASM_AR) crs $@ $(wordlist 600, 799, $^)
$(AR) crs $@ $(wordlist 1, 199, $^)
$(AR) crs $@ $(wordlist 200, 399, $^)
$(AR) crs $@ $(wordlist 400, 599, $^)
$(AR) crs $@ $(wordlist 600, 799, $^)
# This might eventually overflow again, but at least it'll do so in a loud way instead of
# silently dropping the tail.
$(WASM_AR) crs $@ $(wordlist 800, 100000, $^)
$(AR) crs $@ $(wordlist 800, 100000, $^)

$(MUSL_PRINTSCAN_OBJS): CFLAGS += \
-D__wasilibc_printscan_no_long_double \
Expand All @@ -382,15 +388,15 @@ $(LIBWASI_EMULATED_SIGNAL_MUSL_OBJS): CFLAGS += \

$(OBJDIR)/%.long-double.o: $(CURDIR)/%.c include_dirs
@mkdir -p "$(@D)"
$(WASM_CC) $(CFLAGS) -MD -MP -o $@ -c $<
$(CC) $(CFLAGS) -MD -MP -o $@ -c $<

$(OBJDIR)/%.no-floating-point.o: $(CURDIR)/%.c include_dirs
@mkdir -p "$(@D)"
$(WASM_CC) $(CFLAGS) -MD -MP -o $@ -c $<
$(CC) $(CFLAGS) -MD -MP -o $@ -c $<

$(OBJDIR)/%.o: $(CURDIR)/%.c include_dirs
@mkdir -p "$(@D)"
$(WASM_CC) $(CFLAGS) -MD -MP -o $@ -c $<
$(CC) $(CFLAGS) -MD -MP -o $@ -c $<

-include $(shell find $(OBJDIR) -name \*.d)

Expand Down Expand Up @@ -420,7 +426,7 @@ $(LIBWASI_EMULATED_PROCESS_CLOCKS_OBJS): CFLAGS += \
-I$(LIBC_BOTTOM_HALF_CLOUDLIBC_SRC)

include_dirs:
$(RM) -r "$(SYSROOT)"
$(RM) -r "$(SYSROOT_INC)"

#
# Install the include files.
Expand Down Expand Up @@ -450,7 +456,7 @@ startup_files: include_dirs
#
@mkdir -p "$(OBJDIR)"
cd "$(OBJDIR)" && \
$(WASM_CC) $(CFLAGS) -c $(LIBC_BOTTOM_HALF_CRT_SOURCES) -MD -MP && \
$(CC) $(CFLAGS) -c $(LIBC_BOTTOM_HALF_CRT_SOURCES) -MD -MP && \
mkdir -p "$(SYSROOT_LIB)" && \
mv *.o "$(SYSROOT_LIB)"

Expand All @@ -468,11 +474,15 @@ finish: startup_files libc
# Create empty placeholder libraries.
#
for name in m rt pthread crypt util xnet resolv dl; do \
$(WASM_AR) crs "$(SYSROOT_LIB)/lib$${name}.a"; \
$(AR) crs "$(SYSROOT_LIB)/lib$${name}.a"; \
done

#
# The build succeeded! The generated sysroot is in $(SYSROOT).
# The build succeeded! The generated files are in
#
# lib: $(SYSROOT_LIB)
# include: $(SYSROOT_INC)
# share: $(SYSROOT_SHARE)
#

# The check for defined and undefined symbols expects there to be a heap
Expand All @@ -495,9 +505,9 @@ check-symbols: startup_files libc
@# LLVM PR40497, which is fixed in 9.0, but not in 8.0.
@# Ignore certain llvm builtin symbols such as those starting with __mul
@# since these dependencies can vary between llvm versions.
"$(WASM_NM)" --defined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libwasi-emulated-*.a "$(SYSROOT_LIB)"/*.o \
"$(NM)" --defined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libwasi-emulated-*.a "$(SYSROOT_LIB)"/*.o \
|grep ' [[:upper:]] ' |sed 's/.* [[:upper:]] //' |LC_ALL=C sort > "$(SYSROOT_SHARE)/defined-symbols.txt"
for undef_sym in $$("$(WASM_NM)" --undefined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libc-*.a "$(SYSROOT_LIB)"/*.o \
for undef_sym in $$("$(NM)" --undefined-only "$(SYSROOT_LIB)"/libc.a "$(SYSROOT_LIB)"/libc-*.a "$(SYSROOT_LIB)"/*.o \
|grep ' U ' |sed 's/.* U //' |LC_ALL=C sort |uniq); do \
grep -q '\<'$$undef_sym'\>' "$(SYSROOT_SHARE)/defined-symbols.txt" || echo $$undef_sym; \
done | grep -v "^__mul" > "$(SYSROOT_SHARE)/undefined-symbols.txt"
Expand All @@ -507,16 +517,16 @@ check-symbols: startup_files libc
#
# Generate a test file that includes all public header files.
#
cd "$(SYSROOT)" && \
for header in $$(find include -type f -not -name mman.h -not -name signal.h -not -name times.h -not -name resource.h |grep -v /bits/); do \
echo '#include <'$$header'>' | sed 's/include\///' ; \
done |LC_ALL=C sort >share/$(MULTIARCH_TRIPLE)/include-all.c ; \
cd "$(SYSROOT_INC)" && \
for header in $$(find . -type f -not -name mman.h -not -name signal.h -not -name times.h -not -name resource.h |grep -v /bits/); do \
echo '#include <'$$header'>' | sed 's/\.\///' ; \
done |LC_ALL=C sort >$(SYSROOT_SHARE)/include-all.c ; \
cd - >/dev/null

#
# Test that it compiles.
#
$(WASM_CC) $(CFLAGS) -fsyntax-only "$(SYSROOT_SHARE)/include-all.c" -Wno-\#warnings
$(CC) $(CFLAGS) -fsyntax-only "$(SYSROOT_SHARE)/include-all.c" -Wno-\#warnings

#
# Collect all the predefined macros, except for compiler version macros
Expand All @@ -532,7 +542,7 @@ check-symbols: startup_files libc
@#
@# TODO: Undefine __FLOAT128__ for now since it's not in clang 8.0.
@# TODO: Filter out __FLT16_* for now, as not all versions of clang have these.
$(WASM_CC) $(CFLAGS) "$(SYSROOT_SHARE)/include-all.c" \
$(CC) $(CFLAGS) "$(SYSROOT_SHARE)/include-all.c" \
-isystem $(SYSROOT_INC) \
-std=gnu17 \
-E -dM -Wno-\#warnings \
Expand All @@ -558,8 +568,25 @@ check-symbols: startup_files libc
# This ignores whitespace because on Windows the output has CRLF line endings.
diff -wur "$(CURDIR)/expected/$(MULTIARCH_TRIPLE)" "$(SYSROOT_SHARE)"

NORMAL_SYSROOT := \
$(findstring $(SYSROOT)/lib,$(SYSROOT_LIB)) \
$(findstring $(SYSROOT)/include,$(SYSROOT_INC)) \
$(findstring $(SYSROOT)/share,$(SYSROOT_SHARE))

# If the 3 dirs are not within the standard locations, the install rule
# is undefined. This protects the user from doing something silly by
# mistake.
ifeq ($(SYSROOT)/lib $(SYSROOT)/include $(SYSROOT)/share,$(strip $(NORMAL_SYSROOT)))
install: finish
mkdir -p "$(INSTALL_DIR)"
cp -r "$(SYSROOT)/lib" "$(SYSROOT)/share" "$(SYSROOT)/include" "$(INSTALL_DIR)"
.PHONY: install
endif

clean:
$(RM) -r "$(OBJDIR)"
$(RM) -r "$(SYSROOT_INC)"
$(RM) -r "$(SYSROOT_LIB)"
$(RM) -r "$(SYSROOT_SHARE)"

.PHONY: default startup_files libc finish install include_dirs
.PHONY: default startup_files libc finish include_dirs clean
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ To build a WASI sysroot from source, obtain a WebAssembly-supporting C compiler
and then run:

```sh
make WASM_CC=/path/to/clang/with/wasm/support \
WASM_AR=/path/to/llvm-ar \
WASM_NM=/path/to/llvm-nm
make CC=/path/to/clang/with/wasm/support \
AR=/path/to/llvm-ar \
NM=/path/to/llvm-nm
```

This makes a directory called "sysroot", by default. See the top of the Makefile
Expand Down