Skip to content

chore: parameterize BUILD_ARCH/BUILD_PLATFORM in Makefiles#2257

Merged
jakubno merged 3 commits intomainfrom
chore/makefile-build-arch
Mar 30, 2026
Merged

chore: parameterize BUILD_ARCH/BUILD_PLATFORM in Makefiles#2257
jakubno merged 3 commits intomainfrom
chore/makefile-build-arch

Conversation

@tomassrnka
Copy link
Copy Markdown
Member

Summary

  • Add BUILD_ARCH and BUILD_PLATFORM variables to all service Makefiles (api, client-proxy, envd, orchestrator)
  • Replace hardcoded amd64 / linux/amd64 references with the new variables
  • Default to host architecture via go env GOARCH, preserving existing behavior on amd64 hosts
  • Enables cross-compilation (e.g., BUILD_ARCH=arm64 make build) and multi-arch Docker builds (e.g., BUILD_PLATFORM=linux/amd64,linux/arm64 make build)

Part of #1875 (ARM64 support), split out as a standalone change since the Makefile parameterization is safe and backwards-compatible.

Test plan

  • Verify make build in each package still defaults to amd64 on an amd64 host
  • Verify BUILD_ARCH=arm64 make build-local cross-compiles correctly in packages/orchestrator
  • Verify BUILD_PLATFORM=linux/arm64 make build produces arm64 Docker images
  • Confirm no regressions in CI (existing amd64 workflows unaffected)

🤖 Generated with Claude Code

Replace hardcoded amd64/linux/amd64 with BUILD_ARCH and BUILD_PLATFORM
variables across all service Makefiles. Defaults to host architecture
via `go env GOARCH`, preserving existing behavior.

Enables cross-compilation by setting BUILD_ARCH=arm64 or multi-arch
Docker builds via BUILD_PLATFORM=linux/amd64,linux/arm64.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@cursor
Copy link
Copy Markdown

cursor bot commented Mar 29, 2026

PR Summary

Low Risk
Low risk build-tooling change, but it can break builds if callers relied on hardcoded linux/amd64 defaults or if BUILD_PLATFORM is set to a value unsupported by the local Docker/buildx setup.

Overview
Updates service Makefile build and Docker commands to use new BUILD_ARCH/BUILD_PLATFORM variables (defaulting to go env GOARCH) instead of hardcoded amd64/linux/amd64, enabling cross-compilation and multi-arch Docker builds while keeping existing behavior on amd64 hosts.

Written by Cursor Bugbot for commit 7318e8f. This will update automatically on new commits. Configure here.

BUILD_ARCH ?= $(shell go env GOARCH)
# Docker platform string. Override for multi-arch builds:
# BUILD_PLATFORM=linux/amd64,linux/arm64 make build-and-upload
BUILD_PLATFORM ?= linux/$(BUILD_ARCH)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BUILD_PLATFORM is defined here but never actually used. The build-and-upload target calls docker buildx bake without passing this variable, and api/docker-bake.hcl still hardcodes platforms = ["linux/amd64"] for both api and db-migrator targets. Running BUILD_PLATFORM=linux/arm64 make build-and-upload from this package will silently produce an amd64 image.

To wire it up, either pass --set "*.platforms=$(BUILD_PLATFORM)" to docker buildx bake, or add a BUILD_PLATFORM variable to docker-bake.hcl and pass it as an environment variable.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — removed BUILD_ARCH/BUILD_PLATFORM from api Makefile entirely.

Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Autofix Details

Bugbot Autofix prepared fixes for all 3 issues found in the latest run.

  • ✅ Fixed: Unused BUILD_ARCH/BUILD_PLATFORM variables in api Makefile
    • Removed the unused BUILD_ARCH and BUILD_PLATFORM variables since they were never referenced by any target in the api Makefile.
  • ✅ Fixed: docker run breaks with multi-platform BUILD_PLATFORM value
    • Updated the comment to document single-platform usage only, since docker build and docker run don't support comma-separated multi-platform values.
  • ✅ Fixed: Non-buildx docker build breaks with multi-platform value
    • Updated the comment to document single-platform usage only, since non-buildx docker build doesn't support comma-separated multi-platform values.

