Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ jobs:
macos_cross: false

- target: x86_64-pc-windows-msvc
runner: windows-latest
runner: ubuntu-24.04
binary_ext: ".exe"
linux_cross: false
macos_cross: false
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/release-auto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ jobs:
macos_cross: false

- target: x86_64-pc-windows-msvc
runner: windows-latest
runner: ubuntu-24.04
binary_ext: ".exe"
linux_cross: false
macos_cross: false
Expand Down
70 changes: 59 additions & 11 deletions .github/workflows/template_native_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,24 +84,65 @@ jobs:

# Linux musl toolchain (libudev is auto-excluded for musl targets by serialport)
- name: Install Linux dependencies
if: runner.os == 'Linux' && !inputs.linux_cross
if: runner.os == 'Linux' && !inputs.linux_cross && !contains(inputs.target, 'pc-windows-msvc')
run: |
sudo apt-get update
sudo apt-get install -y musl-tools pkg-config

# Windows MSVC release artifacts are built from Linux with cargo-xwin.
- name: Install cargo-xwin
if: contains(inputs.target, 'pc-windows-msvc')
uses: taiki-e/install-action@v2
with:
tool: cargo-xwin

- name: Install xwin system dependencies
if: contains(inputs.target, 'pc-windows-msvc')
run: |
sudo apt-get update
sudo apt-get install -y --no-install-recommends clang lld zip

# cargo-zigbuild — used for two reasons on Linux:
# 1. musl cross-compilation (linux_cross targets)
# 2. Building the PyO3 extension with a pinned glibc symbol version
# so manylinux_2_17 wheels actually run on glibc 2.17. The native
# ubuntu-latest linker would otherwise pull in glibc 2.39 symbols.
- name: Install cross-compilation tools
if: runner.os == 'Linux'
if: runner.os == 'Linux' && !contains(inputs.target, 'pc-windows-msvc')
run: pip install cargo-zigbuild

- name: Fetch Windows Python lib for PyO3 cross-compile
if: contains(inputs.target, 'pc-windows-msvc')
shell: bash
run: |
set -euo pipefail
PYTHON_VERSION="3.13.0"
if [[ "${{ inputs.target }}" == aarch64-* ]]; then
PKG="pythonarm64"
else
PKG="python"
fi
curl -fsSL -o python.zip "https://www.nuget.org/api/v2/package/${PKG}/${PYTHON_VERSION}"
mkdir -p python-windows
unzip -q python.zip -d python-windows
libs_dir="$(pwd)/python-windows/tools/libs"
if [ ! -f "$libs_dir/python3.lib" ]; then
echo "ERROR: python3.lib not found in extracted NuGet package" >&2
find python-windows -name "python3*.lib" || true
exit 1
fi
echo "PYO3_CROSS_LIB_DIR=$libs_dir" >> "$GITHUB_ENV"
echo "PYO3_CROSS_PYTHON_VERSION=3.13" >> "$GITHUB_ENV"
echo "PYO3_CROSS_PYTHON_IMPLEMENTATION=CPython" >> "$GITHUB_ENV"

- name: Build release binaries
shell: bash
run: |
if [[ "${{ inputs.target }}" == *-unknown-linux-musl ]]; then
if [[ "${{ inputs.target }}" == *-pc-windows-msvc ]]; then
cargo xwin build --release --target ${{ inputs.target }} \
-p fbuild-cli \
-p fbuild-daemon
elif [[ "${{ inputs.target }}" == *-unknown-linux-musl ]]; then
# Direct `cargo zigbuild` (pip-installed wrapper) bypasses
# soldr's bin cache, which has been serving a corrupted
# cargo-zigbuild binary (`Syntax error: ")" unexpected` at
Expand Down Expand Up @@ -131,7 +172,12 @@ jobs:
shell: bash
run: |
PYTHON_TARGET_DIR="target/python-extension"
if [ "${{ runner.os }}" = "Linux" ]; then
if [[ "${{ inputs.target }}" == *-pc-windows-msvc ]]; then
PYO3_NO_PYTHON=1 cargo xwin build --release \
--target-dir "${PYTHON_TARGET_DIR}" \
--target ${{ inputs.target }} -p fbuild-python \
--features extension-module
elif [ "${{ runner.os }}" = "Linux" ]; then
TARGET="${{ inputs.target }}"
ARCH="${TARGET%%-*}"
PYO3_TARGET="${ARCH}-unknown-linux-gnu"
Expand Down Expand Up @@ -167,7 +213,13 @@ jobs:
cp target/${{ inputs.target }}/release/fbuild-daemon${{ inputs.binary_ext }} staging/

# Stage Python extension — location depends on how it was built
if [ "${{ runner.os }}" = "Linux" ]; then
if [[ "${{ inputs.target }}" == *-pc-windows-msvc ]]; then
for ext_src in \
"${PYTHON_TARGET_DIR}/${{ inputs.target }}/release/_native.dll" \
"${PYTHON_TARGET_DIR}/release/_native.dll"; do
[ -f "$ext_src" ] && cp "$ext_src" staging/_native.pyd && break
done
elif [ "${{ runner.os }}" = "Linux" ]; then
TARGET="${{ inputs.target }}"
ARCH="${TARGET%%-*}"
ext_src="${PYTHON_TARGET_DIR}/${ARCH}-unknown-linux-gnu.2.17/release/lib_native.so"
Expand All @@ -176,12 +228,6 @@ jobs:
elif [ "${{ runner.os }}" = "macOS" ]; then
ext_src="${PYTHON_TARGET_DIR}/${{ inputs.target }}/release/lib_native.dylib"
[ -f "$ext_src" ] && cp "$ext_src" staging/_native.abi3.so
elif [ "${{ inputs.binary_ext }}" = ".exe" ]; then
for ext_src in \
"${PYTHON_TARGET_DIR}/${{ inputs.target }}/release/_native.dll" \
"${PYTHON_TARGET_DIR}/release/_native.dll"; do
[ -f "$ext_src" ] && cp "$ext_src" staging/_native.pyd && break
done
else
for ext in so dylib; do
src="${PYTHON_TARGET_DIR}/release/lib_native.$ext"
Expand All @@ -201,6 +247,8 @@ jobs:
llvm-strip staging/fbuild || true
llvm-strip staging/fbuild-daemon || true
llvm-strip staging/_native.abi3.so 2>/dev/null || true
elif [[ "${{ inputs.target }}" == *-pc-windows-msvc ]]; then
true
elif command -v strip &> /dev/null; then
strip staging/fbuild${{ inputs.binary_ext }} || true
strip staging/fbuild-daemon${{ inputs.binary_ext }} || true
Expand Down
Loading