CMake selecting incorrect assembler

Hello everyone,

I am relatively new to CMake and I encountered an issue with CMake filing to compile the test program when trying to setup a simple “hello world” CMake script on a (new) Redhat 8 machine. I want to use a different compiler instead of the default one. Specifically, I am trying to choose the gcc toolset 11. For this I use the recommended methods suggested here.

The CMakeLists.txt is

project(hello_world)
message(STATUS "Hello world!")

The command line call is:

cmake -G "Ninja Multi-Config" -D CMAKE_C_COMPILER=/opt/rh/gcc-toolset-11/root/bin/gcc -D CMAKE_CXX_COMPILER=/opt/rh/gcc-toolset-11/root/bin/g++ /path/to/cmakelists.txt

This produces an error and the command line output is:

-- The C compiler identification is GNU 11.2.1
-- The CXX compiler identification is GNU 11.2.1
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: /opt/rh/gcc-toolset-11/root/bin/gcc
-- Check for working C compiler: /opt/rh/gcc-toolset-11/root/bin/gcc - broken
CMake Error at /u/location/of/cmake/cmake-3.24/Modules/CMakeTestCCompiler.cmake:69 (message):
  The C compiler

    "/opt/rh/gcc-toolset-11/root/bin/gcc"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: /u/location/of/cmakelists/temp_cmake_trial/build/CMakeFiles/CMakeTmp

    Run Build Command(s):/usr/bin/ninja cmTC_69185 && [1/2] Building C object CMakeFiles/cmTC_69185.dir/Debug/testCCompiler.c.o
    FAILED: CMakeFiles/cmTC_69185.dir/Debug/testCCompiler.c.o
    /opt/rh/gcc-toolset-11/root/bin/gcc -DCMAKE_INTDIR=\"Debug\"  -g -o CMakeFiles/cmTC_69185.dir/Debug/testCCompiler.c.o -c /u/location/of/cmakelists/temp_cmake_trial/build/CMakeFiles/CMakeTmp/testCCompiler.c
    as: unrecognized option '--gdwarf-4'
    ninja: build stopped: subcommand failed.





  CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:2 (project)


-- Configuring incomplete, errors occurred!
See also "/u/location/of/cmakelists/temp_cmake_trial/build/CMakeFiles/CMakeOutput.log".
See also "/u/location/of/cmakelists/temp_cmake_trial/build/CMakeFiles/CMakeError.log".

I see that CMake picks the correct C and CXX compiler. However, what I do not understand is why CMake does not choose GNU assembler as from the gcc toolset but instead chooses to use the default
one.

I could work around this problem by prefixing the location of the compiler, asselbler to PATH in the shell
but I do not want to do this. I would like to change the path only within CMake. I have tried modifying all the following variables:
CMAKE_PROGRAM_PATH, CMAKE_PRREFIX_PATH and (although not recommended) CMAKE_SYSTEM_PREFOX_PATH
by adding

LIST(APPEND CMAKE_ABCD_PATH  "/opt/rh/gcc-toolset-11/root/bin")

before the project(hello_world) call. None of these changes fix the problem.

I have tried this with gcc toolset 10 and everything works fine. The CMake version I am using is 3.24 and the OS is Redhat 8.6.

Thank you for the help.

I don’t think you can just feed devtoolset compilers as paths and instead you must use scl enable devtoolset-11 -- cmake … to properly load their environment.

Hi Ben,

Thank you for your reply. I did try scl enable earlier and as you pointed out, it does work. However, I wanted to know if there is a way to make it from from within CMake. Another issue which I do not yet understand is why setting the paths directly to the compiler locations of gcc-toolset-10 works while it does not for gcc-toolset-11.

Thank you again for the answer.

Luck. Toolset 10 didn’t use any flags the native assembler didn’t understand; you’re probably still using the system assembler and not the devtoolset’s assembler.

CMake, in general, assumes the compiler environment is already loaded when configuring and building. While this is generally trivial on Linux, alternate toolchains may require more setup (devtoolset and Intel toolchains being examples). Only the IDE generators really know how to find their own things, but make and ninja have no mechanism for CMake to say “please load toolchain X env before running”.

Thank you for the information. I understand this better now. I will look into this and get back in case I have more questions.

From my understanding (and for my current issue) the scl enable should be equivalent to prepending the /opt/rh/gcc-toolset-11/root/bin
to the PATH. (Manually adding this location to PATH in my shell before calling CMake does indeed fix my problem).
Then is there a way this can be done directly from CMake? I have already tried to set this in
the various CMake path variables.

To give some more context, we have multiple builds using various toolsets and ideally, we would like to keep all the settings for these stored within a CMakePresets or toolchain file and use it from that instead of setting it up prior to calling CMake.

If it is that simple, doing it from a toolchain file is probably possible… Though if you have ExternalProject instances, the build will need it set up too which means you will need the environment loaded during the build too. That will require external setup unless you’re somehow using Visual Studio or Xcode on Linux :wink: .

Trying to have CMake manage setting up the environment for the toolchain is raised by users from time to time… Unfortunately, this is outside the scope of what CMake can generally do for you. The user may invoke the build tool directly, so at build time, CMake won’t have the opportunity to set up the environment for the toolchain. Therefore, it is the user’s responsibility to set up the environment before invoking CMake or the build tool, and the assumption is that the environment will be the same for both.

There has been discussion about whether CMake presets could set up the required environment. Technically speaking, since the use of a build preset means CMake will be used to launch the build tool, it would be possible to engineer a preset to do this. However, I wouldn’t recommend it. You would essentially end up having to duplicate everything that something like scl enable ... does. While you might think that setting just the PATH is enough, it may set up other environment variables that may matter to the toolchain. And it’s not out of the question that those environment variables may get updated over time. I’d recommend just getting used to using the scl command as provided and incorporating that into your personal workflow.

I acknowledge that this isn’t so convenient when you are working entirely within the IDE though. I’d be interested in hearing how others deal with that aspect, which would be very IDE-specific.