Skip to content

Conversation

rossburton
Copy link
Contributor

When cross-compiling the LLVM project as a whole (from llvm/), if it cannot find presupplied tools it will create a native build environment to build the tools it needs.

However, when doing a standalone build of clang (that is, from clang/ and linking against an existing libLLVM) this doesn't work. Instead a target binary is built which predictably then fails.

The conventional workaround for this is to build the native tools in a separate native compile phase and pass the paths to the cross build, for example see OpenEmbedded[1] or Nix[2]. But we can do better!

The first problem is that LLVM_USE_HOST_TOOLS is only set in the llvm/ CMakeLists.txt, so setup_host_tool() will never consider building a native binary. This can be solved by setting LLVM_USE_HOST_TOOLS based on CMAKE_CROSSCOMPILING in clang/CMakeLists.txt in the standalone case.

Now setup_host_tool() will try to build a native tool, but it needs build_native_tool() from CrossCompile.cmake, so that also needs to be included.

Finally, the native binary then fails because there's no provider for the dependency "CONFIGURE_Clang_NATIVE", so use llvm_create_cross_target to create the native environment.

These few lines mirror what the lldb CMakeLists.txt does in the standalone case, so there is prior art for this.

[1] https://git.openembedded.org/openembedded-core/tree/meta/recipes-devtools/clang/clang_git.bb?id=e18d697e92b55e57124e80234369d46575226386#n212
[2] https://github.com/NixOS/nixpkgs/blob/3354d448f2a26117a74638957b0131ce3da9c8c4/pkgs/development/compilers/llvm/common/tblgen.nix#L54

… clang

When cross-compiling the LLVM project as a whole (from llvm/), if it
cannot find presupplied tools it will create a native build environment
to build the tools it needs.

However, when doing a standalone build of clang (that is, from clang/
and linking against an existing libLLVM) this doesn't work. Instead
a _target_ binary is built which predictably then fails.

The conventional workaround for this is to build the native tools in a
separate native compile phase and pass the paths to the cross build, for
example see OpenEmbedded[1] or Nix[2]. But we can do better!

The first problem is that LLVM_USE_HOST_TOOLS is only set in the llvm/
CMakeLists.txt, so setup_host_tool() will never consider building a
native binary.  This can be solved by setting LLVM_USE_HOST_TOOLS based
on CMAKE_CROSSCOMPILING in clang/CMakeLists.txt in the standalone case.

Now setup_host_tool() will try to build a native tool, but it needs
build_native_tool() from CrossCompile.cmake, so that also needs to be
included.

Finally, the native binary then fails because there's no provider for
the dependency "CONFIGURE_Clang_NATIVE", so use llvm_create_cross_target
to create the native environment.

These few lines mirror what the lldb CMakeLists.txt does in the
standalone case, so there is prior art for this.

[1] https://git.openembedded.org/openembedded-core/tree/meta/recipes-devtools/clang/clang_git.bb?id=e18d697e92b55e57124e80234369d46575226386#n212
[2] https://github.com/NixOS/nixpkgs/blob/3354d448f2a26117a74638957b0131ce3da9c8c4/pkgs/development/compilers/llvm/common/tblgen.nix#L54
@llvmbot llvmbot added the clang Clang issues not falling into any other category label Sep 24, 2025
@llvmbot
Copy link
Member

llvmbot commented Sep 24, 2025

@llvm/pr-subscribers-clang

Author: Ross Burton (rossburton)

Changes

When cross-compiling the LLVM project as a whole (from llvm/), if it cannot find presupplied tools it will create a native build environment to build the tools it needs.

However, when doing a standalone build of clang (that is, from clang/ and linking against an existing libLLVM) this doesn't work. Instead a target binary is built which predictably then fails.

The conventional workaround for this is to build the native tools in a separate native compile phase and pass the paths to the cross build, for example see OpenEmbedded[1] or Nix[2]. But we can do better!

