From 7c845c34d4680f41239ec8b97a035931f4f983a9 Mon Sep 17 00:00:00 2001 From: Michael Bolin Date: Thu, 5 Jun 2025 16:47:52 -0700 Subject: [PATCH] fix: support arm64 build for Linux --- .devcontainer/Dockerfile | 29 +++++++++++++++++++++++++++++ .devcontainer/README.md | 30 ++++++++++++++++++++++++++++++ .devcontainer/devcontainer.json | 29 +++++++++++++++++++++++++++++ .github/workflows/rust-ci.yml | 6 +++++- .github/workflows/rust-release.yml | 4 +++- codex-rs/.gitignore | 6 ++++++ codex-rs/core/Cargo.toml | 4 ++++ 7 files changed, 106 insertions(+), 2 deletions(-) create mode 100644 .devcontainer/Dockerfile create mode 100644 .devcontainer/README.md create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile new file mode 100644 index 0000000000..259e59ab31 --- /dev/null +++ b/.devcontainer/Dockerfile @@ -0,0 +1,29 @@ +FROM ubuntu:22.04 + +ARG DEBIAN_FRONTEND=noninteractive +# enable 'universe' because musl-tools & clang live there +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + software-properties-common && \ + add-apt-repository --yes universe + +# now install build deps +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + build-essential curl git ca-certificates \ + pkg-config clang musl-tools libssl-dev && \ + rm -rf /var/lib/apt/lists/* + +# non-root dev user +ARG USER=dev +ARG UID=1000 +RUN useradd -m -u $UID $USER +USER $USER + +# install Rust + musl target as dev user +RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal && \ + ~/.cargo/bin/rustup target add aarch64-unknown-linux-musl + +ENV PATH="/home/${USER}/.cargo/bin:${PATH}" + +WORKDIR /workspace diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 0000000000..58e4458a06 --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,30 @@ +# Containerized Development + +We provide the following options to facilitate Codex development in a container. This is particularly useful for verifying the Linux build when working on a macOS host. + +## Docker + +To build the Docker image locally for x64 and then run it with the repo mounted under `/workspace`: + +```shell +CODEX_DOCKER_IMAGE_NAME=codex-linux-dev +docker build --platform=linux/amd64 -t "$CODEX_DOCKER_IMAGE_NAME" ./.devcontainer +docker run --platform=linux/amd64 --rm -it -e CARGO_TARGET_DIR=/workspace/codex-rs/target-amd64 -v "$PWD":/workspace -w /workspace/codex-rs "$CODEX_DOCKER_IMAGE_NAME" +``` + +Note that `/workspace/target` will contain the binaries built for your host platform, so we include `-e CARGO_TARGET_DIR=/workspace/codex-rs/target-amd64` in the `docker run` command so that the binaries built inside your container are written to a separate directory. + +For arm64, specify `--platform=linux/amd64` instead for both `docker build` and `docker run`. + +Currently, the `Dockerfile` works for both x64 and arm64 Linux, though you need to run `rustup target add x86_64-unknown-linux-musl` yourself to install the musl toolchain for x64. + +## VS Code + +VS Code recognizes the `devcontainer.json` file and gives you the option to develop Codex in a container. Currently, `devcontainer.json` builds and runs the `arm64` flavor of the container. + +From the integrated terminal in VS Code, you can build either flavor of the `arm64` build (GNU or musl): + +```shell +cargo build --target aarch64-unknown-linux-musl +cargo build --target aarch64-unknown-linux-gnu +``` diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..17aee91421 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,29 @@ +{ + "name": "Codex", + "build": { + "dockerfile": "Dockerfile", + "context": "..", + "platform": "linux/arm64" + }, + + /* Force VS Code to run the container as arm64 in + case your host is x86 (or vice-versa). */ + "runArgs": ["--platform=linux/arm64"], + + "containerEnv": { + "RUST_BACKTRACE": "1", + "CARGO_TARGET_DIR": "${containerWorkspaceFolder}/codex-rs/target-arm64" + }, + + "remoteUser": "dev", + "customizations": { + "vscode": { + "settings": { + "terminal.integrated.defaultProfile.linux": "bash" + }, + "extensions": [ + "rust-lang.rust-analyzer" + ], + } + } +} diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index f0eadaf254..3c836b8a01 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -55,6 +55,10 @@ jobs: target: x86_64-unknown-linux-musl - runner: ubuntu-24.04 target: x86_64-unknown-linux-gnu + - runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-musl + - runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-gnu - runner: windows-latest target: x86_64-pc-windows-msvc @@ -75,7 +79,7 @@ jobs: ${{ github.workspace }}/codex-rs/target/ key: cargo-${{ matrix.runner }}-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} name: Install musl build tools run: | sudo apt install -y musl-tools pkg-config diff --git a/.github/workflows/rust-release.yml b/.github/workflows/rust-release.yml index bb5ca67ce4..7c89622390 100644 --- a/.github/workflows/rust-release.yml +++ b/.github/workflows/rust-release.yml @@ -69,6 +69,8 @@ jobs: target: x86_64-unknown-linux-musl - runner: ubuntu-24.04 target: x86_64-unknown-linux-gnu + - runner: ubuntu-24.04-arm + target: aarch64-unknown-linux-musl - runner: ubuntu-24.04-arm target: aarch64-unknown-linux-gnu @@ -88,7 +90,7 @@ jobs: ${{ github.workspace }}/codex-rs/target/ key: cargo-release-${{ matrix.runner }}-${{ matrix.target }}-${{ hashFiles('**/Cargo.lock') }} - - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' }} + - if: ${{ matrix.target == 'x86_64-unknown-linux-musl' || matrix.target == 'aarch64-unknown-linux-musl'}} name: Install musl build tools run: | sudo apt install -y musl-tools pkg-config diff --git a/codex-rs/.gitignore b/codex-rs/.gitignore index b83d22266a..e996253768 100644 --- a/codex-rs/.gitignore +++ b/codex-rs/.gitignore @@ -1 +1,7 @@ /target/ + +# Recommended value of CARGO_TARGET_DIR when using Docker as explained in .devcontainer/README.md. +/target-amd64/ + +# Value of CARGO_TARGET_DIR when using .devcontainer/devcontainer.json. +/target-arm64/ diff --git a/codex-rs/core/Cargo.toml b/codex-rs/core/Cargo.toml index 4739ef31ed..2f110d9a6d 100644 --- a/codex-rs/core/Cargo.toml +++ b/codex-rs/core/Cargo.toml @@ -58,6 +58,10 @@ seccompiler = "0.5.0" [target.x86_64-unknown-linux-musl.dependencies] openssl-sys = { version = "*", features = ["vendored"] } +# Build OpenSSL from source for musl builds. +[target.aarch64-unknown-linux-musl.dependencies] +openssl-sys = { version = "*", features = ["vendored"] } + [dev-dependencies] assert_cmd = "2" maplit = "1.0.2"