Is CMakeCCompilerId.c used on the target or host system? How to tell Cmake which build system to use?

Newbie here.

My question appears to be a variant of:

Cross compiling a Qt application for arm but the target rcc and moc executables are used instead of the host versions

My question is about specific operation of the Cmake operational process which I think is a narrower version of the same operational issue.

The description of Tool Chains is explicit about using it to describe the Target environment but says little ( that I could glean ) about the use or settings for the Host environment. This is important because it is unclear whether the files CMakeCCompilerId.c and/or CMakeCXXCompilerId.cpp are executed on the host or on the target. Their purpose/utility is not apparent to this reader. If they are to be executed on the host as I suspect then how does one tell CMake this? Currently, my cross compilation setup thinks both are to be executed on the target processor yielding the following error:

Compiling the C compiler identification source file "CMakeCCompilerId.c" failed.
Compiler: C:/VSARM/armcc/10 2021.10/bin/arm-none-eabi-gcc.exe
Build flags: ;-mcpu=cortex-m0plus;-mthumb
Id flags:
The output was:
c:/vsarm/armcc/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/bin/ld.exe: c:/vsarm/armcc/10 2021.10/bin/../lib/gcc/arm-none-eabi/10.3.1/../../../../arm-none-eabi/lib/thumb/v6-m/nofp\libc.a(lib_a-exit.o): in function `exit':
exit.c:(.text.exit+0x18): undefined reference to `_exit'
collect2.exe: error: ld returned 1 exit status

This undefined reference error occurs for both c and cpp files although the compilation succeeds for both. So the questions are, Is my suspicion correct and if so how does one inform Cmake to use the host build process?

I think a description of how to manage the host side of cross compiling and a clear delineation of which parts of the Cmake process are built for use on the host in support of the target versus those that are built directly for the target would reduce my confusion and perhaps that of others.

On a more general note, I find my biggest barrier to the use of Cmake is that I have little to no operational model of how it works. So, I find it difficult to reason about its behavior. The context of usage for particular commands rarely describes the surrounding conditions. This would provide the context and motivation for a commands usage and therefore reduce forensic exploration to discover the operational model.

@craig.scott might have some input here. Getting host tools in a cross-compile can be…interesting when the same package also provides the same targets to the host bits.

I thought Qt itself handled working out where to get its own host tools from (moc, rcc, etc.). You may want to revisit their build/setup instructions and follow whatever they recommend. You shouldn’t need to be getting down into the low level details that you are at the moment. From what I recall, you may need to set one variable to tell it where to find the host Qt tools, but again, see what their current instructions tell you to do.

Thanks for the suggestion. I’ve rebuilt the entire cross-development system several ( more than 3) times and keep getting the same issue. There is likely some minor detail that I’m overlooking that provides the correct hint to the mysterious operation of Cmake. If only there were a dependency tree from setting a variable to the downstream failure! I’ve changed a number of things but with no success and no change in the failure error messages. Random walks in a large domain are rarely successful without an enormous number of steps he says as onward he plods!

@alcroito or @jobor might have more insight into this area.

Not sure how the original question is related to qt.

There’s one important thing to know, roughly, a single CMake invocation can only build for one specific target platform.

Trying to build executables/libraries for two different targets (platforms, architectures) with a single CMake invocation is not generally supported, without doing additional ‘workarounds’ like calling the compiler and linker manually, or using something like ExternalProject_Add, which adds a lot more complexity.

That’s why Qt forces builders to build Qt twice for cross-compilation, once to get host tools, and once for some cross-compilation target, with separate cmake invocations, in two separate build directories. The second invocation then uses the already built host tools from the first installation, and thus doesn’t need to try and build for two different architectures.

Which target is being built is controlled by the toolchain file.

You ask ’ This is important because it is unclear whether the files CMakeCCompilerId.c and/or CMakeCXXCompilerId.cpp are executed on the host or on the target.’

The files are compiled for whatever target is specified in your toolchain file. Given the various arm cortex flags, i assume the toolchain is set up to cross-compile, for some arm target.
I don’t know why you get an undefined symbol error from the linker, but i don’t think it’s related to the host in any way. It’s likely an issue with your c/c++ toolchain or with the cmake toolchain file.

Weird, I may have mixed up this one with a different thread. I thought the original query related to a Qt build and missing tools like rcc, moc, etc. Sorry for pulling you into this one if it wasn’t Qt-related!

Thanks for assisting me in understanding what is going on.

I don’t think my original question is related to qt; except in the sense that CMake is used to cross-compile qt similar to what I’m trying to do.

Also, I’m not trying to build executables or libraries for two different targets. My target is an ARM Cortex M0+ chip with CMake and the build and compilation tools are executing on a Windows 10 machine. CMake in its wisdom produces the files CMakeCCompilerId.c and CMakeCXXCompilerId.c whose utility and use is unclear ( at least to me!).

I suspect that they are used to validate or identify the cross-compiler used in the build. So if this is true, wouldn’t they be run on the machine hosting the cross compiler ( i.e. the Win10 machine.)?

However, the evidence seems to point toward CMake compiling them for the target and then cannot find the supporting libraries ( e.g. _exit() ) which is not used on the target. This causes the CMake to fail and therefore never get to “making” the files intended to be built for the target.

Perhaps if I understood the two files use/utility in the build process I could make some progress in correcting the error.

I presumed, probably incorrectly, that CMake would have commands to control the build of these two files to assure that they are tools executed on the host where the cross compiler runs. It is also quite possible ( and becoming more likely by the day ) that I’m missing a key piece of understanding of CMake.

I appreciate your taking the time to explain more of what is going on.

Ah! Sorry, seems I got distracted by the Qt bit.

They are indeed compiled for the target. However, they are never executed. Instead, the binaries are inspected for strings which embed the information that is relevant. It seems that the toolchain setup for your cross-compilers needs flags to link in the standard library.

Excellent! Thanks, this clears up my misunderstanding and makes perfect sense that the binaries would be examined for the info. Ok, so now off to find out how to tell the linker that there is not an _exit() routine for this “bare metal” machine. Thanks again for your assistance. The fog is slightly less dense! :wink:

Ben Boeckel provides the succinct answer to the question:

[quote=“Ben Boeckel, post:9, topic:6731, username:ben.boeckel”]
They are indeed compiled for the target. However, they are never executed. Instead, the binaries are inspected for strings which embed the information that is relevant.

The use is by CMake on the Host Machine which examines the compiled binaries (on the host) for the “relevant information” (the utility) before completing the build. This cross compiler assumes that the standard runtime library contains an _exit() routine which the target runtime does NOT contain. Thus a link error is generated.

In your toolchain file, set CMAKE_TRY_COMPILE_TARGET_TYPE to STATIC_LIBRARY. Then it will only create a static library instead of an executable. That will avoid the linker trying to resolve symbols that are not going to be there for a bare metal arrangement.

Thank you Craig, I’ll give it a try!