The first problem is that LLVM_USE_HOST_TOOLS is only set in the llvm/ CMakeLists.txt, so setup_host_tool() will never consider building a native binary. This can be solved by setting LLVM_USE_HOST_TOOLS based on CMAKE_CROSSCOMPILING in clang/CMakeLists.txt in the standalone case.

Now setup_host_tool() will try to build a native tool, but it needs build_native_tool() from CrossCompile.cmake, so that also needs to be included.

Finally, the native binary then fails because there's no provider for the dependency "CONFIGURE_Clang_NATIVE", so use llvm_create_cross_target to create the native environment.

These few lines mirror what the lldb CMakeLists.txt does in the standalone case, so there is prior art for this.

[1] https://git.openembedded.org/openembedded-core/tree/meta/recipes-devtools/clang/clang_git.bb?id=e18d697e92b55e57124e80234369d46575226386#n212
[2] https://github.com/NixOS/nixpkgs/blob/3354d448f2a26117a74638957b0131ce3da9c8c4/pkgs/development/compilers/llvm/common/tblgen.nix#L54


Full diff: https://github.com/llvm/llvm-project/pull/160605.diff

1 Files Affected:

  • (modified) clang/CMakeLists.txt (+6)
diff --git a/clang/CMakeLists.txt b/clang/CMakeLists.txt
index 1bb73599970c1..4eaa712899856 100644
--- a/clang/CMakeLists.txt
+++ b/clang/CMakeLists.txt
@@ -80,6 +80,12 @@ if(CLANG_BUILT_STANDALONE)
   include(GetErrcMessages)
   include(LLVMDistributionSupport)
 
+  if(CMAKE_CROSSCOMPILING)
+    set(LLVM_USE_HOST_TOOLS ON)
+    include(CrossCompile)
+    llvm_create_cross_target(Clang NATIVE "" Release)
+  endif()
+
   set(PACKAGE_VERSION "${LLVM_PACKAGE_VERSION}")
   set(BUG_REPORT_URL "${LLVM_PACKAGE_BUGREPORT}" CACHE STRING
     "Default URL where bug reports are to be submitted.")

@jthackray jthackray self-requested a review September 24, 2025 21:06
Copy link
Contributor

@jthackray jthackray left a comment

Choose a reason for hiding this comment

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

LGTM

@jthackray jthackray merged commit 2100c50 into llvm:main Sep 26, 2025
11 checks passed
YixingZhang007 pushed a commit to YixingZhang007/llvm-project that referenced this pull request Sep 27, 2025
… clang (llvm#160605)

When cross-compiling the LLVM project as a whole (from llvm/), if it
cannot find presupplied tools it will create a native build environment
to build the tools it needs.

However, when doing a standalone build of clang (that is, from clang/
and linking against an existing libLLVM) this doesn't work. Instead a
_target_ binary is built which predictably then fails.

The conventional workaround for this is to build the native tools in a
separate native compile phase and pass the paths to the cross build, for
example see OpenEmbedded[1] or Nix[2]. But we can do better!

The first problem is that LLVM_USE_HOST_TOOLS is only set in the llvm/
CMakeLists.txt, so setup_host_tool() will never consider building a
native binary. This can be solved by setting LLVM_USE_HOST_TOOLS based
on CMAKE_CROSSCOMPILING in clang/CMakeLists.txt in the standalone case.

Now setup_host_tool() will try to build a native tool, but it needs
build_native_tool() from CrossCompile.cmake, so that also needs to be
included.

Finally, the native binary then fails because there's no provider for
the dependency "CONFIGURE_Clang_NATIVE", so use llvm_create_cross_target
to create the native environment.

These few lines mirror what the lldb CMakeLists.txt does in the
standalone case, so there is prior art for this.

[1]
https://git.openembedded.org/openembedded-core/tree/meta/recipes-devtools/clang/clang_git.bb?id=e18d697e92b55e57124e80234369d46575226386#n212
[2]
https://github.com/NixOS/nixpkgs/blob/3354d448f2a26117a74638957b0131ce3da9c8c4/pkgs/development/compilers/llvm/common/tblgen.nix#L54
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants