Linker configuration in toolchain file for cross-compiling

I am trying to setup cross compilation using cmake.

I am working on windows 11. I am using WSL 2 with an Ubuntu-22.04 as host system to build on and my target system is an aarch64 embedded ARM processor running something like ubuntu. My current cmake support is for version 3.11 and upwards.

I have an SDK with the sysroot and all the build tools for the target system. This has been installed under ~/xos/env/sysroots/aarch64-linux/. However that SDK has a gcc compiler (version 9.2.1) with an issue making it unable to find any std library.
To solve this I also installed gcc for cross compiling directly from https://developer.arm.com/-/media/Files/downloads/gnu-a/9.2-2019.12/binrel/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz?revision=61c3be5d-5175-4db6-9030-b565aae9f766&rev=61c3be5d51754db69030b565aae9f766&hash=43A89163112C6A1E6DBBE3B14CC393143722BD0E
into the location ~/xos/gcc/.

Based on this, I create a toolchain file like such:

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR aarch64)
set(CMAKE_SYSROOT "${ROOT}sysroots/aarch64-linux/")

# Specify the cross compiler
set(CMAKE_C_COMPILER ${ROOT_GCC}aarch64-none-linux-gnu-gcc )
set(CMAKE_CXX_COMPILER ${ROOT_GCC}aarch64-none-linux-gnu-g++)

# indicate where the target environment libraries to include are located
set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT }usr/lib)

# search executable programs in the host environment
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)

# search headers and libraries ONLY in the target environment
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

where ${ROOT}, ${ROOT_GCC} are defined in the CMakeUserPresets.json file to account for the user name of each developer. For example:

{
  "version": 3,
  "configurePresets": [
    {
      "name": "MyRelease",
      "displayName": "release cross compile",
      "inherits": "base-release",
      "cacheVariables": {
        "ROOT_GCC": "~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/",
        "ROOT": "~/xos/env/"
      }
    }
  ]
}

I am running this from Visual Studio 2022, but in cmake mode (so not through solution files).

The problem I have is that cmake gives me the following error:

1> Copying files to the remote machine.
..
1> Finished copying files (elapsed time 00h:00m:00s:392ms).
1> CMake generation started for configuration: 'MyRelease'.
1> Found cmake executable at /usr/bin/cmake.
1> /usr/bin/cmake -G "Ninja" -DCMAKE_BUILD_TYPE:STRING="Release" -DROOT_GCC="~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/" -DROOT:STRING="~/xos/env/" -DCMAKE_INSTALL_PREFIX:PATH="~/.vs/<redacted>" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="cmake/toolchains/WSL-ARM64.cmake"   <redacted>/CMakeLists.txt;
1> [CMake] -- Setting up cross compilation toolchain
1> [CMake] -- The CXX compiler identification is GNU 9.2.1
1> [CMake] -- Detecting CXX compiler ABI info
1> [CMake] -- Detecting CXX compiler ABI info - failed
1> [CMake] -- Check for working CXX compiler: ~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++
1> [CMake] -- Check for working CXX compiler: ~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++ - broken
1> [CMake] CMake Error at /usr/share/cmake-3.22/Modules/CMakeTestCXXCompiler.cmake:62 (message):
1> [CMake]   The C++ compiler
1> [CMake] 
1> [CMake]     "~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++"
1> [CMake] 
1> [CMake]   is not able to compile a simple test program.
1> [CMake] 
1> [CMake]   It fails with the following output:
1> [CMake] 
1> [CMake]     Change Dir: <redacted>/out/build/MyRelease/CMakeFiles/CMakeTmp
1> [CMake]     
1> [CMake]     Run Build Command(s):/usr/bin/ninja cmTC_7d34b && [1/2] Building CXX object CMakeFiles/cmTC_7d34b.dir/testCXXCompiler.cxx.o
1> [CMake]     [2/2] Linking CXX executable cmTC_7d34b
1> [CMake]     FAILED: cmTC_7d34b 
1> [CMake]     : && ~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-g++ --sysroot=sysroots/aarch64-linux/usr/lib   CMakeFiles/cmTC_7d34b.dir/testCXXCompiler.cxx.o -o cmTC_7d34b   && :
1> [CMake]     ~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/9.2.1/../../../../aarch64-none-linux-gnu/bin/ld: cannot find crt1.o: No such file or directory
1> [CMake]     ~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/9.2.1/../../../../aarch64-none-linux-gnu/bin/ld: cannot find crti.o: No such file or directory
1> [CMake]     ~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/9.2.1/../../../../aarch64-none-linux-gnu/bin/ld: cannot find -lm
1> [CMake]     ~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/9.2.1/../../../../aarch64-none-linux-gnu/bin/ld: cannot find -lc
1> [CMake]     ~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/../lib/gcc/aarch64-none-linux-gnu/9.2.1/../../../../aarch64-none-linux-gnu/bin/ld: cannot find crtn.o: No such file or directory
1> [CMake]     collect2: error: ld returned 1 exit status
1> [CMake]     ninja: build stopped: subcommand failed.
1> [CMake]     
1> [CMake] 
1> [CMake]   CMake will not be able to correctly generate this project.
1> [CMake] Call Stack (most recent call first):
1> [CMake]   CMakeLists.txt:21 (project)
1> [CMake] -- Configuring incomplete, errors occurred!
1> [CMake] See also "<redacted>/out/build/MyRelease/CMakeFiles/CMakeOutput.log".
1> [CMake] See also "<redacted>/out/build/MyRelease/CMakeFiles/CMakeError.log".
1> [CMake] 
1> cd "~/.vs/XManager/out/build/MyRelease";/usr/bin/cmake -G "Ninja" -DCMAKE_BUILD_TYPE:STRING="Release" -DROOT_GCC:STRING="~/xos/gcc/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin/" -DROOT:STRING="~/xos/env/" -DCMAKE_INSTALL_PREFIX:PATH="<redacted>/out/install/MyRelease" -DCMAKE_TOOLCHAIN_FILE:FILEPATH="cmake/toolchains/WSL-ARM64.cmake"   <redacted> 2>&1; returned with exit code: 1

The error says that it cannot find crt1.o and such. Indeed, they are not in the gcc installation.
Instead these file are located in the sysroot: ${CMAKE_SYSROOT}usr/lib.

My question is how to make cmake handle this.

I learned from Googling the error that cmake is not calling the linker directly, but instead gcc is calling the linker and that I should somehow tell it to add this ${CMAKE_SYSROOT}usr/lib to the search path for the linker. But how exactly to do this?
I found the following variables, but none of them worked for me:

  • CMAKE_SYSROOT_LINK
  • CMAKE_<LANG>_IMPLICIT_LINK_DIRECTORIES

One thing I did noticed is that if I do not set the CMAKE_SYSROOT variable, then everything compiles and links. But reading the ‘Professional cmake’ book, it strongly suggest to define this variable to indicate the cross compilation nature to CMake.

Can anybody tell me which cmake variable I should set to indicate that it should include this ${CMAKE_SYSROOT}usr/lib as search path towards the linker? Or how I should solve this issue?

Thank you in advance.

note: Whenever you see ~ or <redacted> the full path is actually present, but I removed it in this post for anonymity.