mirror of
https://github.com/openai/codex.git
synced 2026-02-01 22:47:52 +00:00
feat: add support for building with Bazel (#8875)
This PR configures Codex CLI so it can be built with [Bazel](https://bazel.build) in addition to Cargo. The `.bazelrc` includes configuration so that remote builds can be done using [BuildBuddy](https://www.buildbuddy.io). If you are familiar with Bazel, things should work as you expect, e.g., run `bazel test //... --keep-going` to run all the tests in the repo, but we have also added some new aliases in the `justfile` for convenience: - `just bazel-test` to run tests locally - `just bazel-remote-test` to run tests remotely (currently, the remote build is for x86_64 Linux regardless of your host platform). Note we are currently seeing the following test failures in the remote build, so we still need to figure out what is happening here: ``` failures: suite::compact::manual_compact_twice_preserves_latest_user_messages suite::compact_resume_fork::compact_resume_after_second_compaction_preserves_history suite::compact_resume_fork::compact_resume_and_fork_preserve_model_history_view ``` - `just build-for-release` to build release binaries for all platforms/architectures remotely To setup remote execution: - [Create a buildbuddy account](https://app.buildbuddy.io/) (OpenAI employees should also request org access at https://openai.buildbuddy.io/join/ with their `@openai.com` email address.) - [Copy your API key](https://app.buildbuddy.io/docs/setup/) to `~/.bazelrc` (add the line `build --remote_header=x-buildbuddy-api-key=YOUR_KEY`) - Use `--config=remote` in your `bazel` invocations (or add `common --config=remote` to your `~/.bazelrc`, or use the `just` commands) ## CI In terms of CI, this PR introduces `.github/workflows/bazel.yml`, which uses Bazel to run the tests _locally_ on Mac and Linux GitHub runners (we are working on supporting Windows, but that is not ready yet). Note that the failures we are seeing in `just bazel-remote-test` do not occur on these GitHub CI jobs, so everything in `.github/workflows/bazel.yml` is green right now. The `bazel.yml` uses extra config in `.github/workflows/ci.bazelrc` so that macOS CI jobs build _remotely_ on Linux hosts (using the `docker://docker.io/mbolin491/codex-bazel` Docker image declared in the root `BUILD.bazel`) using cross-compilation to build the macOS artifacts. Then these artifacts are downloaded locally to GitHub's macOS runner so the tests can be executed natively. This is the relevant config that enables this: ``` common:macos --config=remote common:macos --strategy=remote common:macos --strategy=TestRunner=darwin-sandbox,local ``` Because of the remote caching benefits we get from BuildBuddy, these new CI jobs can be extremely fast! For example, consider these two jobs that ran all the tests on Linux x86_64: - Bazel 1m37s https://github.com/openai/codex/actions/runs/20861063212/job/59940545209?pr=8875 - Cargo 9m20s https://github.com/openai/codex/actions/runs/20861063192/job/59940559592?pr=8875 For now, we will continue to run both the Bazel and Cargo jobs for PRs, but once we add support for Windows and running Clippy, we should be able to cutover to using Bazel exclusively for PRs, which should still speed things up considerably. We will probably continue to run the Cargo jobs post-merge for commits that land on `main` as a sanity check. Release builds will also continue to be done by Cargo for now. Earlier attempt at this PR: https://github.com/openai/codex/pull/8832 Earlier attempt to add support for Buck2, now abandoned: https://github.com/openai/codex/pull/8504 --------- Co-authored-by: David Zbarsky <dzbarsky@gmail.com> Co-authored-by: Michael Bolin <mbolin@openai.com>
This commit is contained in:
45
.bazelrc
Normal file
45
.bazelrc
Normal file
@@ -0,0 +1,45 @@
|
||||
common --repo_env=BAZEL_DO_NOT_DETECT_CPP_TOOLCHAIN=1
|
||||
common --repo_env=BAZEL_NO_APPLE_CPP_TOOLCHAIN=1
|
||||
|
||||
common --disk_cache=~/.cache/bazel-disk-cache
|
||||
common --repo_contents_cache=~/.cache/bazel-repo-contents-cache
|
||||
common --repository_cache=~/.cache/bazel-repo-cache
|
||||
|
||||
common --experimental_platform_in_output_dir
|
||||
|
||||
common --enable_platform_specific_config
|
||||
# TODO(zbarsky): We need to untangle these libc constraints to get linux remote builds working.
|
||||
common:linux --host_platform=//:local
|
||||
common --@rules_cc//cc/toolchains/args/archiver_flags:use_libtool_on_macos=False
|
||||
common --@toolchains_llvm_bootstrapped//config:experimental_stub_libgcc_s
|
||||
|
||||
# We need to use the sh toolchain on windows so we don't send host bash paths to the linux executor.
|
||||
common:windows --@rules_rust//rust/settings:experimental_use_sh_toolchain_for_bootstrap_process_wrapper
|
||||
|
||||
# TODO(zbarsky): rules_rust doesn't implement this flag properly with remote exec...
|
||||
# common --@rules_rust//rust/settings:pipelined_compilation
|
||||
|
||||
common --incompatible_strict_action_env
|
||||
# Not ideal, but We need to allow dotslash to be found
|
||||
common --test_env=PATH=/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
|
||||
common --test_output=errors
|
||||
common --bes_results_url=https://app.buildbuddy.io/invocation/
|
||||
common --bes_backend=grpcs://remote.buildbuddy.io
|
||||
common --remote_cache=grpcs://remote.buildbuddy.io
|
||||
common --remote_download_toplevel
|
||||
common --nobuild_runfile_links
|
||||
common --remote_timeout=3600
|
||||
common --noexperimental_throttle_remote_action_building
|
||||
common --experimental_remote_execution_keepalive
|
||||
common --grpc_keepalive_time=30s
|
||||
|
||||
# This limits both in-flight executions and concurrent downloads. Even with high number
|
||||
# of jobs execution will still be limited by CPU cores, so this just pays a bit of
|
||||
# memory in exchange for higher download concurrency.
|
||||
common --jobs=30
|
||||
|
||||
common:remote --extra_execution_platforms=//:rbe
|
||||
common:remote --remote_executor=grpcs://remote.buildbuddy.io
|
||||
common:remote --jobs=800
|
||||
|
||||
20
.github/workflows/Dockerfile.bazel
vendored
Normal file
20
.github/workflows/Dockerfile.bazel
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
FROM ubuntu:24.04
|
||||
|
||||
# TODO(mbolin): Published to docker.io/mbolin491/codex-bazel:latest for
|
||||
# initial debugging, but we should publish to a more proper location.
|
||||
#
|
||||
# docker buildx create --use
|
||||
# docker buildx build --platform linux/amd64 -f .github/workflows/Dockerfile.bazel -t mbolin491/codex-bazel:latest --push .
|
||||
|
||||
RUN apt-get update && \
|
||||
apt-get install -y --no-install-recommends \
|
||||
curl git python3 ca-certificates && \
|
||||
rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install dotslash.
|
||||
RUN curl -LSfs "https://github.com/facebook/dotslash/releases/download/v0.5.8/dotslash-ubuntu-22.04.$(uname -m).tar.gz" | tar fxz - -C /usr/local/bin
|
||||
|
||||
# Ubuntu 24.04 ships with user 'ubuntu' already created with UID 1000.
|
||||
USER ubuntu
|
||||
|
||||
WORKDIR /workspace
|
||||
110
.github/workflows/bazel.yml
vendored
Normal file
110
.github/workflows/bazel.yml
vendored
Normal file
@@ -0,0 +1,110 @@
|
||||
name: Bazel (experimental)
|
||||
|
||||
# Note this workflow was originally derived from:
|
||||
# https://github.com/cerisier/toolchains_llvm_bootstrapped/blob/main/.github/workflows/ci.yaml
|
||||
|
||||
on:
|
||||
pull_request: {}
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
# Cancel previous actions from the same PR or branch except 'main' branch.
|
||||
# See https://docs.github.com/en/actions/using-jobs/using-concurrency and https://docs.github.com/en/actions/learn-github-actions/contexts for more info.
|
||||
group: concurrency-group::${{ github.workflow }}::${{ github.event.pull_request.number > 0 && format('pr-{0}', github.event.pull_request.number) || github.ref_name }}${{ github.ref_name == 'main' && format('::{0}', github.run_id) || ''}}
|
||||
cancel-in-progress: ${{ github.ref_name != 'main' }}
|
||||
jobs:
|
||||
test:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
# macOS
|
||||
- os: macos-15-xlarge
|
||||
target: aarch64-apple-darwin
|
||||
- os: macos-15-xlarge
|
||||
target: x86_64-apple-darwin
|
||||
|
||||
# Linux
|
||||
- os: ubuntu-24.04-arm
|
||||
target: aarch64-unknown-linux-gnu
|
||||
- os: ubuntu-24.04
|
||||
target: x86_64-unknown-linux-gnu
|
||||
- os: ubuntu-24.04-arm
|
||||
target: aarch64-unknown-linux-musl
|
||||
- os: ubuntu-24.04
|
||||
target: x86_64-unknown-linux-musl
|
||||
# TODO: Enable Windows once we fix the toolchain issues there.
|
||||
#- os: windows-latest
|
||||
# target: x86_64-pc-windows-gnullvm
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
# Configure a human readable name for each job
|
||||
name: Local Bazel build on ${{ matrix.os }} for ${{ matrix.target }}
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
|
||||
# Some integration tests rely on DotSlash being installed.
|
||||
# See https://github.com/openai/codex/pull/7617.
|
||||
- name: Install DotSlash
|
||||
uses: facebook/install-dotslash@v2
|
||||
|
||||
- name: Make DotSlash available in PATH (Unix)
|
||||
if: runner.os != 'Windows'
|
||||
run: cp "$(which dotslash)" /usr/local/bin
|
||||
|
||||
- name: Make DotSlash available in PATH (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: Copy-Item (Get-Command dotslash).Source -Destination "$env:LOCALAPPDATA\Microsoft\WindowsApps\dotslash.exe"
|
||||
|
||||
# Install Bazel via Bazelisk
|
||||
- name: Set up Bazel
|
||||
uses: bazelbuild/setup-bazelisk@v3
|
||||
|
||||
# TODO(mbolin): Bring this back once we have caching working. Currently,
|
||||
# we never seem to get a cache hit but we still end up paying the cost of
|
||||
# uploading at the end of the build, which takes over a minute!
|
||||
#
|
||||
# Cache build and external artifacts so that the next ci build is incremental.
|
||||
# Because github action caches cannot be updated after a build, we need to
|
||||
# store the contents of each build in a unique cache key, then fall back to loading
|
||||
# it on the next ci run. We use hashFiles(...) in the key and restore-keys- with
|
||||
# the prefix to load the most recent cache for the branch on a cache miss. You
|
||||
# should customize the contents of hashFiles to capture any bazel input sources,
|
||||
# although this doesn't need to be perfect. If none of the input sources change
|
||||
# then a cache hit will load an existing cache and bazel won't have to do any work.
|
||||
# In the case of a cache miss, you want the fallback cache to contain most of the
|
||||
# previously built artifacts to minimize build time. The more precise you are with
|
||||
# hashFiles sources the less work bazel will have to do.
|
||||
# - name: Mount bazel caches
|
||||
# uses: actions/cache@v4
|
||||
# with:
|
||||
# path: |
|
||||
# ~/.cache/bazel-repo-cache
|
||||
# ~/.cache/bazel-repo-contents-cache
|
||||
# key: bazel-cache-${{ matrix.os }}-${{ hashFiles('**/BUILD.bazel', '**/*.bzl', 'MODULE.bazel') }}
|
||||
# restore-keys: |
|
||||
# bazel-cache-${{ matrix.os }}
|
||||
|
||||
- name: Configure Bazel startup args (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
shell: pwsh
|
||||
run: |
|
||||
# Use a very short path to reduce argv/path length issues.
|
||||
"BAZEL_STARTUP_ARGS=--output_user_root=C:\" | Out-File -FilePath $env:GITHUB_ENV -Encoding utf8 -Append
|
||||
|
||||
- name: bazel test //...
|
||||
env:
|
||||
BUILDBUDDY_API_KEY: ${{ secrets.BUILDBUDDY_API_KEY }}
|
||||
shell: bash
|
||||
run: |
|
||||
bazel $BAZEL_STARTUP_ARGS --bazelrc=.github/workflows/ci.bazelrc test //... \
|
||||
--build_metadata=REPO_URL=https://github.com/openai/codex.git \
|
||||
--build_metadata=COMMIT_SHA=$(git rev-parse HEAD) \
|
||||
--build_metadata=ROLE=CI \
|
||||
--build_metadata=VISIBILITY=PUBLIC \
|
||||
"--remote_header=x-buildbuddy-api-key=$BUILDBUDDY_API_KEY"
|
||||
15
.github/workflows/ci.bazelrc
vendored
Normal file
15
.github/workflows/ci.bazelrc
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
common --remote_download_minimal
|
||||
common --nobuild_runfile_links
|
||||
common --keep_going
|
||||
|
||||
# Prefer to run the build actions entirely remotely so we can dial up the concurrency.
|
||||
# Currently remote builds only work on Mac hosts, until we untangle the libc constraints mess on linux.
|
||||
common:macos --config=remote
|
||||
common:macos --strategy=remote
|
||||
|
||||
# We have platform-specific tests, so execute the tests locally using the strongest sandboxing available on each platform.
|
||||
common:macos --strategy=TestRunner=darwin-sandbox,local
|
||||
# Note: linux-sandbox is stronger, but not available in GHA.
|
||||
common:linux --strategy=TestRunner=processwrapper-sandbox,local
|
||||
common:windows --strategy=TestRunner=local
|
||||
|
||||
29
BUILD.bazel
Normal file
29
BUILD.bazel
Normal file
@@ -0,0 +1,29 @@
|
||||
# We mark the local platform as glibc-compatible so that rust can grab a toolchain for us.
|
||||
# TODO(zbarsky): Upstream a better libc constraint into rules_rust.
|
||||
# We only enable this on linux though for sanity, and because it breaks remote execution.
|
||||
platform(
|
||||
name = "local",
|
||||
constraint_values = [
|
||||
"@toolchains_llvm_bootstrapped//constraints/libc:gnu.2.28",
|
||||
],
|
||||
parents = [
|
||||
"@platforms//host",
|
||||
],
|
||||
)
|
||||
|
||||
platform(
|
||||
name = "rbe",
|
||||
constraint_values = [
|
||||
"@platforms//cpu:x86_64",
|
||||
"@platforms//os:linux",
|
||||
"@bazel_tools//tools/cpp:clang",
|
||||
"@toolchains_llvm_bootstrapped//constraints/libc:gnu.2.28",
|
||||
],
|
||||
exec_properties = {
|
||||
# Ubuntu-based image that includes git, python3, dotslash, and other
|
||||
# tools that various integration tests need.
|
||||
# Verify at https://hub.docker.com/layers/mbolin491/codex-bazel/latest/images/sha256:8c9ff94187ea7c08a31e9a81f5fe8046ea3972a6768983c955c4079fa30567fb
|
||||
"container-image": "docker://docker.io/mbolin491/codex-bazel@sha256:8c9ff94187ea7c08a31e9a81f5fe8046ea3972a6768983c955c4079fa30567fb",
|
||||
"OSFamily": "Linux",
|
||||
},
|
||||
)
|
||||
122
MODULE.bazel
Normal file
122
MODULE.bazel
Normal file
@@ -0,0 +1,122 @@
|
||||
bazel_dep(name = "platforms", version = "1.0.0")
|
||||
bazel_dep(name = "toolchains_llvm_bootstrapped", version = "0.3.1")
|
||||
archive_override(
|
||||
module_name = "toolchains_llvm_bootstrapped",
|
||||
integrity = "sha256-9ks21bgEqbQWmwUIvqeLA64+Jk6o4ZVjC8KxjVa2Vw8=",
|
||||
strip_prefix = "toolchains_llvm_bootstrapped-e3775e66a7b6d287c705ca0cd24497ef4a77c503",
|
||||
urls = ["https://github.com/cerisier/toolchains_llvm_bootstrapped/archive/e3775e66a7b6d287c705ca0cd24497ef4a77c503/master.tar.gz"],
|
||||
patch_strip = 1,
|
||||
patches = [
|
||||
"//patches:llvm_toolchain_archive_params.patch",
|
||||
],
|
||||
)
|
||||
|
||||
osx = use_extension("@toolchains_llvm_bootstrapped//toolchain/extension:osx.bzl", "osx")
|
||||
osx.framework(name = "ApplicationServices")
|
||||
osx.framework(name = "AppKit")
|
||||
osx.framework(name = "ColorSync")
|
||||
osx.framework(name = "CoreFoundation")
|
||||
osx.framework(name = "CoreGraphics")
|
||||
osx.framework(name = "CoreServices")
|
||||
osx.framework(name = "CoreText")
|
||||
osx.framework(name = "CFNetwork")
|
||||
osx.framework(name = "Foundation")
|
||||
osx.framework(name = "ImageIO")
|
||||
osx.framework(name = "Kernel")
|
||||
osx.framework(name = "OSLog")
|
||||
osx.framework(name = "Security")
|
||||
osx.framework(name = "SystemConfiguration")
|
||||
|
||||
register_toolchains(
|
||||
"@toolchains_llvm_bootstrapped//toolchain:all",
|
||||
)
|
||||
|
||||
bazel_dep(name = "rules_cc", version = "0.2.16")
|
||||
bazel_dep(name = "rules_platform", version = "0.1.0")
|
||||
bazel_dep(name = "rules_rust", version = "0.68.1")
|
||||
single_version_override(
|
||||
module_name = "rules_rust",
|
||||
patch_strip = 1,
|
||||
patches = [
|
||||
"//patches:rules_rust.patch",
|
||||
"//patches:rules_rust_windows_gnu.patch",
|
||||
"//patches:rules_rust_musl.patch",
|
||||
],
|
||||
)
|
||||
|
||||
RUST_TRIPLES = [
|
||||
"aarch64-unknown-linux-musl",
|
||||
"aarch64-apple-darwin",
|
||||
"aarch64-pc-windows-gnullvm",
|
||||
"x86_64-unknown-linux-musl",
|
||||
"x86_64-apple-darwin",
|
||||
"x86_64-pc-windows-gnullvm",
|
||||
]
|
||||
|
||||
rust = use_extension("@rules_rust//rust:extensions.bzl", "rust")
|
||||
rust.toolchain(
|
||||
edition = "2024",
|
||||
extra_target_triples = RUST_TRIPLES,
|
||||
versions = ["1.90.0"],
|
||||
)
|
||||
use_repo(rust, "rust_toolchains")
|
||||
|
||||
register_toolchains("@rust_toolchains//:all")
|
||||
|
||||
bazel_dep(name = "rules_rs", version = "0.0.23")
|
||||
|
||||
crate = use_extension("@rules_rs//rs:extensions.bzl", "crate")
|
||||
crate.from_cargo(
|
||||
cargo_lock = "//codex-rs:Cargo.lock",
|
||||
cargo_toml = "//codex-rs:Cargo.toml",
|
||||
platform_triples = RUST_TRIPLES,
|
||||
)
|
||||
|
||||
bazel_dep(name = "openssl", version = "3.5.4.bcr.0")
|
||||
|
||||
crate.annotation(
|
||||
build_script_data = [
|
||||
"@openssl//:gen_dir",
|
||||
],
|
||||
build_script_env = {
|
||||
"OPENSSL_DIR": "$(execpath @openssl//:gen_dir)",
|
||||
"OPENSSL_NO_VENDOR": "1",
|
||||
"OPENSSL_STATIC": "1",
|
||||
},
|
||||
crate = "openssl-sys",
|
||||
data = ["@openssl//:gen_dir"],
|
||||
)
|
||||
|
||||
inject_repo(crate, "openssl")
|
||||
|
||||
# Fix readme inclusions
|
||||
crate.annotation(
|
||||
crate = "windows-link",
|
||||
patch_args = ["-p1"],
|
||||
patches = [
|
||||
"//patches:windows-link.patch"
|
||||
],
|
||||
)
|
||||
|
||||
WINDOWS_IMPORT_LIB = """
|
||||
load("@rules_cc//cc:defs.bzl", "cc_import")
|
||||
|
||||
cc_import(
|
||||
name = "windows_import_lib",
|
||||
static_library = glob(["lib/*.a"])[0],
|
||||
)
|
||||
"""
|
||||
|
||||
crate.annotation(
|
||||
additive_build_file_content = WINDOWS_IMPORT_LIB,
|
||||
crate = "windows_x86_64_gnullvm",
|
||||
gen_build_script = "off",
|
||||
deps = [":windows_import_lib"],
|
||||
)
|
||||
crate.annotation(
|
||||
additive_build_file_content = WINDOWS_IMPORT_LIB,
|
||||
crate = "windows_aarch64_gnullvm",
|
||||
gen_build_script = "off",
|
||||
deps = [":windows_import_lib"],
|
||||
)
|
||||
use_repo(crate, "crates")
|
||||
1097
MODULE.bazel.lock
generated
Normal file
1097
MODULE.bazel.lock
generated
Normal file
File diff suppressed because one or more lines are too long
1
codex-rs/BUILD.bazel
Normal file
1
codex-rs/BUILD.bazel
Normal file
@@ -0,0 +1 @@
|
||||
|
||||
6
codex-rs/ansi-escape/BUILD.bazel
Normal file
6
codex-rs/ansi-escape/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "ansi-escape",
|
||||
crate_name = "codex_ansi_escape",
|
||||
)
|
||||
6
codex-rs/app-server-protocol/BUILD.bazel
Normal file
6
codex-rs/app-server-protocol/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "app-server-protocol",
|
||||
crate_name = "codex_app_server_protocol",
|
||||
)
|
||||
6
codex-rs/app-server-test-client/BUILD.bazel
Normal file
6
codex-rs/app-server-test-client/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "codex-app-server-test-client",
|
||||
crate_name = "codex_app_server_test_client",
|
||||
)
|
||||
8
codex-rs/app-server/BUILD.bazel
Normal file
8
codex-rs/app-server/BUILD.bazel
Normal file
@@ -0,0 +1,8 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "app-server",
|
||||
crate_name = "codex_app_server",
|
||||
integration_deps_extra = ["//codex-rs/app-server/tests/common:common"],
|
||||
test_tags = ["no-sandbox"],
|
||||
)
|
||||
7
codex-rs/app-server/tests/common/BUILD.bazel
Normal file
7
codex-rs/app-server/tests/common/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "common",
|
||||
crate_name = "app_test_support",
|
||||
crate_srcs = glob(["*.rs"]),
|
||||
)
|
||||
11
codex-rs/apply-patch/BUILD.bazel
Normal file
11
codex-rs/apply-patch/BUILD.bazel
Normal file
@@ -0,0 +1,11 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
exports_files(["apply_patch_tool_instructions.md"])
|
||||
|
||||
codex_rust_crate(
|
||||
name = "apply-patch",
|
||||
crate_name = "codex_apply_patch",
|
||||
compile_data = [
|
||||
"apply_patch_tool_instructions.md",
|
||||
],
|
||||
)
|
||||
6
codex-rs/arg0/BUILD.bazel
Normal file
6
codex-rs/arg0/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "arg0",
|
||||
crate_name = "codex_arg0",
|
||||
)
|
||||
6
codex-rs/async-utils/BUILD.bazel
Normal file
6
codex-rs/async-utils/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "async-utils",
|
||||
crate_name = "codex_async_utils",
|
||||
)
|
||||
7
codex-rs/backend-client/BUILD.bazel
Normal file
7
codex-rs/backend-client/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "backend-client",
|
||||
crate_name = "codex_backend_client",
|
||||
compile_data = glob(["tests/fixtures/**"]),
|
||||
)
|
||||
6
codex-rs/chatgpt/BUILD.bazel
Normal file
6
codex-rs/chatgpt/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "chatgpt",
|
||||
crate_name = "codex_chatgpt",
|
||||
)
|
||||
10
codex-rs/cli/BUILD.bazel
Normal file
10
codex-rs/cli/BUILD.bazel
Normal file
@@ -0,0 +1,10 @@
|
||||
load("//:defs.bzl", "codex_rust_crate", "multiplatform_binaries")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "cli",
|
||||
crate_name = "codex_cli",
|
||||
)
|
||||
|
||||
multiplatform_binaries(
|
||||
name = "codex",
|
||||
)
|
||||
10
codex-rs/cloud-tasks-client/BUILD.bazel
Normal file
10
codex-rs/cloud-tasks-client/BUILD.bazel
Normal file
@@ -0,0 +1,10 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "cloud-tasks-client",
|
||||
crate_name = "codex_cloud_tasks_client",
|
||||
crate_features = [
|
||||
"mock",
|
||||
"online",
|
||||
],
|
||||
)
|
||||
6
codex-rs/cloud-tasks/BUILD.bazel
Normal file
6
codex-rs/cloud-tasks/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "cloud-tasks",
|
||||
crate_name = "codex_cloud_tasks",
|
||||
)
|
||||
6
codex-rs/codex-api/BUILD.bazel
Normal file
6
codex-rs/codex-api/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "codex-api",
|
||||
crate_name = "codex_api",
|
||||
)
|
||||
6
codex-rs/codex-backend-openapi-models/BUILD.bazel
Normal file
6
codex-rs/codex-backend-openapi-models/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "codex-backend-openapi-models",
|
||||
crate_name = "codex_backend_openapi_models",
|
||||
)
|
||||
6
codex-rs/codex-client/BUILD.bazel
Normal file
6
codex-rs/codex-client/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "codex-client",
|
||||
crate_name = "codex_client",
|
||||
)
|
||||
11
codex-rs/common/BUILD.bazel
Normal file
11
codex-rs/common/BUILD.bazel
Normal file
@@ -0,0 +1,11 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "common",
|
||||
crate_name = "codex_common",
|
||||
crate_features = [
|
||||
"cli",
|
||||
"elapsed",
|
||||
"sandbox_summary",
|
||||
],
|
||||
)
|
||||
31
codex-rs/core/BUILD.bazel
Normal file
31
codex-rs/core/BUILD.bazel
Normal file
@@ -0,0 +1,31 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "core",
|
||||
crate_name = "codex_core",
|
||||
# TODO(mbolin): Eliminate the use of features in the version of the
|
||||
# rust_library() that is used by rust_binary() rules for release artifacts
|
||||
# such as the Codex CLI.
|
||||
crate_features = ["deterministic_process_ids", "test-support"],
|
||||
compile_data = glob(
|
||||
include = ["**"],
|
||||
exclude = [
|
||||
"**/* *",
|
||||
"BUILD.bazel",
|
||||
"Cargo.toml",
|
||||
],
|
||||
allow_empty = True,
|
||||
),
|
||||
integration_compile_data_extra = [
|
||||
"//codex-rs/apply-patch:apply_patch_tool_instructions.md",
|
||||
"prompt.md",
|
||||
],
|
||||
integration_deps_extra = ["//codex-rs/core/tests/common:common"],
|
||||
test_tags = ["no-sandbox"],
|
||||
extra_binaries = [
|
||||
"//codex-rs/linux-sandbox:codex-linux-sandbox",
|
||||
"//codex-rs/rmcp-client:test_stdio_server",
|
||||
"//codex-rs/rmcp-client:test_streamable_http_server",
|
||||
"//codex-rs/cli:codex",
|
||||
],
|
||||
)
|
||||
7
codex-rs/core/tests/common/BUILD.bazel
Normal file
7
codex-rs/core/tests/common/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "common",
|
||||
crate_name = "core_test_support",
|
||||
crate_srcs = glob(["*.rs"]),
|
||||
)
|
||||
52
codex-rs/docs/bazel.md
Normal file
52
codex-rs/docs/bazel.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Bazel in codex-rs
|
||||
|
||||
This repository uses Bazel to build the Rust workspace under `codex-rs`.
|
||||
Cargo remains the source of truth for crates and features, while Bazel
|
||||
provides hermetic builds, toolchains, and cross-platform artifacts.
|
||||
|
||||
As of 1/9/2026, this setup is still experimental as we stabilize it.
|
||||
|
||||
## High-level layout
|
||||
|
||||
- `../MODULE.bazel` defines Bazel dependencies and Rust toolchains.
|
||||
- `rules_rs` imports third-party crates from `codex-rs/Cargo.toml` and
|
||||
`codex-rs/Cargo.lock` via `crate.from_cargo(...)` and exposes them under
|
||||
`@crates`.
|
||||
- `../defs.bzl` provides `codex_rust_crate`, which wraps `rust_library`,
|
||||
`rust_binary`, and `rust_test` so Bazel targets line up with Cargo conventions.
|
||||
It provides a sane set of defaults that work for most first-party crates, but may
|
||||
need tweaks in some cases.
|
||||
- Each crate in `codex-rs/*/BUILD.bazel` typically uses `codex_rust_crate` and
|
||||
makes some adjustments if the crate needs additional compile-time or runtime data,
|
||||
or other customizations.
|
||||
|
||||
## Evolving the setup
|
||||
|
||||
When you add or change Rust dependencies, update the Cargo.toml/Cargo.lock as normal.
|
||||
The Bazel build should automatically pick things up without any manual action needed.
|
||||
|
||||
In some cases, an upstream crate may need a patch or a `crate.annotation` in `../MODULE.bzl`
|
||||
to have it build in Bazel's sandbox or make it cross-compilation-friendly. If you see issues,
|
||||
feel free to ping zbarsky or mbolin.
|
||||
|
||||
When you add a new crate or binary:
|
||||
|
||||
1. Add it to the Cargo workspace as usual.
|
||||
2. Create a `BUILD.bazel` that calls `codex_rust_crate` (see nearby crates for
|
||||
examples).
|
||||
3. If a dependency needs special handling (compile/runtime data, additional binaries
|
||||
for integration tests, env vars, etc) you may need to adjust the parameters to
|
||||
`codex_rust_crate` to configure it.
|
||||
One common customization is setting `test_tags = ["no-sandbox]` to run the test
|
||||
unsandboxed. Prefer to avoid it, but it is necessary in some cases such as when the
|
||||
test itself uses Seatbelt (the sandbox does as well, and it cannot be nested).
|
||||
To limit the blast radius, consider isolating such tests to a separate crate.
|
||||
|
||||
If you see build issue and are not sure how to apply the proper customizations, feel free to ping zbarsky or mbolin.
|
||||
|
||||
## References
|
||||
|
||||
- Bazel overview: https://bazel.build/
|
||||
- Bzlmod (module system): https://bazel.build/external/overview
|
||||
- rules_rust: https://github.com/bazelbuild/rules_rust
|
||||
- rules_rs: https://github.com/bazelbuild/rules_rs
|
||||
11
codex-rs/exec-server/BUILD.bazel
Normal file
11
codex-rs/exec-server/BUILD.bazel
Normal file
@@ -0,0 +1,11 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "exec-server",
|
||||
crate_name = "codex_exec_server",
|
||||
integration_deps_extra = ["//codex-rs/exec-server/tests/common:common"],
|
||||
test_tags = ["no-sandbox"],
|
||||
extra_binaries = [
|
||||
"//codex-rs/cli:codex",
|
||||
],
|
||||
)
|
||||
7
codex-rs/exec-server/tests/common/BUILD.bazel
Normal file
7
codex-rs/exec-server/tests/common/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "common",
|
||||
crate_name = "exec_server_test_support",
|
||||
crate_srcs = glob(["*.rs"]),
|
||||
)
|
||||
7
codex-rs/exec/BUILD.bazel
Normal file
7
codex-rs/exec/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "exec",
|
||||
crate_name = "codex_exec",
|
||||
test_tags = ["no-sandbox"],
|
||||
)
|
||||
7
codex-rs/execpolicy-legacy/BUILD.bazel
Normal file
7
codex-rs/execpolicy-legacy/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "execpolicy-legacy",
|
||||
crate_name = "codex_execpolicy_legacy",
|
||||
compile_data = ["src/default.policy"],
|
||||
)
|
||||
6
codex-rs/execpolicy/BUILD.bazel
Normal file
6
codex-rs/execpolicy/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "execpolicy",
|
||||
crate_name = "codex_execpolicy",
|
||||
)
|
||||
6
codex-rs/feedback/BUILD.bazel
Normal file
6
codex-rs/feedback/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "feedback",
|
||||
crate_name = "codex_feedback",
|
||||
)
|
||||
6
codex-rs/file-search/BUILD.bazel
Normal file
6
codex-rs/file-search/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "file-search",
|
||||
crate_name = "codex_file_search",
|
||||
)
|
||||
6
codex-rs/keyring-store/BUILD.bazel
Normal file
6
codex-rs/keyring-store/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "keyring-store",
|
||||
crate_name = "codex_keyring_store",
|
||||
)
|
||||
6
codex-rs/linux-sandbox/BUILD.bazel
Normal file
6
codex-rs/linux-sandbox/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "linux-sandbox",
|
||||
crate_name = "codex_linux_sandbox",
|
||||
)
|
||||
6
codex-rs/lmstudio/BUILD.bazel
Normal file
6
codex-rs/lmstudio/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "lmstudio",
|
||||
crate_name = "codex_lmstudio",
|
||||
)
|
||||
7
codex-rs/login/BUILD.bazel
Normal file
7
codex-rs/login/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "login",
|
||||
crate_name = "codex_login",
|
||||
compile_data = ["src/assets/success.html"],
|
||||
)
|
||||
7
codex-rs/mcp-server/BUILD.bazel
Normal file
7
codex-rs/mcp-server/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "mcp-server",
|
||||
crate_name = "codex_mcp_server",
|
||||
integration_deps_extra = ["//codex-rs/mcp-server/tests/common:common"],
|
||||
)
|
||||
7
codex-rs/mcp-server/tests/common/BUILD.bazel
Normal file
7
codex-rs/mcp-server/tests/common/BUILD.bazel
Normal file
@@ -0,0 +1,7 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "common",
|
||||
crate_name = "mcp_test_support",
|
||||
crate_srcs = glob(["*.rs"]),
|
||||
)
|
||||
6
codex-rs/mcp-types/BUILD.bazel
Normal file
6
codex-rs/mcp-types/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "mcp-types",
|
||||
crate_name = "mcp_types",
|
||||
)
|
||||
6
codex-rs/ollama/BUILD.bazel
Normal file
6
codex-rs/ollama/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "ollama",
|
||||
crate_name = "codex_ollama",
|
||||
)
|
||||
6
codex-rs/otel/BUILD.bazel
Normal file
6
codex-rs/otel/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "otel",
|
||||
crate_name = "codex_otel",
|
||||
)
|
||||
6
codex-rs/process-hardening/BUILD.bazel
Normal file
6
codex-rs/process-hardening/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "process-hardening",
|
||||
crate_name = "codex_process_hardening",
|
||||
)
|
||||
6
codex-rs/protocol/BUILD.bazel
Normal file
6
codex-rs/protocol/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "protocol",
|
||||
crate_name = "codex_protocol",
|
||||
)
|
||||
6
codex-rs/responses-api-proxy/BUILD.bazel
Normal file
6
codex-rs/responses-api-proxy/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "responses-api-proxy",
|
||||
crate_name = "codex_responses_api_proxy",
|
||||
)
|
||||
6
codex-rs/rmcp-client/BUILD.bazel
Normal file
6
codex-rs/rmcp-client/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "rmcp-client",
|
||||
crate_name = "codex_rmcp_client",
|
||||
)
|
||||
6
codex-rs/stdio-to-uds/BUILD.bazel
Normal file
6
codex-rs/stdio-to-uds/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "stdio-to-uds",
|
||||
crate_name = "codex_stdio_to_uds",
|
||||
)
|
||||
17
codex-rs/tui/BUILD.bazel
Normal file
17
codex-rs/tui/BUILD.bazel
Normal file
@@ -0,0 +1,17 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "tui",
|
||||
crate_name = "codex_tui",
|
||||
compile_data = glob(
|
||||
include = ["**"],
|
||||
exclude = [
|
||||
"**/* *",
|
||||
"BUILD.bazel",
|
||||
"Cargo.toml",
|
||||
],
|
||||
allow_empty = True,
|
||||
),
|
||||
test_data_extra = glob(["src/**/snapshots/**"]),
|
||||
integration_compile_data_extra = ["src/test_backend.rs"],
|
||||
)
|
||||
17
codex-rs/tui2/BUILD.bazel
Normal file
17
codex-rs/tui2/BUILD.bazel
Normal file
@@ -0,0 +1,17 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "tui2",
|
||||
crate_name = "codex_tui2",
|
||||
compile_data = glob(
|
||||
include = ["**"],
|
||||
exclude = [
|
||||
"**/* *",
|
||||
"BUILD.bazel",
|
||||
"Cargo.toml",
|
||||
],
|
||||
allow_empty = True,
|
||||
),
|
||||
test_data_extra = glob(["src/**/snapshots/**"]),
|
||||
integration_compile_data_extra = ["src/test_backend.rs"],
|
||||
)
|
||||
6
codex-rs/utils/absolute-path/BUILD.bazel
Normal file
6
codex-rs/utils/absolute-path/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "absolute-path",
|
||||
crate_name = "codex_utils_absolute_path",
|
||||
)
|
||||
6
codex-rs/utils/cache/BUILD.bazel
vendored
Normal file
6
codex-rs/utils/cache/BUILD.bazel
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "cache",
|
||||
crate_name = "codex_utils_cache",
|
||||
)
|
||||
6
codex-rs/utils/cargo-bin/BUILD.bazel
Normal file
6
codex-rs/utils/cargo-bin/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "cargo-bin",
|
||||
crate_name = "codex_utils_cargo_bin",
|
||||
)
|
||||
6
codex-rs/utils/git/BUILD.bazel
Normal file
6
codex-rs/utils/git/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "git",
|
||||
crate_name = "codex_git",
|
||||
)
|
||||
6
codex-rs/utils/image/BUILD.bazel
Normal file
6
codex-rs/utils/image/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "image",
|
||||
crate_name = "codex_utils_image",
|
||||
)
|
||||
6
codex-rs/utils/json-to-toml/BUILD.bazel
Normal file
6
codex-rs/utils/json-to-toml/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "json-to-toml",
|
||||
crate_name = "codex_utils_json_to_toml",
|
||||
)
|
||||
6
codex-rs/utils/pty/BUILD.bazel
Normal file
6
codex-rs/utils/pty/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "pty",
|
||||
crate_name = "codex_utils_pty",
|
||||
)
|
||||
6
codex-rs/utils/readiness/BUILD.bazel
Normal file
6
codex-rs/utils/readiness/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "readiness",
|
||||
crate_name = "codex_utils_readiness",
|
||||
)
|
||||
6
codex-rs/utils/string/BUILD.bazel
Normal file
6
codex-rs/utils/string/BUILD.bazel
Normal file
@@ -0,0 +1,6 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "string",
|
||||
crate_name = "codex_utils_string",
|
||||
)
|
||||
11
codex-rs/windows-sandbox-rs/BUILD.bazel
Normal file
11
codex-rs/windows-sandbox-rs/BUILD.bazel
Normal file
@@ -0,0 +1,11 @@
|
||||
load("//:defs.bzl", "codex_rust_crate")
|
||||
|
||||
codex_rust_crate(
|
||||
name = "windows-sandbox-rs",
|
||||
crate_name = "codex_windows_sandbox",
|
||||
build_script_data = [
|
||||
"Cargo.toml",
|
||||
"codex-windows-sandbox-setup.manifest",
|
||||
],
|
||||
crate_edition = "2021",
|
||||
)
|
||||
177
defs.bzl
Normal file
177
defs.bzl
Normal file
@@ -0,0 +1,177 @@
|
||||
load("@crates//:data.bzl", "DEP_DATA")
|
||||
load("@crates//:defs.bzl", "all_crate_deps")
|
||||
load("@rules_platform//platform_data:defs.bzl", "platform_data")
|
||||
load("@rules_rust//rust:defs.bzl", "rust_binary", "rust_library", "rust_test")
|
||||
load("@rules_rust//cargo/private:cargo_build_script_wrapper.bzl", "cargo_build_script")
|
||||
|
||||
PLATFORMS = [
|
||||
"linux_arm64_musl",
|
||||
"linux_amd64_musl",
|
||||
"macos_amd64",
|
||||
"macos_arm64",
|
||||
"windows_amd64",
|
||||
"windows_arm64",
|
||||
]
|
||||
|
||||
def multiplatform_binaries(name, platforms = PLATFORMS):
|
||||
for platform in platforms:
|
||||
platform_data(
|
||||
name = name + "_" + platform,
|
||||
platform = "@toolchains_llvm_bootstrapped//platforms:" + platform,
|
||||
target = name,
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
native.filegroup(
|
||||
name = "release_binaries",
|
||||
srcs = [name + "_" + platform for platform in platforms],
|
||||
tags = ["manual"],
|
||||
)
|
||||
|
||||
def codex_rust_crate(
|
||||
name,
|
||||
crate_name,
|
||||
crate_features = [],
|
||||
crate_srcs = None,
|
||||
crate_edition = None,
|
||||
build_script_data = [],
|
||||
compile_data = [],
|
||||
deps_extra = [],
|
||||
integration_deps_extra = [],
|
||||
integration_compile_data_extra = [],
|
||||
test_data_extra = [],
|
||||
test_tags = [],
|
||||
extra_binaries = []):
|
||||
"""Defines a Rust crate with library, binaries, and tests wired for Bazel + Cargo parity.
|
||||
|
||||
The macro mirrors Cargo conventions: it builds a library when `src/` exists,
|
||||
wires build scripts, exports `CARGO_BIN_EXE_*` for integration tests, and
|
||||
creates unit + integration test targets. Dependency buckets map to the
|
||||
Cargo.lock resolution in `@crates`.
|
||||
|
||||
Args:
|
||||
name: Bazel target name for the library, should be the directory name.
|
||||
Example: `app-server`.
|
||||
crate_name: Cargo crate name from Cargo.toml
|
||||
Example: `codex_app_server`.
|
||||
crate_features: Cargo features to enable for this crate.
|
||||
Crates are only compiled in a single configuration across the workspace, i.e.
|
||||
with all features in this list enabled. So use sparingly, and prefer to refactor
|
||||
optional functionality to a separate crate.
|
||||
crate_srcs: Optional explicit srcs; defaults to `src/**/*.rs`.
|
||||
crate_edition: Rust edition override, if not default.
|
||||
You probably don't want this, it's only here for a single caller.
|
||||
build_script_data: Data files exposed to the build script at runtime.
|
||||
compile_data: Non-Rust compile-time data for the library target.
|
||||
deps_extra: Extra normal deps beyond @crates resolution.
|
||||
Typically only needed when features add additional deps.
|
||||
integration_deps_extra: Extra deps for integration tests only.
|
||||
integration_compile_data_extra: Extra compile_data for integration tests.
|
||||
test_data_extra: Extra runtime data for tests.
|
||||
test_tags: Tags applied to unit + integration test targets.
|
||||
Typically used to disable the sandbox, but see https://bazel.build/reference/be/common-definitions#common.tags
|
||||
extra_binaries: Additional binary labels to surface as test data and
|
||||
`CARGO_BIN_EXE_*` environment variables. These are only needed for binaries from a different crate.
|
||||
"""
|
||||
deps = all_crate_deps(normal = True) + deps_extra
|
||||
dev_deps = all_crate_deps(normal_dev = True)
|
||||
proc_macro_deps = all_crate_deps(proc_macro = True)
|
||||
proc_macro_dev_deps = all_crate_deps(proc_macro_dev = True)
|
||||
|
||||
test_env = {
|
||||
"INSTA_WORKSPACE_ROOT": ".",
|
||||
"INSTA_SNAPSHOT_PATH": "src",
|
||||
}
|
||||
|
||||
rustc_env = {
|
||||
"BAZEL_PACKAGE": native.package_name(),
|
||||
}
|
||||
|
||||
binaries = DEP_DATA.get(native.package_name())["binaries"]
|
||||
|
||||
# TODO(zbarsky): cargo_build_script support?
|
||||
|
||||
lib_srcs = crate_srcs or native.glob(["src/**/*.rs"], exclude = binaries.values(), allow_empty = True)
|
||||
|
||||
if native.glob(["build.rs"], allow_empty = True):
|
||||
cargo_build_script(
|
||||
name = name + "-build-script",
|
||||
srcs = ["build.rs"],
|
||||
deps = all_crate_deps(build = True),
|
||||
proc_macro_deps = all_crate_deps(build_proc_macro = True),
|
||||
data = build_script_data,
|
||||
# Some build script deps sniff version-related env vars...
|
||||
version = "0.0.0",
|
||||
)
|
||||
|
||||
deps = deps + [name + "-build-script"]
|
||||
|
||||
if lib_srcs:
|
||||
rust_library(
|
||||
name = name,
|
||||
crate_name = crate_name,
|
||||
crate_features = crate_features,
|
||||
deps = deps,
|
||||
proc_macro_deps = proc_macro_deps,
|
||||
compile_data = compile_data,
|
||||
srcs = lib_srcs,
|
||||
edition = crate_edition,
|
||||
rustc_env = rustc_env,
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
rust_test(
|
||||
name = name + "-unit-tests",
|
||||
crate = name,
|
||||
env = test_env,
|
||||
deps = deps + dev_deps,
|
||||
proc_macro_deps = proc_macro_deps + proc_macro_dev_deps,
|
||||
rustc_env = rustc_env,
|
||||
data = test_data_extra,
|
||||
tags = test_tags,
|
||||
)
|
||||
|
||||
maybe_lib = [name]
|
||||
else:
|
||||
maybe_lib = []
|
||||
|
||||
sanitized_binaries = []
|
||||
cargo_env = {}
|
||||
for binary, main in binaries.items():
|
||||
#binary = binary.replace("-", "_")
|
||||
sanitized_binaries.append(binary)
|
||||
cargo_env["CARGO_BIN_EXE_" + binary] = "$(rootpath :%s)" % binary
|
||||
|
||||
rust_binary(
|
||||
name = binary,
|
||||
crate_name = binary.replace("-", "_"),
|
||||
crate_root = main,
|
||||
deps = maybe_lib + deps,
|
||||
proc_macro_deps = proc_macro_deps,
|
||||
edition = crate_edition,
|
||||
srcs = native.glob(["src/**/*.rs"]),
|
||||
visibility = ["//visibility:public"],
|
||||
)
|
||||
|
||||
for binary_label in extra_binaries:
|
||||
sanitized_binaries.append(binary_label)
|
||||
binary = Label(binary_label).name
|
||||
cargo_env["CARGO_BIN_EXE_" + binary] = "$(rootpath %s)" % binary_label
|
||||
|
||||
for test in native.glob(["tests/*.rs"], allow_empty = True):
|
||||
test_name = name + "-" + test.removeprefix("tests/").removesuffix(".rs").replace("/", "-")
|
||||
if not test_name.endswith("-test"):
|
||||
test_name += "-test"
|
||||
|
||||
rust_test(
|
||||
name = test_name,
|
||||
crate_root = test,
|
||||
srcs = [test],
|
||||
data = native.glob(["tests/**"], allow_empty = True) + sanitized_binaries + test_data_extra,
|
||||
compile_data = native.glob(["tests/**"], allow_empty = True) + integration_compile_data_extra,
|
||||
deps = maybe_lib + deps + dev_deps + integration_deps_extra,
|
||||
proc_macro_deps = proc_macro_deps + proc_macro_dev_deps,
|
||||
rustc_env = rustc_env,
|
||||
env = test_env | cargo_env,
|
||||
tags = test_tags,
|
||||
)
|
||||
9
justfile
9
justfile
@@ -44,6 +44,15 @@ install:
|
||||
test:
|
||||
cargo nextest run --no-fail-fast
|
||||
|
||||
bazel-test:
|
||||
bazel test //... --keep_going
|
||||
|
||||
bazel-remote-test:
|
||||
bazel test //... --config=remote --platforms=//:rbe --keep_going
|
||||
|
||||
build-for-release:
|
||||
bazel build //codex-rs/cli:release_binaries --config=remote
|
||||
|
||||
# Run the MCP server
|
||||
mcp-server-run *args:
|
||||
cargo run -p codex-mcp-server -- "$@"
|
||||
|
||||
0
patches/BUILD.bazel
Normal file
0
patches/BUILD.bazel
Normal file
52
patches/llvm_toolchain_archive_params.patch
Normal file
52
patches/llvm_toolchain_archive_params.patch
Normal file
@@ -0,0 +1,52 @@
|
||||
diff --git a/toolchain/cc_toolchain.bzl b/toolchain/cc_toolchain.bzl
|
||||
index 58da8ec..bf1fbdd 100644
|
||||
--- a/toolchain/cc_toolchain.bzl
|
||||
+++ b/toolchain/cc_toolchain.bzl
|
||||
@@ -26,6 +26,7 @@ def cc_toolchain(name, tool_map):
|
||||
cc_feature_set(
|
||||
name = name + "_runtimes_only_known_features",
|
||||
all_of = [
|
||||
+ "//toolchain/features:archive_param_file",
|
||||
# Always last (contains user_compile_flags and user_link_flags who should apply last).
|
||||
"@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features",
|
||||
],
|
||||
@@ -45,6 +46,7 @@ def cc_toolchain(name, tool_map):
|
||||
],
|
||||
"@platforms//os:none": [],
|
||||
}) + [
|
||||
+ "//toolchain/features:archive_param_file",
|
||||
"//toolchain/features/legacy:all_legacy_builtin_features",
|
||||
# Always last (contains user_compile_flags and user_link_flags who should apply last).
|
||||
"@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features",
|
||||
@@ -54,6 +56,7 @@ def cc_toolchain(name, tool_map):
|
||||
cc_feature_set(
|
||||
name = name + "_runtimes_only_enabled_features",
|
||||
all_of = [
|
||||
+ "//toolchain/features:archive_param_file",
|
||||
# Always last (contains user_compile_flags and user_link_flags who should apply last).
|
||||
"@rules_cc//cc/toolchains/args:experimental_replace_legacy_action_config_features",
|
||||
],
|
||||
diff --git a/toolchain/features/BUILD.bazel b/toolchain/features/BUILD.bazel
|
||||
index e787484..bccd45b 100644
|
||||
--- a/toolchain/features/BUILD.bazel
|
||||
+++ b/toolchain/features/BUILD.bazel
|
||||
@@ -17,6 +17,11 @@ cc_feature(
|
||||
overrides = "@rules_cc//cc/toolchains/features:static_link_cpp_runtimes",
|
||||
)
|
||||
|
||||
+cc_feature(
|
||||
+ name = "archive_param_file",
|
||||
+ feature_name = "archive_param_file",
|
||||
+)
|
||||
+
|
||||
cc_args(
|
||||
name = "opt_link_flags",
|
||||
actions = [
|
||||
@@ -124,6 +129,7 @@ cc_feature(
|
||||
cc_feature_set(
|
||||
name = "all_non_legacy_builtin_features",
|
||||
all_of = [
|
||||
+ ":archive_param_file",
|
||||
":opt",
|
||||
":opt_stub",
|
||||
":dbg",
|
||||
34
patches/rules_rust.patch
Normal file
34
patches/rules_rust.patch
Normal file
@@ -0,0 +1,34 @@
|
||||
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
|
||||
index a28ad50b7..af627fe50 100644
|
||||
--- a/rust/private/rustc.bzl
|
||||
+++ b/rust/private/rustc.bzl
|
||||
@@ -2361,19 +2361,19 @@ def _get_make_link_flag_funcs(target_os, target_abi, use_direct_link_driver):
|
||||
- callable: The function for producing link args.
|
||||
- callable: The function for formatting link library names.
|
||||
"""
|
||||
+
|
||||
+ get_lib_name = get_lib_name_default
|
||||
+
|
||||
if target_os == "windows":
|
||||
- make_link_flags_windows_msvc = _make_link_flags_windows_msvc_direct if use_direct_link_driver else _make_link_flags_windows_msvc_indirect
|
||||
- make_link_flags_windows_gnu = _make_link_flags_windows_gnu_direct if use_direct_link_driver else _make_link_flags_windows_gnu_indirect
|
||||
- make_link_flags = make_link_flags_windows_msvc if target_abi == "msvc" else make_link_flags_windows_gnu
|
||||
- get_lib_name = get_lib_name_for_windows
|
||||
+ if target_abi == "msvc":
|
||||
+ make_link_flags = _make_link_flags_windows_msvc_direct if use_direct_link_driver else _make_link_flags_windows_msvc_indirect
|
||||
+ get_lib_name = get_lib_name_for_windows
|
||||
+ else:
|
||||
+ make_link_flags = _make_link_flags_windows_gnu_direct if use_direct_link_driver else _make_link_flags_windows_gnu_indirect
|
||||
elif target_os.startswith(("mac", "darwin", "ios")):
|
||||
- make_link_flags_darwin = _make_link_flags_darwin_direct if use_direct_link_driver else _make_link_flags_darwin_indirect
|
||||
- make_link_flags = make_link_flags_darwin
|
||||
- get_lib_name = get_lib_name_default
|
||||
+ make_link_flags = _make_link_flags_darwin_direct if use_direct_link_driver else _make_link_flags_darwin_indirect
|
||||
else:
|
||||
- make_link_flags_default = _make_link_flags_default_direct if use_direct_link_driver else _make_link_flags_default_indirect
|
||||
- make_link_flags = make_link_flags_default
|
||||
- get_lib_name = get_lib_name_default
|
||||
+ make_link_flags = _make_link_flags_default_direct if use_direct_link_driver else _make_link_flags_default_indirect
|
||||
|
||||
return (make_link_flags, get_lib_name)
|
||||
|
||||
27
patches/rules_rust_musl.patch
Normal file
27
patches/rules_rust_musl.patch
Normal file
@@ -0,0 +1,27 @@
|
||||
diff -uNr rust/platform/triple_mappings.bzl rust/platform/triple_mappings.bzl
|
||||
--- a/rust/platform/triple_mappings.bzl
|
||||
+++ b/rust/platform/triple_mappings.bzl
|
||||
@@ -1,6 +1,7 @@
|
||||
"""Helpers for constructing supported Rust platform triples"""
|
||||
|
||||
load("//rust/platform:triple.bzl", "triple")
|
||||
+load("@@toolchains_llvm_bootstrapped+//constraints/libc:libc_versions.bzl", "DEFAULT_LIBC")
|
||||
|
||||
def _support(*, std = False, host_tools = False):
|
||||
"""Identify the type of support an associated platform triple has.
|
||||
@@ -334,10 +335,11 @@
|
||||
|
||||
all_abi_constraints = []
|
||||
|
||||
- # add constraints for MUSL static compilation and linking
|
||||
- # to separate the MUSL from the non-MUSL toolchain on x86_64
|
||||
- # if abi == "musl" and system == "linux" and arch == "x86_64":
|
||||
- # all_abi_constraints.append("//rust/platform/constraints:musl_on")
|
||||
+ if system == "linux":
|
||||
+ if abi == "musl":
|
||||
+ all_abi_constraints.append("@@toolchains_llvm_bootstrapped+//constraints/libc:musl")
|
||||
+ elif abi.startswith("gnu"):
|
||||
+ all_abi_constraints.append("@@toolchains_llvm_bootstrapped+//constraints/libc:{}".format(DEFAULT_LIBC))
|
||||
|
||||
# add constraints for iOS + watchOS simulator and device triples
|
||||
if system in ["ios", "watchos"]:
|
||||
58
patches/rules_rust_windows_gnu.patch
Normal file
58
patches/rules_rust_windows_gnu.patch
Normal file
@@ -0,0 +1,58 @@
|
||||
diff --git a/rust/private/rustc.bzl b/rust/private/rustc.bzl
|
||||
index af627fe50..d1c5142cb 100644
|
||||
--- a/rust/private/rustc.bzl
|
||||
+++ b/rust/private/rustc.bzl
|
||||
@@ -560,9 +560,12 @@ def _symlink_for_ambiguous_lib(actions, toolchain, crate_info, lib):
|
||||
|
||||
# Take the absolute value of hash() since it could be negative.
|
||||
path_hash = abs(hash(lib.path))
|
||||
- lib_name = get_lib_name_for_windows(lib) if toolchain.target_os.startswith("windows") else get_lib_name_default(lib)
|
||||
-
|
||||
- if toolchain.target_os.startswith("windows"):
|
||||
+ if toolchain.target_os.startswith("windows") and toolchain.target_abi == "msvc":
|
||||
+ lib_name = get_lib_name_for_windows(lib)
|
||||
+ else:
|
||||
+ lib_name = get_lib_name_default(lib)
|
||||
+
|
||||
+ if toolchain.target_os.startswith("windows") and toolchain.target_abi == "msvc":
|
||||
prefix = ""
|
||||
extension = ".lib"
|
||||
elif lib_name.endswith(".pic"):
|
||||
@@ -1495,7 +1498,7 @@ def rustc_compile_action(
|
||||
pdb_file = None
|
||||
dsym_folder = None
|
||||
if crate_info.type in ("cdylib", "bin") and not experimental_use_cc_common_link:
|
||||
- if toolchain.target_os == "windows" and compilation_mode.strip_level == "none":
|
||||
+ if toolchain.target_os == "windows" and toolchain.target_abi == "msvc" and compilation_mode.strip_level == "none":
|
||||
pdb_file = ctx.actions.declare_file(crate_info.output.basename[:-len(crate_info.output.extension)] + "pdb", sibling = crate_info.output)
|
||||
action_outputs.append(pdb_file)
|
||||
elif toolchain.target_os in ["macos", "darwin"]:
|
||||
@@ -1626,7 +1629,7 @@ def rustc_compile_action(
|
||||
|
||||
additional_linker_outputs = []
|
||||
- if crate_info.type in ("cdylib", "bin") and cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "generate_pdb_file"):
|
||||
+ if crate_info.type in ("cdylib", "bin") and toolchain.target_abi == "msvc" and cc_common.is_enabled(feature_configuration = feature_configuration, feature_name = "generate_pdb_file"):
|
||||
pdb_file = ctx.actions.declare_file(crate_info.output.basename[:-len(crate_info.output.extension)] + "pdb", sibling = crate_info.output)
|
||||
additional_linker_outputs.append(pdb_file)
|
||||
|
||||
@@ -2248,8 +2251,8 @@ def _portable_link_flags(lib, use_pic, ambiguous_libs, get_lib_name, for_windows
|
||||
]
|
||||
else:
|
||||
return [
|
||||
- "-lstatic=%s" % get_lib_name(artifact),
|
||||
- "-Clink-arg=-l{}".format(artifact.basename),
|
||||
+ "-lstatic=%s" % get_lib_name(artifact),
|
||||
+ "-Clink-arg=-l{}".format(get_lib_name(artifact)),
|
||||
]
|
||||
else:
|
||||
return [
|
||||
@@ -2281,7 +2284,8 @@ def _make_link_flags_windows(make_link_flags_args, flavor_msvc, use_direct_drive
|
||||
("-Clink-arg=%s--no-whole-archive" % prefix),
|
||||
])
|
||||
elif include_link_flags:
|
||||
- ret.extend(_portable_link_flags(lib, use_pic, ambiguous_libs, get_lib_name_for_windows, for_windows = True, flavor_msvc = flavor_msvc))
|
||||
+ get_name_fn = get_lib_name_for_windows if flavor_msvc else get_lib_name_default
|
||||
+ ret.extend(_portable_link_flags(lib, use_pic, ambiguous_libs, get_name_fn, for_windows = True, flavor_msvc = flavor_msvc))
|
||||
_add_user_link_flags(ret, linker_input)
|
||||
return ret
|
||||
|
||||
10
patches/windows-link.patch
Normal file
10
patches/windows-link.patch
Normal file
@@ -0,0 +1,10 @@
|
||||
diff --git a/src/lib.rs b/src/lib.rs
|
||||
index 2d5a2a2..6e8c4cd 100644
|
||||
--- a/src/lib.rs
|
||||
+++ b/src/lib.rs
|
||||
@@ -1,4 +1,4 @@
|
||||
-#![doc = include_str!("../readme.md")]
|
||||
+#![doc = "windows-link"]
|
||||
#![no_std]
|
||||
|
||||
/// Defines an external function to import.
|
||||
Reference in New Issue
Block a user