Skip to content

Commit 5caaa4d

Browse files
authored
Merge pull request #592 from crazywhalecc/feat/gnu-static
[feat] Add gnu based static binary support
2 parents 067b02f + 939fd88 commit 5caaa4d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+664
-103
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ packlib_files.txt
3333
!/bin/setup-runtime*
3434
!/bin/spc-alpine-docker
3535
!/bin/php-cs-fixer-wrapper
36+
!/bin/build-static-frankenphp
3637

3738
# exclude windows build tools
3839
/php-sdk-binary-tools/

bin/build-static-frankenphp

+150
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
#!/usr/bin/env bash
2+
3+
# This file is using docker to run commands
4+
set -e
5+
6+
# Detect docker can run
7+
if ! which docker >/dev/null; then
8+
echo "Docker is not installed, please install docker first !"
9+
exit 1
10+
fi
11+
DOCKER_EXECUTABLE="docker"
12+
# shellcheck disable=SC2046
13+
if [ $(id -u) -ne 0 ]; then
14+
if ! docker info > /dev/null 2>&1; then
15+
if [ "$SPC_USE_SUDO" != "yes" ]; then
16+
echo "Docker command requires sudo"
17+
# shellcheck disable=SC2039
18+
echo -n 'To use sudo to run docker, run "export SPC_USE_SUDO=yes" and run command again'
19+
exit 1
20+
fi
21+
DOCKER_EXECUTABLE="sudo docker"
22+
fi
23+
fi
24+
25+
26+
27+
# to check if qemu-docker run
28+
if [ "$SPC_USE_ARCH" = "" ]; then
29+
SPC_USE_ARCH=current
30+
fi
31+
case $SPC_USE_ARCH in
32+
current)
33+
BASE_ARCH=$(uname -m)
34+
if [ "$BASE_ARCH" = "arm64" ]; then
35+
BASE_ARCH=aarch64
36+
GO_ARCH=arm64
37+
else
38+
GO_ARCH=amd64
39+
fi
40+
;;
41+
aarch64)
42+
BASE_ARCH=aarch64
43+
GO_ARCH=arm64
44+
# shellcheck disable=SC2039
45+
echo -e "\e[033m* Using different arch needs to setup qemu-static for docker !\e[0m"
46+
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
47+
;;
48+
*)
49+
echo "Current arch is not supported to run in docker: $SPC_USE_ARCH"
50+
exit 1
51+
;;
52+
esac
53+
54+
# Detect docker env is setup
55+
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-frankenphp-gnu-$SPC_USE_ARCH; then
56+
echo "Docker container does not exist. Building docker image ..."
57+
$DOCKER_EXECUTABLE build -t cwcc-frankenphp-gnu-$SPC_USE_ARCH -f- . <<EOF
58+
FROM centos:7
59+
RUN sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo && \
60+
sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
61+
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo
62+
RUN yum clean all && \
63+
yum makecache && \
64+
yum update -y
65+
66+
RUN yum install -y centos-release-scl
67+
68+
RUN if [ "$BASE_ARCH" = "aarch64" ]; then \
69+
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo ; \
70+
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl.repo ; \
71+
else \
72+
sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo ; \
73+
fi
74+
RUN sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
75+
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo
76+
77+
RUN yum update -y && \
78+
yum install -y devtoolset-10-gcc-*
79+
RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc
80+
RUN source /etc/bashrc
81+
82+
RUN curl -o cmake.tgz -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$BASE_ARCH.tar.gz && \
83+
mkdir /cmake && \
84+
tar -xzf cmake.tgz -C /cmake --strip-components 1
85+
86+
WORKDIR /app
87+
ADD ./src /app/src
88+
COPY ./composer.* /app/
89+
ADD ./bin/setup-runtime /app/bin/setup-runtime
90+
ADD ./bin/spc /app/bin/spc
91+
RUN /app/bin/setup-runtime
92+
RUN /app/bin/php /app/bin/composer install --no-dev --classmap-authoritative
93+
ENV PATH="/app/bin:/cmake/bin:/usr/local/go/bin:$PATH"
94+
ENV SPC_SKIP_DOCTOR_CHECK_ITEMS="if musl-wrapper is installed,if musl-cross-make is installed"
95+
96+
ADD ./config/env.ini /app/config/env.ini
97+
RUN bin/spc doctor --auto-fix --debug
98+
99+
RUN curl -o make.tgz -fsSL https://ftp.gnu.org/gnu/make/make-4.4.tar.gz && \
100+
tar -zxvf make.tgz && \
101+
cd make-4.4 && \
102+
./configure && \
103+
make && \
104+
make install && \
105+
ln -sf /usr/local/bin/make /usr/bin/make
106+
107+
RUN git clone https://github.com/static-php/gnu-frankenphp --depth=1 /frankenphp
108+
WORKDIR /frankenphp
109+
110+
RUN curl -o go.tgz -fsSL https://go.dev/dl/go1.24.1.linux-$GO_ARCH.tar.gz && \
111+
rm -rf /usr/local/go && tar -C /usr/local -xzf go.tgz
112+
EOF
113+
fi
114+
115+
# Check if in ci (local terminal can execute with -it)
116+
if [ -t 0 ]; then
117+
INTERACT=-it
118+
else
119+
INTERACT=''
120+
fi
121+
122+
# Mounting volumes
123+
MOUNT_LIST=""
124+
# shellcheck disable=SC2089
125+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/config:/app/config"
126+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/src:/app/src"
127+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/buildroot:/app/buildroot"
128+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/source:/app/source"
129+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/dist:/app/dist"
130+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/downloads:/app/downloads"
131+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/pkgroot:/app/pkgroot"
132+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/dist:/frankenphp/dist"
133+
134+
# Apply env in temp env file
135+
echo 'SPC_SKIP_DOCTOR_CHECK_ITEMS=if musl-wrapper is installed,if musl-cross-make is installed' > /tmp/spc-gnu-docker.env
136+
echo 'CC=/opt/rh/devtoolset-10/root/usr/bin/gcc' >> /tmp/spc-gnu-docker.env
137+
echo 'CXX=/opt/rh/devtoolset-10/root/usr/bin/g++' >> /tmp/spc-gnu-docker.env
138+
echo 'AR=/opt/rh/devtoolset-10/root/usr/bin/ar' >> /tmp/spc-gnu-docker.env
139+
echo 'LD=/opt/rh/devtoolset-10/root/usr/bin/ld' >> /tmp/spc-gnu-docker.env
140+
echo 'SPC_DEFAULT_C_FLAGS=-fPIE' >> /tmp/spc-gnu-docker.env
141+
echo 'SPC_NO_MUSL_PATH=yes' >> /tmp/spc-gnu-docker.env
142+
echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-Wl,-O1 -pie"' >> /tmp/spc-gnu-docker.env
143+
echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm -lresolv -lutil -lrt"' >> /tmp/spc-gnu-docker.env
144+
145+
# Run docker
146+
# shellcheck disable=SC2068
147+
# shellcheck disable=SC2086
148+
# shellcheck disable=SC2090
149+
150+
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-frankenphp-gnu-$SPC_USE_ARCH ./build-static.sh

