@@ -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} "
6066ARTIFACT_MODE=" ${ARTIFACT_MODE:- full} "
6167FORCE_CLEAN=" ${FORCE_CLEAN:- 0} "
6268FORCE_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
120174echo " [nginx] using CLANG = $CLANG "
121175echo " [nginx] using AR = $AR "
122176echo " [nginx] LIND_WASM_ROOT = $LIND_WASM_ROOT "
123177echo " [nginx] merged sysroot = $MERGED_SYSROOT "
124178echo " [nginx] output dir = $NGINX_OUT_DIR "
125179echo " [nginx] artifact mode = $ARTIFACT_MODE "
180+ echo " [nginx] dylink mode = $LIND_DYLINK "
126181echo
127182
128183# #################
@@ -213,6 +268,7 @@ clang=$CLANG
213268merged=$MERGED_SYSROOT
214269cflags=$CFLAGS_WASM
215270ldflags=$LDFLAGS_WASM
271+ dylink=$LIND_DYLINK
216272args=$configure_args
217273EOF
218274}
@@ -810,15 +866,26 @@ if [[ ! -x "$WASM_OPT" ]]; then
810866 exit 1
811867fi
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
822889echo " [nginx] optimized runnable module: $NGINX_WASM "
823890
824891if [[ " $ARTIFACT_MODE " == " full" ]]; then
@@ -834,6 +901,21 @@ if [[ ! -f "$NGINX_OPT_WASM" ]]; then
834901 exit 1
835902fi
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