Create PR

Or push these changes by commenting:

@cursor push df1c556b27
Preview (df1c556b27)
diff --git a/packages/api/Makefile b/packages/api/Makefile
--- a/packages/api/Makefile
+++ b/packages/api/Makefile
@@ -6,12 +6,6 @@
 HOSTNAME := $(shell hostname 2> /dev/null || hostnamectl hostname 2> /dev/null)
 $(if $(HOSTNAME),,$(error Failed to determine hostname: both 'hostname' and 'hostnamectl' failed))
 
-# Architecture for builds. Defaults to local arch; override for cross-compilation
-# (e.g., BUILD_ARCH=amd64 make build-and-upload from an ARM64 host).
-BUILD_ARCH ?= $(shell go env GOARCH)
-# Docker platform string. Override for multi-arch builds:
-#   BUILD_PLATFORM=linux/amd64,linux/arm64 make build-and-upload
-BUILD_PLATFORM ?= linux/$(BUILD_ARCH)
 
 expectedMigration := $(shell ./../../scripts/get-latest-migration.sh)
 

diff --git a/packages/envd/Makefile b/packages/envd/Makefile
--- a/packages/envd/Makefile
+++ b/packages/envd/Makefile
@@ -10,8 +10,8 @@
 # Architecture for builds. Defaults to local arch; override for cross-compilation
 # (e.g., BUILD_ARCH=amd64 make build from an ARM64 host).
 BUILD_ARCH ?= $(shell go env GOARCH)
-# Docker platform string. Override for multi-arch builds:
-#   BUILD_PLATFORM=linux/amd64,linux/arm64 make start-docker
+# Docker platform string (single platform only for docker build/run).
+# Example: BUILD_PLATFORM=linux/amd64 make start-docker
 BUILD_PLATFORM ?= linux/$(BUILD_ARCH)
 
 .PHONY: init

diff --git a/packages/orchestrator/Makefile b/packages/orchestrator/Makefile
--- a/packages/orchestrator/Makefile
+++ b/packages/orchestrator/Makefile
@@ -10,8 +10,8 @@
 # Architecture for builds. Defaults to local arch; override for cross-compilation
 # (e.g., BUILD_ARCH=amd64 make build from an ARM64 host).
 BUILD_ARCH ?= $(shell go env GOARCH)
-# Docker platform string. Override for multi-arch builds:
-#   BUILD_PLATFORM=linux/amd64,linux/arm64 make build
+# Docker platform string (single platform only for docker build).
+# Example: BUILD_PLATFORM=linux/amd64 make build
 BUILD_PLATFORM ?= linux/$(BUILD_ARCH)
 
 .PHONY: init

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ff8ed13fa0

ℹ️ About Codex in GitHub

Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

docker run \
--name envd \
--platform linux/amd64 \
--platform $(BUILD_PLATFORM) \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Keep BUILD_PLATFORM single-valued for start-docker

start-docker now passes $(BUILD_PLATFORM) to docker run --platform, but this Makefile also documents BUILD_PLATFORM=linux/amd64,linux/arm64 as a supported override. docker run --platform expects one platform value, so a comma-separated list will make start-docker fail before envd starts. This regression is specific to users following the new multi-arch override pattern.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — comment updated to single-arch example.

BUILD_ARCH ?= $(shell go env GOARCH)
# Docker platform string. Override for multi-arch builds:
# BUILD_PLATFORM=linux/amd64,linux/arm64 make build-and-upload
BUILD_PLATFORM ?= linux/$(BUILD_ARCH)
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Wire API BUILD_PLATFORM into build-and-upload flow

The new BUILD_PLATFORM knob in the API Makefile is not consumed by build-and-upload: that target still calls docker buildx bake with api/docker-bake.hcl, and the bake file remains pinned to platforms = ["linux/amd64"] for both targets. As a result, setting BUILD_PLATFORM (as the new comment suggests) has no effect, so API builds are still fixed to amd64.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — removed from api Makefile.

