@@ -5,6 +5,7 @@ readonly real_workspace=/workspace
55readonly output_dir=" ${TYPEPHP_OUTPUT_DIR:- dist} "
66readonly output_name=" ${TYPEPHP_OUTPUT_NAME:- webman-server} "
77readonly force=" ${TYPEPHP_FORCE:- 0} "
8+ readonly is_static=" ${TYPEPHP_STATIC:- 0} "
89readonly build_id=" $( date -u +%Y%m%dT%H%M%SZ) -$$ "
910
1011validate_relative_path () {
@@ -120,8 +121,13 @@ jobs="$(nproc 2>/dev/null || echo 2)"
120121[[ " $jobs " -lt 1 ]] && jobs=1
121122sed -i " s/^job:.*/job: ${jobs} /" " $project_file "
122123
123- echo " [INFO] Compiling Linux x86_64 glibc binary (job=${jobs} )..."
124- " ${tpc[@]} " " $project_file " --no-progress
124+ if [[ " $is_static " = " 1" ]]; then
125+ echo " [INFO] Compiling Linux x86_64 full-static binary with Clang (job=${jobs} )..."
126+ " ${tpc[@]} " " $project_file " --full-static --compiler=clang --no-progress
127+ else
128+ echo " [INFO] Compiling Linux x86_64 glibc binary (job=${jobs} )..."
129+ " ${tpc[@]} " " $project_file " --no-progress
130+ fi
125131
126132normalized_output=" $( dirname -- " $project_output " ) /$( basename -- " $project_output " | tr ' -' ' _' ) "
127133if ! validate_relative_path " $normalized_output " ; then
@@ -139,73 +145,103 @@ if [[ ! -f "$compiled_bin" ]]; then
139145 exit 1
140146fi
141147
142- if ! ldd_output=" $( LD_LIBRARY_PATH=/opt/typephp/vendor/swoole/phpx/lib:/usr/lib ldd " $compiled_bin " 2>&1 ) " ; then
143- echo " [ERROR] ldd failed for '$compiled_bin ': $ldd_output " >&2
144- exit 1
145- fi
146- if grep -q ' not found' <<< " $ldd_output" ; then
147- echo " [ERROR] Unresolved runtime library: $ldd_output " >&2
148- exit 1
149- fi
148+ if [[ " $is_static " = " 1" ]]; then
149+ echo " [INFO] Packaging full-static single binary..."
150+ trap cleanup_stage_on_failure EXIT
151+ install -m 0755 " $compiled_bin " " $stage_dir /webman-server"
152+ if command -v strip & > /dev/null; then
153+ strip --strip-all " $stage_dir /webman-server" 2> /dev/null || true
154+ fi
150155
151- mkdir -p " $stage_dir /lib"
152- trap cleanup_stage_on_failure EXIT
153- install -m 0755 " $compiled_bin " " $stage_dir /webman-server.bin"
156+ # 生成全静态标准启动脚本 start.sh
157+ install -m 0755 /dev/stdin " $stage_dir /start.sh" << 'SCRIPT '
158+ #!/usr/bin/env bash
159+ set -e
160+
161+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
162+ cd "$SCRIPT_DIR"
154163
155- # 1. 自动扫描并打包 PHP 扩展模块 (.so) 到 dist/ext
156- mkdir -p " $stage_dir /ext"
157- php_ext_dir=" $( php-config --extension-dir 2> /dev/null || echo ' /usr/lib/php/20240924' ) "
158- if [[ -d " $php_ext_dir " ]]; then
159- echo " [INFO] Copying PHP extensions from $php_ext_dir to dist/ext/ ..."
160- cp -f " $php_ext_dir " /* .so " $stage_dir /ext/" 2> /dev/null || true
164+ if [ ! -f "$SCRIPT_DIR/webman-server" ]; then
165+ echo "[ERROR] webman-server executable not found in $SCRIPT_DIR!"
166+ exit 1
161167fi
162168
163- # 2. 自动通过 ldd 探测并打包所有程序、PHP 核心库与全部扩展模块的底层共享库
164- mkdir -p " $stage_dir /lib"
165- for bin_or_lib in " $stage_dir /webman-server.bin" " $stage_dir /lib" /* .so* " $stage_dir /ext" /* .so; do
166- if [[ -f " $bin_or_lib " ]]; then
167- mapfile -t found_libs < <( ldd " $bin_or_lib " 2> /dev/null | awk ' /=> \// { print $3 }' )
168- for libpath in " ${found_libs[@]} " ; do
169- if [[ -f " $libpath " ]]; then
170- libname=" $( basename " $libpath " ) "
171- if is_platform_library " $libname " ; then
172- continue
173- fi
174- if [[ ! -f " $stage_dir /lib/$libname " ]]; then
175- cp -L " $libpath " " $stage_dir /lib/$libname " || true
176- fi
177- fi
178- done
179- fi
180- done
169+ chmod +x "$SCRIPT_DIR/webman-server" 2>/dev/null || true
170+ exec "$SCRIPT_DIR/webman-server" "$@"
171+ SCRIPT
181172
182- # 确保核心运行时动态库存在,并复制到根目录和 lib/ 目录
183- for required_library in ' libphpx.so*' ' libphp.so*' ; do
184- found_lib=" $( find /opt /usr " $stage_dir /lib" -name " $required_library " -type f 2> /dev/null | head -n 1 || true) "
185- if [[ -n " $found_lib " && -f " $found_lib " ]]; then
186- libname=" $( basename " $found_lib " ) "
187- clean_libname=" ${libname%% .* } .so"
188- cp -L " $found_lib " " $stage_dir /$clean_libname " || true
189- cp -L " $found_lib " " $stage_dir /lib/$libname " || true
190- else
191- echo " [ERROR] Required library $required_library not found in /opt or /usr!" >&2
173+ if command -v file & > /dev/null; then
174+ echo " [INFO] Verifying static binary ELF format:"
175+ file " $stage_dir /webman-server" || true
176+ fi
177+ else
178+ if ! ldd_output=" $( LD_LIBRARY_PATH=/opt/typephp/vendor/swoole/phpx/lib:/usr/lib ldd " $compiled_bin " 2>&1 ) " ; then
179+ echo " [ERROR] ldd failed for '$compiled_bin ': $ldd_output " >&2
180+ exit 1
181+ fi
182+ if grep -q ' not found' <<< " $ldd_output" ; then
183+ echo " [ERROR] Unresolved runtime library: $ldd_output " >&2
192184 exit 1
193185 fi
194- done
195186
196- # 3. 修复可执行程序和扩展的 RPATH(如果有 patchelf)
197- if command -v patchelf & > /dev/null; then
198- patchelf --set-rpath ' $ORIGIN:$ORIGIN/lib' " $stage_dir /webman-server.bin" 2> /dev/null || true
199- for solib in " $stage_dir " /* .so " $stage_dir " /lib/* .so* ; do
200- [[ -f " $solib " ]] && patchelf --set-rpath ' $ORIGIN:$ORIGIN/lib' " $solib " 2> /dev/null || true
187+ mkdir -p " $stage_dir /lib"
188+ trap cleanup_stage_on_failure EXIT
189+ install -m 0755 " $compiled_bin " " $stage_dir /webman-server.bin"
190+
191+ # 1. 自动扫描并打包 PHP 扩展模块 (.so) 到 dist/ext
192+ mkdir -p " $stage_dir /ext"
193+ php_ext_dir=" $( php-config --extension-dir 2> /dev/null || echo ' /usr/lib/php/20240924' ) "
194+ if [[ -d " $php_ext_dir " ]]; then
195+ echo " [INFO] Copying PHP extensions from $php_ext_dir to dist/ext/ ..."
196+ cp -f " $php_ext_dir " /* .so " $stage_dir /ext/" 2> /dev/null || true
197+ fi
198+
199+ # 2. 自动通过 ldd 探测并打包所有程序、PHP 核心库与全部扩展模块的底层共享库
200+ mkdir -p " $stage_dir /lib"
201+ for bin_or_lib in " $stage_dir /webman-server.bin" " $stage_dir /lib" /* .so* " $stage_dir /ext" /* .so; do
202+ if [[ -f " $bin_or_lib " ]]; then
203+ mapfile -t found_libs < <( ldd " $bin_or_lib " 2> /dev/null | awk ' /=> \// { print $3 }' )
204+ for libpath in " ${found_libs[@]} " ; do
205+ if [[ -f " $libpath " ]]; then
206+ libname=" $( basename " $libpath " ) "
207+ if is_platform_library " $libname " ; then
208+ continue
209+ fi
210+ if [[ ! -f " $stage_dir /lib/$libname " ]]; then
211+ cp -L " $libpath " " $stage_dir /lib/$libname " || true
212+ fi
213+ fi
214+ done
215+ fi
201216 done
202- for extsolib in " $stage_dir " /ext/* .so; do
203- [[ -f " $extsolib " ]] && patchelf --set-rpath ' $ORIGIN/../lib:$ORIGIN:$ORIGIN/..' " $extsolib " 2> /dev/null || true
217+
218+ # 确保核心运行时动态库存在,并复制到根目录和 lib/ 目录
219+ for required_library in ' libphpx.so*' ' libphp.so*' ; do
220+ found_lib=" $( find /opt /usr " $stage_dir /lib" -name " $required_library " -type f 2> /dev/null | head -n 1 || true) "
221+ if [[ -n " $found_lib " && -f " $found_lib " ]]; then
222+ libname=" $( basename " $found_lib " ) "
223+ clean_libname=" ${libname%% .* } .so"
224+ cp -L " $found_lib " " $stage_dir /$clean_libname " || true
225+ cp -L " $found_lib " " $stage_dir /lib/$libname " || true
226+ else
227+ echo " [ERROR] Required library $required_library not found in /opt or /usr!" >&2
228+ exit 1
229+ fi
204230 done
205- fi
206231
207- # 4. 生成自包含纯净 php.ini
208- cat > " $stage_dir /php.ini" << 'EOF '
232+ # 3. 修复可执行程序和扩展的 RPATH(如果有 patchelf)
233+ if command -v patchelf & > /dev/null; then
234+ patchelf --set-rpath ' $ORIGIN:$ORIGIN/lib' " $stage_dir /webman-server.bin" 2> /dev/null || true
235+ for solib in " $stage_dir " /* .so " $stage_dir " /lib/* .so* ; do
236+ [[ -f " $solib " ]] && patchelf --set-rpath ' $ORIGIN:$ORIGIN/lib' " $solib " 2> /dev/null || true
237+ done
238+ for extsolib in " $stage_dir " /ext/* .so; do
239+ [[ -f " $extsolib " ]] && patchelf --set-rpath ' $ORIGIN/../lib:$ORIGIN:$ORIGIN/..' " $extsolib " 2> /dev/null || true
240+ done
241+ fi
242+
243+ # 4. 生成自包含纯净 php.ini
244+ cat > " $stage_dir /php.ini" << 'EOF '
209245output_buffering=0
210246implicit_flush=1
211247memory_limit=4G
@@ -231,18 +267,18 @@ extension=sockets.so
231267extension=event.so
232268EOF
233269
234- # 若 ext/ 目录下没有对应扩展 .so,则注释该行以防产生 Warning
235- while IFS= read -r line || [[ -n " $line " ]]; do
236- if echo " $line " | grep -q " ^extension=" ; then
237- ext_file=$( echo " $line " | cut -d' =' -f2)
238- if [[ ! -f " $stage_dir /ext/$ext_file " ]]; then
239- sed -i " s/^extension=$ext_file $/; extension=$ext_file /" " $stage_dir /php.ini"
270+ # 若 ext/ 目录下没有对应扩展 .so,则注释该行以防产生 Warning
271+ while IFS= read -r line || [[ -n " $line " ]]; do
272+ if echo " $line " | grep -q " ^extension=" ; then
273+ ext_file=$( echo " $line " | cut -d' =' -f2)
274+ if [[ ! -f " $stage_dir /ext/$ext_file " ]]; then
275+ sed -i " s/^extension=$ext_file $/; extension=$ext_file /" " $stage_dir /php.ini"
276+ fi
240277 fi
241- fi
242- done < " $stage_dir /php.ini"
278+ done < " $stage_dir /php.ini"
243279
244- # 5. 生成标准可移植启动包装脚本 webman-server 与 start.sh
245- install -m 0755 /dev/stdin " $stage_dir /webman-server" << 'SCRIPT '
280+ # 5. 生成标准可移植启动包装脚本 webman-server 与 start.sh
281+ install -m 0755 /dev/stdin " $stage_dir /webman-server" << 'SCRIPT '
246282#!/usr/bin/env sh
247283set -eu
248284
@@ -254,7 +290,7 @@ export LD_LIBRARY_PATH="$SCRIPT_DIR:$SCRIPT_DIR/lib${LD_LIBRARY_PATH:+:$LD_LIBRA
254290exec "$SCRIPT_DIR/webman-server.bin" "$@"
255291SCRIPT
256292
257- install -m 0755 /dev/stdin " $stage_dir /start.sh" << 'SCRIPT '
293+ install -m 0755 /dev/stdin " $stage_dir /start.sh" << 'SCRIPT '
258294#!/usr/bin/env bash
259295set -e
260296
0 commit comments