bin/spc

+5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@
44
use SPC\ConsoleApplication;
55
use SPC\exception\ExceptionHandler;
66

7+
// Load custom php if exists
8+
if (PHP_OS_FAMILY !== 'Windows' && PHP_BINARY !== (__DIR__ . '/php') && file_exists(__DIR__ . '/php') && is_executable(__DIR__ . '/php')) {
9+
pcntl_exec(__DIR__ . '/php', $argv);
10+
}
11+
712
if (file_exists(dirname(__DIR__) . '/vendor/autoload.php')) {
813
// Current: ./bin (git/project mode)
914
require_once dirname(__DIR__) . '/vendor/autoload.php';

bin/spc-alpine-docker

+5-1
Original file line numberDiff line numberDiff line change
@@ -119,4 +119,8 @@ MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/pkgroot:/app/pkgroot"
119119
# shellcheck disable=SC2068
120120
# shellcheck disable=SC2086
121121
# shellcheck disable=SC2090
122-
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-v2 bin/spc $@
122+
if [ "$SPC_DOCKER_DEBUG" = "yes" ]; then
123+
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-v2
124+
else
125+
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" $MOUNT_LIST cwcc-spc-$SPC_USE_ARCH-v2 bin/spc $@
126+
fi

bin/spc-gnu-docker

+140
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#!/usr/bin/env bash
2+
3+
# This file is using docker to run commands
4+
set -e
5+
6+
# Detect docker can run
7+
if ! which docker >/dev/null; then
8+
echo "Docker is not installed, please install docker first !"
9+
exit 1
10+
fi
11+
DOCKER_EXECUTABLE="docker"
12+
# shellcheck disable=SC2046
13+
if [ $(id -u) -ne 0 ]; then
14+
if ! docker info > /dev/null 2>&1; then
15+
if [ "$SPC_USE_SUDO" != "yes" ]; then
16+
echo "Docker command requires sudo"
17+
# shellcheck disable=SC2039
18+
echo -n 'To use sudo to run docker, run "export SPC_USE_SUDO=yes" and run command again'
19+
exit 1
20+
fi
21+
DOCKER_EXECUTABLE="sudo docker"
22+
fi
23+
fi
24+
25+
26+
27+
# to check if qemu-docker run
28+
if [ "$SPC_USE_ARCH" = "" ]; then
29+
SPC_USE_ARCH=current
30+
fi
31+
case $SPC_USE_ARCH in
32+
current)
33+
BASE_ARCH=$(uname -m)
34+
if [ "$BASE_ARCH" = "arm64" ]; then
35+
BASE_ARCH=aarch64
36+
fi
37+
;;
38+
aarch64)
39+
BASE_ARCH=aarch64
40+
# shellcheck disable=SC2039
41+
echo -e "\e[033m* Using different arch needs to setup qemu-static for docker !\e[0m"
42+
$DOCKER_EXECUTABLE run --rm --privileged multiarch/qemu-user-static:register --reset > /dev/null
43+
;;
44+
*)
45+
echo "Current arch is not supported to run in docker: $SPC_USE_ARCH"
46+
exit 1
47+
;;
48+
esac
49+
50+
# Detect docker env is setup
51+
if ! $DOCKER_EXECUTABLE images | grep -q cwcc-spc-gnu-$SPC_USE_ARCH; then
52+
echo "Docker container does not exist. Building docker image ..."
53+
$DOCKER_EXECUTABLE build -t cwcc-spc-gnu-$SPC_USE_ARCH -f- . <<EOF
54+
FROM centos:7
55+
RUN sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo && \
56+
sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
57+
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo
58+
RUN yum clean all && \
59+
yum makecache && \
60+
yum update -y
61+
62+
RUN yum install -y centos-release-scl
63+
64+
RUN if [ "$BASE_ARCH" = "aarch64" ]; then \
65+
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl-rh.repo ; \
66+
sed -i 's|mirror.centos.org/centos|vault.centos.org/altarch|g' /etc/yum.repos.d/CentOS-SCLo-scl.repo ; \
67+
else \
68+
sed -i 's/mirror.centos.org/vault.centos.org/g' /etc/yum.repos.d/*.repo ; \
69+
fi
70+
RUN sed -i 's/^#.*baseurl=http/baseurl=http/g' /etc/yum.repos.d/*.repo && \
71+
sed -i 's/^mirrorlist=http/#mirrorlist=http/g' /etc/yum.repos.d/*.repo
72+
73+
RUN yum update -y && \
74+
yum install -y devtoolset-10-gcc-*
75+
RUN echo "source scl_source enable devtoolset-10" >> /etc/bashrc
76+
RUN source /etc/bashrc
77+
78+
RUN curl -o cmake.tgz -fsSL https://github.com/Kitware/CMake/releases/download/v3.31.4/cmake-3.31.4-linux-$BASE_ARCH.tar.gz && \
79+
mkdir /cmake && \
80+
tar -xzf cmake.tgz -C /cmake --strip-components 1
81+
82+
WORKDIR /app
83+
ADD ./src /app/src
84+
COPY ./composer.* /app/
85+
ADD ./bin/setup-runtime /app/bin/setup-runtime
86+
ADD ./bin/spc /app/bin/spc
87+
RUN /app/bin/setup-runtime
88+
RUN /app/bin/php /app/bin/composer install --no-dev --classmap-authoritative
89+
ENV PATH="/app/bin:/cmake/bin:$PATH"
90+
ENV SPC_SKIP_DOCTOR_CHECK_ITEMS="if musl-wrapper is installed,if musl-cross-make is installed"
91+
92+
ADD ./config/env.ini /app/config/env.ini
93+
RUN bin/spc doctor --auto-fix --debug
94+
95+
RUN curl -o make.tgz -fsSL https://ftp.gnu.org/gnu/make/make-4.4.tar.gz && \
96+
tar -zxvf make.tgz && \
97+
cd make-4.4 && \
98+
./configure && \
99+
make && \
100+
make install && \
101+
ln -sf /usr/local/bin/make /usr/bin/make
102+
103+
EOF
104+
fi
105+
106+
# Check if in ci (local terminal can execute with -it)
107+
if [ -t 0 ]; then
108+
INTERACT=-it
109+
else
110+
INTERACT=''
111+
fi
112+
113+
# Mounting volumes
114+
MOUNT_LIST=""
115+
# shellcheck disable=SC2089
116+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/config:/app/config"
117+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/src:/app/src"
118+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/buildroot:/app/buildroot"
119+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/source:/app/source"
120+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/dist:/app/dist"
121+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/downloads:/app/downloads"
122+
MOUNT_LIST="$MOUNT_LIST -v ""$(pwd)""/pkgroot:/app/pkgroot"
123+
124+
# Apply env in temp env file
125+
echo 'SPC_SKIP_DOCTOR_CHECK_ITEMS=if musl-wrapper is installed,if musl-cross-make is installed' > /tmp/spc-gnu-docker.env
126+
echo 'CC=/opt/rh/devtoolset-10/root/usr/bin/gcc' >> /tmp/spc-gnu-docker.env
127+
echo 'CXX=/opt/rh/devtoolset-10/root/usr/bin/g++' >> /tmp/spc-gnu-docker.env
128+
echo 'AR=/opt/rh/devtoolset-10/root/usr/bin/ar' >> /tmp/spc-gnu-docker.env
129+
echo 'LD=/opt/rh/devtoolset-10/root/usr/bin/ld' >> /tmp/spc-gnu-docker.env
130+
echo 'SPC_DEFAULT_C_FLAGS=-fPIE -fPIC' >> /tmp/spc-gnu-docker.env
131+
echo 'SPC_NO_MUSL_PATH=yes' >> /tmp/spc-gnu-docker.env
132+
echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LDFLAGS_PROGRAM="-Wl,-O1 -pie"' >> /tmp/spc-gnu-docker.env
133+
echo 'SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS="-ldl -lpthread -lm -lresolv -lutil -lrt"' >> /tmp/spc-gnu-docker.env
134+
135+
# Run docker
136+
# shellcheck disable=SC2068
137+
# shellcheck disable=SC2086
138+
# shellcheck disable=SC2090
139+
140+
$DOCKER_EXECUTABLE run --rm $INTERACT -e SPC_FIX_DEPLOY_ROOT="$(pwd)" --env-file /tmp/spc-gnu-docker.env $MOUNT_LIST cwcc-spc-gnu-$SPC_USE_ARCH # bin/spc $@

config/env.ini

+7-3
Original file line numberDiff line numberDiff line change
@@ -76,21 +76,23 @@ SPC_MICRO_PATCHES=static_extensions_win32,cli_checks,disable_huge_page,vcruntime
7676
; buildconf command
7777
SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
7878
; configure command
79-
SPC_CMD_PREFIX_PHP_CONFIGURE="${SPC_PHP_DEFAULT_LD_LIBRARY_PATH_CMD} ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg"
79+
SPC_CMD_PREFIX_PHP_CONFIGURE="${SPC_PHP_DEFAULT_LD_LIBRARY_PATH_CMD} ./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg --with-pic"
8080
; make command
8181
SPC_CMD_PREFIX_PHP_MAKE="make -j${CPU_COUNT}"
82+
; embed type for php, static (libphp.a) or shared (libphp.so)
83+
SPC_CMD_VAR_PHP_EMBED_TYPE="shared"
8284

8385
; *** default build vars for building php ***
8486
; CFLAGS for configuring php
85-
SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS="${SPC_DEFAULT_C_FLAGS}"
87+
SPC_CMD_VAR_PHP_CONFIGURE_CFLAGS="${SPC_DEFAULT_C_FLAGS} -fPIE"
8688
; CPPFLAGS for configuring php
8789
SPC_CMD_VAR_PHP_CONFIGURE_CPPFLAGS="-I${BUILD_INCLUDE_PATH}"
8890
; LDFLAGS for configuring php
8991
SPC_CMD_VAR_PHP_CONFIGURE_LDFLAGS="-L${BUILD_LIB_PATH}"
9092
; LIBS for configuring php
9193
SPC_CMD_VAR_PHP_CONFIGURE_LIBS="-ldl -lpthread -lm"
9294
; EXTRA_CFLAGS for `make` php
93-
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_PHP_DEFAULT_OPTIMIZE_CFLAGS} -fno-ident -fPIE"
95+
SPC_CMD_VAR_PHP_MAKE_EXTRA_CFLAGS="${SPC_PHP_DEFAULT_OPTIMIZE_CFLAGS} -fno-ident -fPIE -fPIC"
9496
; EXTRA_LIBS for `make` php
9597
SPC_CMD_VAR_PHP_MAKE_EXTRA_LIBS=""
9698
; EXTRA_LDFLAGS_PROGRAM for `make` php
@@ -115,6 +117,8 @@ SPC_CMD_PREFIX_PHP_BUILDCONF="./buildconf --force"
115117
SPC_CMD_PREFIX_PHP_CONFIGURE="./configure --prefix= --with-valgrind=no --enable-shared=no --enable-static=yes --disable-all --disable-cgi --disable-phpdbg"
116118
; make command
117119
SPC_CMD_PREFIX_PHP_MAKE="make -j${CPU_COUNT}"
120+
; embed type for php, static or shared
121+
SPC_CMD_VAR_PHP_EMBED_TYPE="static"
118122

119123
; *** default build vars for building php ***
120124
; CFLAGS for configuring php

docs/.vitepress/sidebar.en.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,24 @@
11
export default {
22
'/en/guide/': [
33
{
4-
text: 'Guide',
4+
text: 'Basic Build Guides',
55
items: [
66
{text: 'Guide', link: '/en/guide/'},
7-
{text: 'Actions Build', link: '/en/guide/action-build'},
8-
{text: 'Manual Build', link: '/en/guide/manual-build'},
9-
{text: 'Extension List', link: '/en/guide/extensions'},
7+
{text: 'Build (Local)', link: '/en/guide/manual-build'},
8+
{text: 'Build (CI)', link: '/en/guide/action-build'},
9+
{text: 'Supported Extensions', link: '/en/guide/extensions'},
1010
{text: 'Extension Notes', link: '/en/guide/extension-notes'},
11-
{text: 'Command Generator', link: '/en/guide/cli-generator'},
11+
{text: 'Build Command Generator', link: '/en/guide/cli-generator'},
1212
{text: 'Environment Variables', link: '/en/guide/env-vars', collapsed: true,},
1313
{text: 'Dependency Table', link: '/en/guide/deps-map'},
1414
]
1515
},
1616
{
17+
text: 'Extended Build Guides',
1718
items: [
1819
{text: 'Troubleshooting', link: '/en/guide/troubleshooting'},
1920
{text: 'Build on Windows', link: '/en/guide/build-on-windows'},
21+
{text: 'Build with GNU libc', link: '/en/guide/build-with-glibc'},
2022
],
2123
}
2224
],

0 commit comments

Comments
 (0)