Skip to content

Commit 314c751

Browse files
add dynamic compilation support for nginx
1 parent 4930659 commit 314c751

File tree

1 file changed

+101
-19
lines changed

1 file changed

+101
-19
lines changed

nginx/compile_nginx.sh

Lines changed: 101 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@ set -euo pipefail
99
# 2. Apply patches for WASI compatibility
1010
# 3. Build nginx with wasm32-wasi toolchain
1111
# 4. Optimize with wasm-opt (asyncify for multi-process support)
12-
# 5. Precompile with wasmtime compile
12+
# 5. Precompile with lind-boot --precompile
13+
#
14+
# Dynamic loading support:
15+
# Set LIND_DYLINK=1 to build nginx as a position-independent executable
16+
# for the dylink branch. This adds -fPIC to CFLAGS, uses PIE link flags,
17+
# and applies the dylink-aware wasm-opt passes.
1318
#
1419
# Prerequisites:
1520
# - Run 'make preflight' and 'make merge-sysroot' from lind-wasm-apps root
@@ -57,6 +62,7 @@ JOBS="${JOBS:-$(nproc 2>/dev/null || getconf _NPROCESSORS_ONLN || echo 4)}"
5762
# skipping .cwasm generation while the default `ARTIFACT_MODE=full` performs
5863
# optimization and .cwasm binary generation
5964
##################
65+
LIND_DYLINK="${LIND_DYLINK:-0}"
6066
ARTIFACT_MODE="${ARTIFACT_MODE:-full}"
6167
FORCE_CLEAN="${FORCE_CLEAN:-0}"
6268
FORCE_CONFIGURE="${FORCE_CONFIGURE:-0}"
@@ -107,22 +113,71 @@ CFLAGS_WASM="-O2 -g -pthread -matomics -mbulk-memory \
107113
-I$MERGED_SYSROOT/include/wasm32-wasi \
108114
-D_GNU_SOURCE"
109115

110-
# LDFLAGS for WASM linking
111-
# Note: nginx's generated Makefile does not use $(LDFLAGS). Instead, the link
112-
# rule uses $(LINK) as the full linker command. We pass these flags via the
113-
# LINK make override at build time (not via --with-ld-opt, which configure
114-
# would test and fail for WASM-specific flags).
115-
LDFLAGS_WASM="-Wl,--shared-memory,--import-memory,--export-memory,--max-memory=67108864 \
116-
-Wl,--export=__stack_pointer,--export=__stack_low,--export=__tls_base \
117-
-L$MERGED_SYSROOT/lib/wasm32-wasi \
118-
-L$MERGED_SYSROOT/usr/lib/wasm32-wasi"
116+
if [[ "$LIND_DYLINK" == "1" ]]; then
117+
echo "[nginx] Dynamic linking mode enabled (LIND_DYLINK=1)"
118+
CFLAGS_WASM+=" -fPIC"
119+
120+
# add-export-tool is used after wasm-opt to export relocation and stack symbols
121+
ADD_EXPORT_TOOL="$LIND_WASM_ROOT/tools/add-export-tool/add-export-tool"
122+
if [[ ! -x "$ADD_EXPORT_TOOL" ]]; then
123+
echo "[nginx] ERROR: add-export-tool not found at '$ADD_EXPORT_TOOL'" >&2
124+
exit 1
125+
fi
126+
127+
# Extra CRT objects required for dynamic PIE executables
128+
DYLINK_CRT_OBJS=(
129+
"$MERGED_SYSROOT/lib/wasm32-wasi/set_stack_pointer.o"
130+
"$MERGED_SYSROOT/lib/wasm32-wasi/crt1_shared.o"
131+
"$MERGED_SYSROOT/lib/wasm32-wasi/lind_utils.o"
132+
)
133+
for obj in "${DYLINK_CRT_OBJS[@]}"; do
134+
if [[ ! -f "$obj" ]]; then
135+
echo "[nginx] ERROR: required dylink CRT object '$obj' not found." >&2
136+
echo "[nginx] Hint: rebuild sysroot on the dylink branch (make sysroot in lind-wasm)." >&2
137+
exit 1
138+
fi
139+
done
140+
141+
# LDFLAGS for WASM dynamic/PIE linking
142+
# -nostartfiles: skip default CRT, use dylink-specific CRT objects instead
143+
# -Wl,-pie: produce a Position Independent Executable
144+
# -Wl,--import-table: import the indirect-function table (cross-module calls)
145+
# -Wl,--allow-undefined + --unresolved-symbols=import-dynamic: resolve at load time
146+
# -Wl,--export=__wasm_call_ctors: let lind-boot call constructors
147+
LDFLAGS_WASM="-nostartfiles \
148+
-Wl,-pie \
149+
-Wl,--import-table \
150+
-Wl,--import-memory \
151+
-Wl,--export-memory \
152+
-Wl,--shared-memory \
153+
-Wl,--max-memory=67108864 \
154+
-Wl,--allow-undefined \
155+
-Wl,--unresolved-symbols=import-dynamic \
156+
-Wl,--export=__wasm_call_ctors \
157+
-Wl,--export-if-defined=__wasm_init_tls \
158+
-Wl,--export=__tls_base \
159+
-L$MERGED_SYSROOT/lib/wasm32-wasi \
160+
-L$MERGED_SYSROOT/usr/lib/wasm32-wasi \
161+
${DYLINK_CRT_OBJS[*]}"
162+
else
163+
# LDFLAGS for static WASM linking
164+
# Note: nginx's generated Makefile does not use $(LDFLAGS). Instead, the link
165+
# rule uses $(LINK) as the full linker command. We pass these flags via the
166+
# LINK make override at build time (not via --with-ld-opt, which configure
167+
# would test and fail for WASM-specific flags).
168+
LDFLAGS_WASM="-Wl,--shared-memory,--import-memory,--export-memory,--max-memory=67108864 \
169+
-Wl,--export=__stack_pointer,--export=__stack_low,--export=__tls_base \
170+
-L$MERGED_SYSROOT/lib/wasm32-wasi \
171+
-L$MERGED_SYSROOT/usr/lib/wasm32-wasi"
172+
fi
119173

