This is an archive of the discontinued LLVM Phabricator instance.

[compiler-rt] Check for missing CMAKE_C_COMPILER_TARGET when using COMPILER_RT_DEFAULT_TARGET_ONLY
ClosedPublic

Authored by DavidSpickett on Apr 5 2023, 2:06 AM.

Details

Summary

COMPILER_RT_DEFAULT_TARGET_ONLY is the goto workaround for building
only one of a multilib setup while still being able to autodetect the native target.
For example only building 64 bit libraries on Intel instead of 32 and 64 bit.
Which may fail without 32 bit compatibility libs installed.

As reported in https://discourse.llvm.org/t/configuring-compiler-rt-to-use-default-target-only-does-not-work/62727
this build config hasn't worked in a while.

It relies on a variable usually set during cross compliation,
though my testing shows you can set it in other scenarios too.
https://cmake.org/cmake/help/latest/variable/CMAKE_LANG_COMPILER_TARGET.html

So the options you need to provide are:
-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DCMAKE_C_COMPILER_TARGET="aarch64-unknown-linux-gnu"

And we should error if CMAKE_C_COMPILER_TARGET isn't set.

Diff Detail

Event Timeline

DavidSpickett created this revision.Apr 5 2023, 2:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 5 2023, 2:06 AM
DavidSpickett requested review of this revision.Apr 5 2023, 2:06 AM
Herald added a project: Restricted Project. · View Herald TranscriptApr 5 2023, 2:06 AM
Herald added a subscriber: Restricted Project. · View Herald Transcript

AArch64 doesn't have >1 possible configuration so I'm going to check this on x86 also.

We do already advise this but only in the context of cross compiling:
https://llvm.org/docs/HowToCrossCompileBuiltinsOnArm.html#building-compiler-rt-builtins-for-arm

Which no one is going to think to look for.

Ah, that explains the error. Thanks for digging this up.

I'm just wondering why CMAKE_C_COMPILER_TARGET isn't set automatically. This sounds like a variable that CMake would always set?

According to the docs "The target for cross-compiling, if supported.". So in this case we're not cross compiling but compiling natively, just with different configurations. It's a bit weird to ask people to set it when not cross compiling, but I have a feeling that COMPILER_RT_DEFAULT_TARGET_ONLY is on its way out in any case, it doesn't really gel with how the runtimes build does things. So a bit of strangeness here won't hurt.

If you can try this with MIPS that would be great.

Tested this on x86. The default build there gives you:

$ ls lib/clang/17/lib/
i386-unknown-linux-gnu/   x86_64-unknown-linux-gnu/

If you add the right options:

-DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DCMAKE_C_COMPILER_TARGET="x86_64-unknown-linux-gnu"

You can get just the 64 bit libraries.

(and this patch doesn't change how any of that actually works, but I wanted to check it wasn't more broken outside of AArch64)

The issue you're seeing on the buildbot is because we're passing a -D... argument to check_c_source_compiles but as a flag not a definition. So cmake thinks it's an option for it.

https://cmake.org/cmake/help/v3.20/module/CheckCSourceCompiles.html

There is a separate option for defines but it will take some surgery to get compiler-rt to use it consistently. It's likely that all this did work before the cmake version was updated, but it wasn't really meant to work that way.

OK, I'm going to apply the patch now and perform a test build to see whether I can get compiler-rt to build successfully on mips64el with CMAKE_C_COMPILER_TARGET set.

Can you make a suggestion on what to change in llvm-zorg for the builder clang-mips64el-linux?

Recorded the issue with multilib detection in https://github.com/llvm/llvm-project/issues/61975.

glaubitz accepted this revision.Apr 6 2023, 1:27 AM

I have verified the change works correctly and solves the problem as intended.

Although I must say, I don't understand why the code checks for CMAKE_C_COMPILER_TARGET instead of COMPILER_RT_DEFAULT_TARGET_TRIPLE.

This revision is now accepted and ready to land.Apr 6 2023, 1:27 AM

I don't understand why the code checks for CMAKE_C_COMPILER_TARGET instead of COMPILER_RT_DEFAULT_TARGET_TRIPLE.

What I gather is that the two options are opposed to each other.

COMPILER_RT_DEFAULT_TARGET_ONLY = autodetect what the default target is, only build that
COMPILER_RT_DEFAULT_TARGET_TRIPLE = I am telling you what the default target triple is, only build that

After this code there is another if that sets COMPILER_RT_HAS_EXPLICIT_DEFAULT_TARGET_TRIPLE. So I think COMPILER_RT_DEFAULT_TARGET_TRIPLE is used later on, instead of CMAKE_C_COMPILER, but you can't set COMPILER_RT_DEFAULT_TARGET_TRIPLE up front.

In other words COMPILER_RT_DEFAULT_TARGET_ONLY causes COMPILER_RT_DEFAULT_TARGET_TRIPLE to be autodetected, but setting COMPILER_RT_DEFAULT_TARGET_TRIPLE is asking for the opposite of that.