Skip to content

Conversation

@auricom
Copy link
Contributor

@auricom auricom commented Jun 24, 2025

Fix Remote Cross Compilation for Multi-Architecture Docker Builds

🎯 Problem

The GitHub Actions workflow was failing during cross-compilation for ARM64 (aarch64) targets due to missing native dependencies and improper toolchain configuration. The build errors included:

  • fatal: No names found, cannot describe anything during git operations
  • error: failed to run custom build command for reth-mdbx-sys with missing stdarg.h headers
  • could not exec the linker cc permission denied errors
  • ARM64 compiler receiving x86_64-specific flags like -m64

🔧 Solution

This PR implements a comprehensive fix for cross-compilation issues by:

1. Enhanced GitHub Workflow (.github/workflows/docker.yml)

  • Added build dependencies installation: Essential tools like build-essential, libclang-dev, clang, llvm-dev
  • Set up toolchain variables: Target-specific CC, CXX, AR for both x86_64 and aarch64

2. Cross-Compilation Configuration (Cross.toml)

  • Custom Docker images: Uses target-specific Dockerfiles for proper toolchain setup

3. ARM64 Docker Image (Dockerfile.cross-aarch64)

4. x86_64 Docker Image (Dockerfile.cross-x86_64)

🚀 Key Improvements

  • ✅ Fixes native dependency compilation: reth-mdbx-sys, tikv-jemalloc-sys, and blst now build successfully
  • ✅ Resolves header location issues: Proper include paths for stdarg.h and other standard headers
  • ✅ Eliminates permission errors: Correct toolchain setup prevents execution permission issues
  • ✅ Supports multi-architecture: Both x86_64 and ARM64 Docker images build successfully
  • ✅ Maintains CI efficiency: Uses proven cross-rs infrastructure with minimal overhead

This fix ensures the project can build and deploy successfully on both Intel/AMD and ARM-based systems, supporting the growing ARM64 ecosystem while maintaining full x86_64 compatibility.

Summary by CodeRabbit

  • New Features
    • Added dedicated cross-compilation support for x86_64 and ARM64 (aarch64) Linux targets using new Dockerfiles and configuration.
  • Chores
    • Enhanced the build workflow to explicitly install required dependencies and set up environment variables for cross-compilation.
    • Introduced a configuration file to manage cross-compilation settings and environment variables for consistent builds.

@auricom auricom requested a review from a team as a code owner June 24, 2025 15:27
@coderabbitai
Copy link

coderabbitai bot commented Jun 24, 2025

Walkthrough

This update introduces new Dockerfiles and a Cross.toml configuration to support cross-compilation for x86_64 and aarch64 Linux targets. The GitHub Actions workflow is enhanced to install required build dependencies and set environment variables for cross-compilation and binding generation, improving the automation of Docker image builds for multiple architectures.

Changes

File(s) Change Summary
.github/workflows/docker.yml Enhanced workflow: installs build dependencies and sets environment variables for cross-compilation and binding generation.
Cross.toml New file: defines cross-compilation settings and Docker images for x86_64 and aarch64 targets, with environment passthroughs.
Dockerfile.cross-aarch64 New file: adds ARM64 cross-compilation environment with toolchains, environment variables, and cleanup steps.
Dockerfile.cross-x86_64 New file: adds x86_64 cross-compilation environment with build tools, environment variables, and cleanup steps.

Sequence Diagram(s)

sequenceDiagram
    participant Developer
    participant GitHubActions
    participant Docker
    participant Cross-Env

    Developer->>GitHubActions: Push/PR triggers workflow
    GitHubActions->>GitHubActions: Install build dependencies
    GitHubActions->>GitHubActions: Set cross-compilation env vars
    GitHubActions->>Docker: Build Docker image (multi-arch)
    Docker->>Cross-Env: Use Dockerfile.cross-x86_64 or Dockerfile.cross-aarch64
    Cross-Env->>Docker: Prepare build environment
    Docker->>GitHubActions: Return built image
    GitHubActions->>Docker: Push image to registry
Loading

Poem

In the warren where code and carrots blend,
New Dockerfiles for arches, around the bend!
Cross.toml hops in, with settings so bright,
Workflows now build with cross-compiling might.
From x86_64 to ARM64 we leap—
Rabbits rejoice, our builds run deep! 🐇✨


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @auricom, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly improves our CI/CD pipeline's ability to perform remote cross-compilation for multi-architecture Docker builds. It specifically addresses and resolves long-standing issues preventing successful ARM64 and x86_64 builds by introducing robust toolchain configurations and dedicated build environments.

Highlights

  • Enhanced Cross-Compilation Configuration: A Cross.toml file has been introduced to configure the cross-rs tool, directing it to utilize custom Docker images for both x86_64-unknown-linux-gnu and aarch64-unknown-linux-gnu targets. This centralizes and streamlines the cross-compilation setup.
  • Dedicated Multi-Architecture Docker Images: Two new Dockerfiles, Dockerfile.cross-aarch64 and Dockerfile.cross-x86_64, have been added. These images are specifically tailored to provide the correct build environments, including necessary toolchains (e.g., gcc, clang), build dependencies, and precise environment variable configurations (like CC, CXX, AR, BINDGEN_EXTRA_CLANG_ARGS, CFLAGS) to ensure successful compilation of native dependencies for their respective architectures.
  • Resolved Critical Build Failures: These changes collectively eliminate previously encountered build errors, such as missing standard headers (stdarg.h), linker permission issues, and incorrect compiler flag usage. This ensures that native dependencies like reth-mdbx-sys, tikv-jemalloc-sys, and blst now compile successfully across both ARM64 and x86_64 architectures.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

The pull request effectively addresses the cross-compilation issues for multi-architecture Docker builds by introducing dedicated Dockerfiles for ARM64 and x86_64 targets, along with the necessary Cross.toml configuration. The changes correctly set up toolchains and environment variables, resolving previously reported build errors. The solution appears robust and well-aligned with the problem statement.

@@ -0,0 +1,27 @@
FROM ghcr.io/cross-rs/cross:main
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

For improved build reproducibility and stability in CI/CD pipelines, it's generally recommended to pin Docker base images to a specific version tag or a digest instead of using a mutable tag like main. While cross:main might be intended to be stable, a specific version (e.g., cross:0.2.x or cross@sha256:digest) would prevent unexpected build failures if the main tag is updated with breaking changes.

@@ -0,0 +1,19 @@
FROM ghcr.io/cross-rs/cross:main
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Similar to the aarch64 Dockerfile, consider pinning the base image to a specific version tag or digest (e.g., ghcr.io/cross-rs/cross:0.2.x or cross@sha256:digest) instead of main. This practice enhances reproducibility and prevents potential issues arising from unexpected updates to the main tag.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (4)
Dockerfile.cross-x86_64 (1)

3-10: Trim image size & speed-up builds – add --no-install-recommends and clean cache more aggressively

build-essential, pkg-config, clang, etc. bring in a large list of recommended packages that are not needed for CI and bloat the final image.
Adding --no-install-recommends and an explicit apt-get clean keeps layers small and speeds-up downstream pulls.

-RUN apt-get update && \
-    apt-get install -y \
+RUN apt-get update && \
+    apt-get install -y --no-install-recommends \
         build-essential \
@@
-    rm -rf /var/lib/apt/lists/*
+    apt-get clean && rm -rf /var/lib/apt/lists/*
Cross.toml (1)

10-14: Forward PKG_CONFIG_ALLOW_CROSS to guarantee pkg-config inside build scripts

Several crates (openssl-sys, jemalloc-sys) rely on PKG_CONFIG_ALLOW_CROSS=1. It is set in the workflow and Dockerfiles, but not forwarded by Cross when the build runs locally.

 pasthrough = [
     "RUST_LOG",
     "CARGO_TERM_COLOR",
+    "PKG_CONFIG_ALLOW_CROSS",
 ]
.github/workflows/docker.yml (1)

27-38: Optimise dependency installation & avoid unneeded multilib packages

gcc-multilib / g++-multilib are only required when building 32-bit binaries on amd64; they are irrelevant for aarch64/x86_64 cross targets and add ~200 MB to the runner.

Consider dropping them or gating on a separate matrix entry if 32-bit artefacts are ever required.

Dockerfile.cross-aarch64 (1)

3-13: Same sizing remark as x86_64 – use --no-install-recommends & clean cache

Replicate the optimisation pattern suggested for the x86_64 Dockerfile to keep the ARM image slim.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 019fb82 and 284c391.

📒 Files selected for processing (4)
  • .github/workflows/docker.yml (2 hunks)
  • Cross.toml (1 hunks)
  • Dockerfile.cross-aarch64 (1 hunks)
  • Dockerfile.cross-x86_64 (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: test
  • GitHub Check: e2e
🔇 Additional comments (3)
Dockerfile.cross-x86_64 (1)

12-19: Pin toolchain versions or risk non-reproducible builds

Relying on the distro’s latest cross toolchain (e.g. x86_64-linux-gnu-gcc) means the exact compiler version can silently change whenever the base image updates, potentially breaking reproducibility.
Consider pinning to an explicit Debian/Ubuntu release or installing a concrete version via apt-get install gcc-13 etc.

Cross.toml (1)

4-8: Missing image = field might break Cross in older versions

While recent cross-rs allows dockerfile = without an accompanying image =, older versions (≤0.2.5) still expect it. Unless the CI toolchain version is locked, builds can sporadically fail.

[target.x86_64-unknown-linux-gnu]
dockerfile = "Dockerfile.cross-x86_64"
+# image = "lumen-cross:x86_64"   # optional but safer
.github/workflows/docker.yml (1)

52-62: Symmetry gap – missing STRIP_* / CPPFLAGS_* env vars for CI build

The Dockerfiles define STRIP_*, CPPFLAGS_*, etc., but the workflow only exports CC, CXX, and AR. During CI these variables leak from the host instead of being target-specific, occasionally breaking link steps (e.g. jemalloc’s make install-strip).

Add the missing counterparts:

 export AR_x86_64_unknown_linux_gnu=x86_64-linux-gnu-ar
+export STRIP_x86_64_unknown_linux_gnu=x86_64-linux-gnu-strip
 export CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
 export CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
 export AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar
+export STRIP_aarch64_unknown_linux_gnu=aarch64-linux-gnu-strip

Comment on lines +15 to +27
# Set up environment variables for ARM64 cross-compilation
# Keep host compiler for build scripts, only set target-specific variables
ENV CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
ENV CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
ENV AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar
ENV STRIP_aarch64_unknown_linux_gnu=aarch64-linux-gnu-strip
ENV PKG_CONFIG_aarch64_unknown_linux_gnu=aarch64-linux-gnu-pkg-config
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
ENV BINDGEN_EXTRA_CLANG_ARGS="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV CFLAGS_aarch64_unknown_linux_gnu="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV CPPFLAGS_aarch64_unknown_linux_gnu="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV JEMALLOC_SYS_WITH_LG_PAGE=16
ENV PKG_CONFIG_ALLOW_CROSS=1
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Environment-variable inconsistency will confuse Cross / bindgen

For x86_64 you used a target-scoped variable
BINDGEN_EXTRA_CLANG_ARGS_x86_64_unknown_linux_gnu,
but here you set the global BINDGEN_EXTRA_CLANG_ARGS.
This value will bleed into all targets and host builds.

Align naming and avoid accidental host pollution:

-ENV BINDGEN_EXTRA_CLANG_ARGS="-I/usr/aarch64-linux-gnu/include -I/usr/include"
+ENV BINDGEN_EXTRA_CLANG_ARGS_aarch64_unknown_linux_gnu="-I/usr/aarch64-linux-gnu/include -I/usr/include"

Do the same for CFLAGS / CPPFLAGS if you want them target-scoped.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# Set up environment variables for ARM64 cross-compilation
# Keep host compiler for build scripts, only set target-specific variables
ENV CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
ENV CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
ENV AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar
ENV STRIP_aarch64_unknown_linux_gnu=aarch64-linux-gnu-strip
ENV PKG_CONFIG_aarch64_unknown_linux_gnu=aarch64-linux-gnu-pkg-config
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
ENV BINDGEN_EXTRA_CLANG_ARGS="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV CFLAGS_aarch64_unknown_linux_gnu="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV CPPFLAGS_aarch64_unknown_linux_gnu="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV JEMALLOC_SYS_WITH_LG_PAGE=16
ENV PKG_CONFIG_ALLOW_CROSS=1
# Set up environment variables for ARM64 cross-compilation
# Keep host compiler for build scripts, only set target-specific variables
ENV CC_aarch64_unknown_linux_gnu=aarch64-linux-gnu-gcc
ENV CXX_aarch64_unknown_linux_gnu=aarch64-linux-gnu-g++
ENV AR_aarch64_unknown_linux_gnu=aarch64-linux-gnu-ar
ENV STRIP_aarch64_unknown_linux_gnu=aarch64-linux-gnu-strip
ENV PKG_CONFIG_aarch64_unknown_linux_gnu=aarch64-linux-gnu-pkg-config
ENV CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER=aarch64-linux-gnu-gcc
ENV BINDGEN_EXTRA_CLANG_ARGS_aarch64_unknown_linux_gnu="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV CFLAGS_aarch64_unknown_linux_gnu="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV CPPFLAGS_aarch64_unknown_linux_gnu="-I/usr/aarch64-linux-gnu/include -I/usr/include"
ENV JEMALLOC_SYS_WITH_LG_PAGE=16
ENV PKG_CONFIG_ALLOW_CROSS=1
🤖 Prompt for AI Agents
In Dockerfile.cross-aarch64 around lines 15 to 27, the environment variables
BINDGEN_EXTRA_CLANG_ARGS, CFLAGS_aarch64_unknown_linux_gnu, and
CPPFLAGS_aarch64_unknown_linux_gnu are inconsistently scoped;
BINDGEN_EXTRA_CLANG_ARGS is set globally while others are target-scoped. To fix
this, rename BINDGEN_EXTRA_CLANG_ARGS to
BINDGEN_EXTRA_CLANG_ARGS_aarch64_unknown_linux_gnu to match the target-specific
pattern and similarly ensure CFLAGS and CPPFLAGS are consistently target-scoped
by using the appropriate target suffix in their variable names.

@auricom auricom closed this Jun 24, 2025
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