120174
echo "[nginx] using CLANG = $CLANG"
121175
echo "[nginx] using AR = $AR"
122176
echo "[nginx] LIND_WASM_ROOT = $LIND_WASM_ROOT"
123177
echo "[nginx] merged sysroot = $MERGED_SYSROOT"
124178
echo "[nginx] output dir = $NGINX_OUT_DIR"
125179
echo "[nginx] artifact mode = $ARTIFACT_MODE"
180+
echo "[nginx] dylink mode = $LIND_DYLINK"
126181
echo
127182

128183
##################
@@ -213,6 +268,7 @@ clang=$CLANG
213268
merged=$MERGED_SYSROOT
214269
cflags=$CFLAGS_WASM
215270
ldflags=$LDFLAGS_WASM
271+
dylink=$LIND_DYLINK
216272
args=$configure_args
217273
EOF
218274
}
@@ -810,15 +866,26 @@ if [[ ! -x "$WASM_OPT" ]]; then
810866
exit 1
811867
fi
812868

813-
echo "[nginx] running wasm-opt (asyncify + epoch injection) to produce runnable nginx.wasm..."
814-
"$WASM_OPT" \
815-
--fpcast-emu \
816-
--epoch-injection \
817-
--asyncify \
818-
--debuginfo \
819-
-O2 \
820-
"$NGINX_RAW_WASM" \
821-
-o "$NGINX_WASM"
869+
if [[ "$LIND_DYLINK" == "1" ]]; then
870+
echo "[nginx] running wasm-opt (dylink-aware: epoch-import + asyncify-import-globals)..."
871+
"$WASM_OPT" \
872+
--enable-bulk-memory --enable-threads \
873+
--epoch-injection --pass-arg=epoch-import --pass-arg=epoch-main-module \
874+
--asyncify --pass-arg=asyncify-import-globals \
875+
--debuginfo \
876+
"$NGINX_RAW_WASM" \
877+
-o "$NGINX_WASM"
878+
else
879+
echo "[nginx] running wasm-opt (asyncify + epoch injection) to produce runnable nginx.wasm..."
880+
"$WASM_OPT" \
881+
--fpcast-emu \
882+
--epoch-injection \
883+
--asyncify \
884+
--debuginfo \
885+
-O2 \
886+
"$NGINX_RAW_WASM" \
887+
-o "$NGINX_WASM"
888+
fi
822889
echo "[nginx] optimized runnable module: $NGINX_WASM"
823890

824891
if [[ "$ARTIFACT_MODE" == "full" ]]; then
@@ -834,6 +901,21 @@ if [[ ! -f "$NGINX_OPT_WASM" ]]; then
834901
exit 1
835902
fi
836903

904+
###############################################################################
905+
# 5.5. Add dylink exports via add-export-tool (dynamic mode only)
906+
###############################################################################
907+
908+
if [[ "$LIND_DYLINK" == "1" ]]; then
909+
echo "[nginx] adding dylink exports via add-export-tool..."
910+
"$ADD_EXPORT_TOOL" "$NGINX_OPT_WASM" "$NGINX_OPT_WASM" \
911+
__wasm_apply_tls_relocs func __wasm_apply_tls_relocs optional
912+
"$ADD_EXPORT_TOOL" "$NGINX_OPT_WASM" "$NGINX_OPT_WASM" \
913+
__wasm_apply_global_relocs func __wasm_apply_global_relocs optional
914+
"$ADD_EXPORT_TOOL" "$NGINX_OPT_WASM" "$NGINX_OPT_WASM" \
915+
__stack_pointer global __stack_pointer
916+
echo "[nginx] dylink exports added to $NGINX_OPT_WASM"
917+
fi
918+
837919
###############################################################################
838920
# 6. cwasm generation (best-effort)
839921
###############################################################################

0 commit comments

Comments
 (0)