Can't crosscompile CMake itself

Hello. I am using clang as a crosscompiler. My toolchain is functional, i can build programs for arm with it. But when i want to bootstrap CMake itself it fails with error:

$ cmake .. -DCMAKE_CROSSCOMPILING=True -DCMAKE_SYSTEM_NAME=Linux -DCMAKE_SYSTEM_PROCESSOR=arm --debug-trycompile
debug trycompile on
-- The C compiler identification is Clang 12.0.0
-- The CXX compiler identification is Clang 12.0.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /opt/llvm_lto_better/bin/clang - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /opt/llvm_lto_better/bin/clang++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Checking if compiler supports needed C++17 constructs
-- Checking if compiler supports needed C++17 constructs - yes
-- Checking if compiler supports C++ make_unique
-- Checking if compiler supports C++ make_unique - no
-- Checking if compiler supports C++ unique_ptr
-- Checking if compiler supports C++ unique_ptr - no
-- Checking if compiler supports C++ filesystem
CMake Error: TRY_RUN() invoked in cross-compiling mode, please set the following cache variables appropriately:
   CMake_RUN_CXX_FILESYSTEM (advanced)
   CMake_RUN_CXX_FILESYSTEM__TRYRUN_OUTPUT (advanced)
For details see /tmp/cmake-3.19.3/b/TryRunResults.cmake
-- Checking if compiler supports C++ filesystem - no
CMake Error at CMakeLists.txt:107 (message):
  The C++ compiler does not support C++11 (e.g.  std::unique_ptr).


-- Configuring incomplete, errors occurred!
See also "/tmp/cmake-3.19.3/b/CMakeFiles/CMakeOutput.log".
See also "/tmp/cmake-3.19.3/b/CMakeFiles/CMakeError.log".

So, lines in error log look like that:

Determining if compiler supports C++ make_unique failed with the following output:
Change Dir: /tmp/cmake-3.19.3/b/CMakeFiles/CMakeTmp

Run Build Command(s):/usr/bin/make cmTC_f848c/fast && /usr/bin/make  -f CMakeFiles/cmTC_f848c.dir/build.make CMakeFiles/cmTC_f848c.dir/build
make[1]: Entering directory '/tmp/cmake-3.19.3/b/CMakeFiles/CMakeTmp'
Building CXX object CMakeFiles/cmTC_f848c.dir/cm_cxx_make_unique.cxx.o
/opt/llvm_lto_better/bin/clang++   --target=arm-linux-gnueabihf -nostdinc -nostdinc++ -I /opt/armhf_initial/include/c++/v1/ -I /usr/arm-linux-gnueabihf/include/ -I /usr/lib/gcc-cross/arm-linux-gnueabihf/10/include/ -stdlib=libc++  -std=gnu++17 -o CMakeFiles/cmTC_f848c.dir/cm_cxx_make_unique.cxx.o -c /tmp/cmake-3.19.3/Source/Checks/cm_cxx_make_unique.cxx
clang-12: warning: argument unused during compilation: '-stdlib=libc++' [-Wunused-command-line-argument]
Linking CXX executable cmTC_f848c
/usr/local/bin/cmake -E cmake_link_script CMakeFiles/cmTC_f848c.dir/link.txt --verbose=1
/opt/llvm_lto_better/bin/clang++ --target=arm-linux-gnueabihf -nostdinc -nostdinc++ -I /opt/armhf_initial/include/c++/v1/ -I /usr/arm-linux-gnueabihf/include/ -I /usr/lib/gcc-cross/arm-linux-gnueabihf/10/include/ -stdlib=libc++  --target=arm-linux-gnueabihf -L /usr/arm-linux-gnueabihf/lib/ -L /opt/armhf_initial/lib -stdlib=libc++ -fuse-ld=lld -lunwind -Wl,--as-needed  CMakeFiles/cmTC_f848c.dir/cm_cxx_make_unique.cxx.o -o cmTC_f848c
clang-12: warning: argument unused during compilation: '-nostdinc' [-Wunused-command-line-argument]
clang-12: warning: argument unused during compilation: '-nostdinc++' [-Wunused-command-line-argument]
make[1]: Leaving directory '/tmp/cmake-3.19.3/b/CMakeFiles/CMakeTmp'

The thing is that the compilation is succesful. The output file cmTC_f848c exists, I can also reproduce the steps by copy pasting them from log and again - it builds. Of course I can’t run the executable on my host for obvious reasons.

$ ./cmTC_f848c
-bash: ./cmTC_f848c: cannot execute binary file: Exec format error

My CXXFLAGS are

--target=arm-linux-gnueabihf -nostdinc -nostdinc++ -I /opt/armhf_initial/include/c++/v1/ -I /usr/arm-linux-gnueabihf/include/ -I /usr/lib/gcc-cross/arm-linux-gnueabihf/10/include/ -stdlib=libc++

CFLAGS

--target=arm-linux-gnueabihf -nostdinc -I /usr/arm-linux-gnueabihf/include/ -I /usr/lib/gcc-cross/arm-linux-gnueabihf/10/include/

LDFLAGS

--target=arm-linux-gnueabihf -L /usr/arm-linux-gnueabihf/lib/ -L /opt/armhf_initial/lib -stdlib=libc++ -fuse-ld=lld -lunwind -Wl,--as-needed

Why CMake thinks that my toolchain is broken? Is it because it tries to run it for whatever reason?

CMake Error: TRY_RUN() invoked in cross-compiling mode

It turned out that adding -DCMake_HAVE_CXX_MAKE_UNIQUE=1 -DCMake_HAVE_CXX_FILESYSTEM=1 worked. But why did cmake initally fail? How come it tried to execute the built binary?

I have not tried for a while, but crosscompiling CMake was relatively easy if
you pass a proper toolchain file.

True, I did it before with the specialized gcc. But clang should work also, and I have no clue why it does not. I already crosscompiled countless projects using it.

Well, i checked Source/Checks/cm_cxx_features.cmake and the answer for failing lies there. Configuration steps fails cause there are just a couple of warnings that match if(check_output MATCHES "(^|[ :])[Ww][Aa][Rr][Nn][Ii][Nn][Gg]") and that’s the reason…

I’ve added -Wno-unused-command-line-argument to my C/CXXFLAGS as a temporary hack and it works and builds the CMake. I understand that the problem comes from the fact that linking is using both CXXFLAGS and LDFLAGS but the flags controling standard include paths are ignored during linking, emitting a warning. But I need them badly in CXXFLAGS to properly set up my cross-toolchain.