Comment on lines +9 to +15
# Architecture for builds. Defaults to local arch; override for cross-compilation
# (e.g., BUILD_ARCH=amd64 make build-and-upload from an ARM64 host).
BUILD_ARCH ?= $(shell go env GOARCH)
# Docker platform string. Override for multi-arch builds:
# BUILD_PLATFORM=linux/amd64,linux/arm64 make build-and-upload
BUILD_PLATFORM ?= linux/$(BUILD_ARCH)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 In packages/api/Makefile, BUILD_ARCH and BUILD_PLATFORM are declared but never referenced in any build target, so cross-compilation via BUILD_ARCH=arm64 or BUILD_PLATFORM=linux/arm64 silently has no effect. The fix requires adding GOARCH=$(BUILD_ARCH) to the build/build-debug targets and either passing BUILD_PLATFORM through to the docker buildx bake invocation or updating api/docker-bake.hcl to accept it as a variable.

Extended reasoning...

Bug: BUILD_ARCH and BUILD_PLATFORM are declared but unused in packages/api/Makefile

The PR's stated goal is to parameterize BUILD_ARCH/BUILD_PLATFORM across all four service Makefiles so that cross-compilation and multi-arch Docker builds can be triggered uniformly. Three of the four packages (client-proxy, envd, orchestrator) correctly wire the new variables into their build commands. The api package declares the variables but fails to use them anywhere.

Specific code paths that are broken:

  1. build and build-debug targets (packages/api/Makefile lines 30–38): Both targets invoke go build as CGO_ENABLED=0 go build ... and CGO_ENABLED=1 go build ... respectively — without any GOARCH env var. Every other package in this PR sets GOARCH=$(BUILD_ARCH) explicitly (e.g., client-proxy line 26: CGO_ENABLED=0 GOOS=linux GOARCH=$(BUILD_ARCH) go build ...). The api package omits this, so running BUILD_ARCH=arm64 make build in packages/api compiles for the host architecture, not arm64.

  2. build-and-upload target (packages/api/Makefile lines ~75–80): This target calls docker buildx bake -f api/docker-bake.hcl --push and passes only REGISTRY_PREFIX, COMMIT_SHA, and EXPECTED_MIGRATION_TIMESTAMP as env vars. It does not pass BUILD_PLATFORM (or any platform-related variable) to the bake command. Furthermore, api/docker-bake.hcl hardcodes platforms = ["linux/amd64"] in both the api and db-migrator targets and defines no BUILD_PLATFORM variable at all. As a result, BUILD_PLATFORM=linux/arm64 make build-and-upload silently produces an amd64 image.

Why existing code doesn't prevent it:

Make variable declarations with ?= only set defaults; they don't enforce usage. There is no mechanism in GNU Make that would warn or error when a declared variable is never referenced in a recipe. The variables evaluate correctly (defaulting to the host arch via go env GOARCH), but because neither the go build commands nor the bake invocation reference them, they are effectively dead declarations.

Impact:

Any developer or CI job attempting to cross-compile the api package (e.g., for ARM64 support as described in the linked issue #1875) will get a silently incorrect binary or image. There is no error message — the build succeeds but targets the wrong architecture. This directly contradicts the PR's test plan item: "Verify BUILD_PLATFORM=linux/arm64 make build produces arm64 Docker images" — it will not for the api package.

Step-by-step proof:

  1. Developer runs BUILD_ARCH=arm64 make build in packages/api
  2. Make evaluates BUILD_ARCH ?= $(shell go env GOARCH) — but since BUILD_ARCH=arm64 is set in the environment, BUILD_ARCH is arm64. ✓
  3. Make executes the build target: CGO_ENABLED=0 go build -o bin/api ... — no GOARCH is set, so Go uses the host architecture (e.g., amd64).
  4. The resulting bin/api binary is amd64, not arm64. The BUILD_ARCH=arm64 override was ignored.
  5. Similarly, BUILD_PLATFORM=linux/arm64 make build-and-upload calls docker buildx bake -f api/docker-bake.hcl which reads its own platforms = ["linux/amd64"] from the HCL file and ignores the Makefile variable entirely.

How to fix:

  • Add GOARCH=$(BUILD_ARCH) to the build target: CGO_ENABLED=0 GOOS=linux GOARCH=$(BUILD_ARCH) go build ...
  • Either: add a variable "BUILD_PLATFORM" block to api/docker-bake.hcl and pass it via an env var in the bake invocation, or switch build-and-upload from docker buildx bake to docker buildx build --platform $(BUILD_PLATFORM) (as client-proxy does).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — BUILD_ARCH/BUILD_PLATFORM removed from api Makefile entirely.

Comment on lines 35 to 43
start-docker:
make build
DOCKER_BUILDKIT=1 docker build --platform linux/amd64 -t envd-debug . -f debug.Dockerfile
DOCKER_BUILDKIT=1 docker build --platform $(BUILD_PLATFORM) -t envd-debug . -f debug.Dockerfile
docker run \
--name envd \
--platform linux/amd64 \
--platform $(BUILD_PLATFORM) \
-p 49983:49983 \
-p 2345:2345 \
-p 9999:9999 \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔴 The comment for BUILD_PLATFORM in packages/envd/Makefile explicitly documents BUILD_PLATFORM=linux/amd64,linux/arm64 make start-docker as a valid example, but the start-docker target passes $(BUILD_PLATFORM) to docker run --platform, which only accepts a single platform string and will fail with a comma-separated value. The comment should either reference a build-only target or the start-docker target should use a separate single-platform variable for the docker run step.

Extended reasoning...

What the bug is and how it manifests

The BUILD_PLATFORM variable comment in packages/envd/Makefile explicitly documents BUILD_PLATFORM=linux/amd64,linux/arm64 make start-docker as a usage example (lines 12-13). The start-docker target then passes this variable to both docker build --platform $(BUILD_PLATFORM) and docker run --platform $(BUILD_PLATFORM). While docker build (via BuildKit) can accept a comma-separated multi-arch platform list, docker run --platform strictly requires a single platform string.

The specific code path that triggers it

When a user runs BUILD_PLATFORM=linux/amd64,linux/arm64 make start-docker, execution proceeds as follows:

  1. make build — succeeds (plain Go cross-compilation, unaffected by BUILD_PLATFORM)
  2. DOCKER_BUILDKIT=1 docker build --platform linux/amd64,linux/arm64 ... — succeeds, creates a multi-arch manifest
  3. docker run --platform linux/amd64,linux/arm64 ...fails with an error such as invalid platform linux/amd64,linux/arm64

Why existing code doesn't prevent it

Make has no mechanism to validate that a variable is appropriate for a specific Docker subcommand. The same $(BUILD_PLATFORM) token is interpolated into both the build and run invocations without any guard or split.

What the impact would be

Any developer following the documented example for start-docker will encounter a hard failure at the docker run step. Even if they work around the comma-separated format by passing a single arch (the default behavior), building a multi-arch manifest and then attempting to run it locally is not a meaningful workflow—multi-arch manifests need to be pushed to a registry first. The comment actively misleads users toward a broken invocation.

How to fix it

Two options:

  1. Change the comment to reference only make build (or a push/upload target) instead of make start-docker, since multi-arch builds are only useful when pushing to a registry.
  2. Split the variable in start-docker: use BUILD_PLATFORM for the docker build step and derive a single-arch run platform from BUILD_ARCH (e.g., --platform linux/$(BUILD_ARCH)) for docker run.

Step-by-step proof

  1. User reads the comment: # BUILD_PLATFORM=linux/amd64,linux/arm64 make start-docker
  2. User runs: BUILD_PLATFORM=linux/amd64,linux/arm64 make start-docker
  3. Make expands start-docker → runs docker run --platform linux/amd64,linux/arm64 ...
  4. Docker rejects the value: docker: invalid platform linux/amd64,linux/arm64: unknown os or arch or variant
  5. The container never starts; the command fails.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — comment now shows single-arch example only.

Comment on lines 112 to 118
@cp -r ../shared .shared/
@rm -rf .clickhouse/
@cp -r ../clickhouse .clickhouse/
@docker build --platform linux/amd64 -f test.Dockerfile --no-cache-filter runner --progress=plain -t orchestrator-test .
@docker build --platform $(BUILD_PLATFORM) -f test.Dockerfile --no-cache-filter runner --progress=plain -t orchestrator-test .
@rm -rf .shared/
@rm -rf .clickhouse/
@echo "Done"
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 The test-docker target still echoes Running orchestrator tests in Docker (AMD64 Linux)... even though the platform is now controlled by $(BUILD_PLATFORM). When a user overrides the platform (e.g., BUILD_PLATFORM=linux/arm64 make test-docker), the log output will incorrectly claim AMD64 Linux. Update the echo to reference $(BUILD_PLATFORM) so it reflects the actual platform being used.

Extended reasoning...

What the bug is and how it manifests

In packages/orchestrator/Makefile, the test-docker target contains two lines that are now inconsistent after this PR's parameterization refactor. Line 110 (the echo) still hardcodes "AMD64 Linux", while line 115 (the actual docker build command) correctly uses $(BUILD_PLATFORM):

@echo "Running orchestrator tests in Docker (AMD64 Linux)..."
...
@docker build --platform $(BUILD_PLATFORM) -f test.Dockerfile ...

The specific code path that triggers it

Any invocation of make test-docker where BUILD_PLATFORM is set to a non-amd64 value will trigger the mismatch. For example: BUILD_PLATFORM=linux/arm64 make test-docker will print "Running orchestrator tests in Docker (AMD64 Linux)..." while Docker actually builds for linux/arm64.

Why existing code doesn't prevent it

The PR correctly updated every functional reference from linux/amd64 to $(BUILD_PLATFORM) but missed updating this informational echo statement. There is no mechanism in make to enforce consistency between echo strings and actual command flags.

What the impact would be

The impact is cosmetic/informational only — the actual docker build uses the correct $(BUILD_PLATFORM) variable, so builds are functionally correct. However, developers relying on the log output to confirm which platform is being targeted will be misled when using non-default platforms, potentially causing confusion during debugging or CI output review.

How to fix it

Change the echo to dynamically include the platform value:

@echo "Running orchestrator tests in Docker ($(BUILD_PLATFORM))..."

Step-by-step proof

  1. Default case (amd64 host): make test-dockerBUILD_PLATFORM resolves to linux/amd64 → echo says "AMD64 Linux" → happens to be accurate.
  2. Non-default case: BUILD_PLATFORM=linux/arm64 make test-docker → echo still prints "Running orchestrator tests in Docker (AMD64 Linux)..." → docker actually runs --platform linux/arm64 → the log output contradicts the actual behavior, misleading the developer.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed — echo now uses $(BUILD_PLATFORM) instead of hardcoded "AMD64 Linux".

- Remove BUILD_ARCH/BUILD_PLATFORM from api Makefile (uses docker-bake.hcl)
- Fix misleading multi-arch BUILD_PLATFORM examples in envd and
  orchestrator Makefiles (these use plain docker build, not buildx)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

docker run \
--name envd \
--platform linux/amd64 \
--platform $(BUILD_PLATFORM) \
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Envd start-docker mixes local binary arch with Docker platform

Medium Severity

The start-docker target calls make build (which uses GOARCH=$(BUILD_ARCH)) then docker build/run --platform $(BUILD_PLATFORM). Since debug.Dockerfile copies the locally-built binary (COPY bin/envd), overriding only BUILD_PLATFORM (as the comment on line 14 documents: BUILD_PLATFORM=linux/arm64 make start-docker) creates an architecture mismatch — the Go binary is built for the host arch while the container expects the overridden platform. This causes an exec format error at runtime.

Additional Locations (1)
Fix in Cursor Fix in Web

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't fix — BUILD_ARCH and BUILD_PLATFORM both default to host arch via go env GOARCH. They only diverge if a user overrides one but not the other, which is a user error. Adding coupling would add complexity for no practical benefit.

Replace hardcoded 'AMD64 Linux' with $(BUILD_PLATFORM) so the log
output reflects the actual platform being tested.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@jakubno jakubno merged commit 911760b into main Mar 30, 2026
36 checks passed
@jakubno jakubno deleted the chore/makefile-build-arch branch March 30, 2026 07:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants