Skip to content

Commit 69c1895

Browse files
committed
ci: add musl build step
1 parent 3f6595d commit 69c1895

File tree

8 files changed

+160
-18
lines changed

8 files changed

+160
-18
lines changed

.cargo/config.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,7 @@ linker = "rust-lld"
66

77
[target.i686-pc-windows-msvc]
88
linker = "rust-lld"
9+
10+
[target.'cfg(target_env = "musl")']
11+
rustflags = ["-C", "target-feature=-crt-static"]
12+
linker = "rust-lld"

.github/action/musl/Dockerfile

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
FROM alpine:3.20
2+
3+
ARG PHP_VERSION=8.4
4+
ARG TS=ts
5+
6+
RUN apk add --no-cache \
7+
autoconf \
8+
automake \
9+
bison \
10+
re2c \
11+
gcc \
12+
g++ \
13+
make \
14+
musl-dev \
15+
linux-headers \
16+
pkgconfig \
17+
curl \
18+
jq \
19+
llvm17 \
20+
llvm17-dev \
21+
llvm17-libs \
22+
llvm17-static \
23+
zlib-static \
24+
ncurses-static \
25+
libffi-dev \
26+
libstdc++-dev
27+
28+
WORKDIR /tmp
29+
RUN FULL_VERSION=$(curl -fsSL "https://www.php.net/releases/index.php?json&version=${PHP_VERSION}" | jq -r '.version') && \
30+
echo "Downloading PHP ${FULL_VERSION}..." && \
31+
curl -fsSL "https://www.php.net/distributions/php-${FULL_VERSION}.tar.gz" -o php.tar.gz && \
32+
tar -xzf php.tar.gz && \
33+
rm php.tar.gz && \
34+
mv "php-${FULL_VERSION}" php-src
35+
36+
WORKDIR /tmp/php-src
37+
RUN CONFIGURE_OPTS="--enable-debug --enable-embed=shared --disable-all --disable-cgi" && \
38+
if [ "$TS" = "ts" ]; then CONFIGURE_OPTS="$CONFIGURE_OPTS --enable-zts"; fi && \
39+
./configure $CONFIGURE_OPTS --prefix=/usr/local && \
40+
make -j$(nproc) && \
41+
make install && \
42+
rm -rf /tmp/php-src
43+
44+
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
45+
ENV PATH="/root/.cargo/bin:${PATH}"
46+
47+
RUN rustup target add x86_64-unknown-linux-musl
48+
49+
ENV PHP=/usr/local/bin/php
50+
ENV PHP_CONFIG=/usr/local/bin/php-config
51+
52+
ENV LLVM_CONFIG_PATH=/usr/lib/llvm17/bin/llvm-config
53+
ENV LIBCLANG_PATH=/usr/lib/llvm17/lib
54+
ENV LIBRARY_PATH=/usr/lib/llvm17/lib:$LIBRARY_PATH
55+
ENV LD_LIBRARY_PATH=/usr/lib/llvm17/lib:$LD_LIBRARY_PATH
56+
57+
ENV RUSTFLAGS="-C link-arg=-L/usr/lib/llvm17/lib -C link-arg=-Wl,--allow-multiple-definition -C target-feature=-crt-static"
58+
59+
WORKDIR /workspace
60+
61+
COPY . .
62+
63+
ENTRYPOINT ["cargo"]
64+
CMD ["build", "--release", "--no-default-features", "--features", "closure,anyhow,static,enum", "--workspace", "--target", "x86_64-unknown-linux-musl"]

.github/workflows/build.yml

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ jobs:
168168
# Macos fails on unstable rust. We skip the inline examples test for now.
169169
if: "!(contains(matrix.os, 'macos') && matrix.rust == 'nightly')"
170170
run: cargo test --release --workspace --features closure,anyhow,runtime --no-fail-fast
171-
172171
test-embed:
173172
name: Test with embed
174173
runs-on: ubuntu-latest
@@ -226,3 +225,50 @@ jobs:
226225
227226
- name: Test with embed feature
228227
run: cargo test --workspace --release --features closure,embed,anyhow --no-fail-fast
228+
229+
build-musl:
230+
name: musl
231+
runs-on: ubuntu-latest
232+
strategy:
233+
matrix:
234+
php: ["8.1", "8.2", "8.3", "8.4"]
235+
phpts: [ts, nts]
236+
env:
237+
CARGO_TERM_COLOR: always
238+
steps:
239+
- name: Checkout code
240+
uses: actions/checkout@v5
241+
- name: Setup PHP
242+
uses: shivammathur/setup-php@v2
243+
with:
244+
php-version: ${{ matrix.php }}
245+
env:
246+
phpts: ${{ matrix.phpts }}
247+
debug: true
248+
249+
- name: Cache LLVM and Clang
250+
id: cache-llvm
251+
uses: actions/cache@v4
252+
with:
253+
path: ${{ runner.temp }}/llvm-17
254+
key: ubuntu-latest-llvm-17
255+
- name: Setup LLVM & Clang
256+
id: clang
257+
uses: KyleMayes/install-llvm-action@v2
258+
with:
259+
version: 17
260+
directory: ${{ runner.temp }}/llvm-17
261+
cached: ${{ steps.cache-llvm.outputs.cache-hit }}
262+
- name: Configure Clang
263+
run: |
264+
echo "LIBCLANG_PATH=${{ runner.temp }}/llvm-17/lib" >> $GITHUB_ENV
265+
echo "LLVM_VERSION=${{ steps.clang.outputs.version }}" >> $GITHUB_ENV
266+
echo "LLVM_CONFIG_PATH=${{ runner.temp }}/llvm-17/bin/llvm-config" >> $GITHUB_ENV
267+
268+
- name: Build
269+
uses: houseabsolute/actions-rust-cross@v1
270+
with:
271+
target: x86_64-unknown-linux-musl
272+
use-rust-cache: true
273+
command: build
274+
args: --release --no-default-features --features closure,anyhow,runtime,enum --workspace

Dockerfile

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@ apt update -y
88
apt install -y \
99
libclang-dev \
1010
bison \
11-
re2c
11+
re2c \
12+
curl \
13+
jq
14+
15+
# Download and extract PHP
16+
FULL_VERSION=$(curl -fsSL "https://www.php.net/releases/index.php?json&version=${PHP_VERSION}" | jq -r '.version')
17+
echo "Downloading PHP ${FULL_VERSION}..."
18+
curl -fsSL "https://www.php.net/distributions/php-${FULL_VERSION}.tar.gz" -o php.tar.gz
19+
tar -xzf php.tar.gz
20+
rm php.tar.gz
21+
mv "php-${FULL_VERSION}" php-src
1222

1323
# Build PHP
14-
git clone --depth 1 -b PHP-${PHP_VERSION} https://github.com/php/php-src.git
1524
cd php-src
16-
# by default you will be on the master branch, which is the current
17-
# development version. You can check out a stable branch instead:
18-
./buildconf
1925
./configure \
2026
--enable-debug \
2127
--disable-all --disable-cgi

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,22 @@ best resource at the moment. This can be viewed at [docs.rs].
126126
1.57 at the time of writing.
127127
- Clang 5.0 or later.
128128

129+
### Alpine Linux (musl) Requirements
130+
131+
Building for Alpine Linux (musl libc) is supported on stable Rust with the following
132+
requirements:
133+
134+
- Install musl toolchain: `sudo apt-get install musl-tools musl-dev`
135+
- Add musl target: `rustup target add x86_64-unknown-linux-musl`
136+
- Build with dynamic linking flag:
137+
```bash
138+
RUSTFLAGS="-C target-feature=-crt-static" \
139+
cargo build --target x86_64-unknown-linux-musl
140+
```
141+
142+
**Note**: Building for musl requires dynamic CRT linking (`-crt-static` flag) to produce
143+
the `cdylib` output required for PHP extensions.
144+
129145
### Windows Requirements
130146

131147
- Extensions can only be compiled for PHP installations sourced from

tests/Cargo.toml

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,20 @@
11
[package]
22
name = "tests"
33
version = "0.0.0"
4-
edition = "2021"
4+
edition = "2024"
55
publish = false
66
license = "MIT OR Apache-2.0"
77

88
[dependencies]
9-
ext-php-rs = { path = "../", default-features = false, features = ["closure", "runtime"] }
9+
ext-php-rs = { path = "../", default-features = false }
1010

1111
[features]
12-
default = ["enum"]
12+
default = ["enum", "runtime", "closure"]
1313
enum = ["ext-php-rs/enum"]
14+
anyhow = ["ext-php-rs/anyhow"]
15+
runtime = ["ext-php-rs/runtime"]
16+
closure = ["ext-php-rs/closure"]
17+
static = ["ext-php-rs/static"]
1418

1519
[lib]
1620
crate-type = ["cdylib"]

tests/src/integration/mod.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,13 @@ mod test {
3636
{
3737
command.arg("--features=enum");
3838
}
39-
assert!(command
40-
.output()
41-
.expect("failed to build extension")
42-
.status
43-
.success());
39+
assert!(
40+
command
41+
.output()
42+
.expect("failed to build extension")
43+
.status
44+
.success()
45+
);
4446
});
4547
}
4648

tests/src/integration/variadic_args/mod.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,10 @@ pub fn test_variadic_first_last(items: &[&Zval]) -> Vec<Zval> {
7979
if let Some(first) = items.first() {
8080
result.push(first.shallow_clone());
8181
}
82-
if let Some(last) = items.last() {
83-
if items.len() > 1 {
84-
result.push(last.shallow_clone());
85-
}
82+
if let Some(last) = items.last()
83+
&& items.len() > 1
84+
{
85+
result.push(last.shallow_clone());
8686
}
8787
result
8888
}

0 commit comments

Comments
 (0)