Cmake issues with clang and overwritten stdenv

I am working on a C++ project which is based on CMake. Thanks to nix, I can easily check that it builds with different compilers with the help of overrideCC. Recently, I wanted to enable LTO and use CMake’s CheckIPOSupport to figure out whether the current compiler supports LTO. While this is fine when clang and gcc are directly used as buildInputs, it breaks for clang with the overrideCC approach:

projectWithClang = with pkgs; projectWithGcc.override {
    # This override breaks LTO detection
    stdenv = pkgs.overrideCC stdenv clang_9;

I set up a minimal example for reproducing the problem here: GitHub - jtraue/nix-cmake-lto-support: Minimal demo project for reproducing nix cmake build problem

The build fails when CMake tries to detect IPO support. Under the hood, a minimal project (foo) is set up, compiled and then linked with -flto. This is where it breaks:

 [3/4] Linking CXX static library libfoo.a

  FAILED: libfoo.a

  : && /nix/store/yvq7zkvkmycdg22l4lsr4nn20174gi74-cmake-3.16.3/bin/cmake -E
  remove libfoo.a && "CMAKE_CXX_COMPILER_AR-NOTFOUND" cr libfoo.a
  CMakeFiles/foo.dir/foo.cpp.o && "CMAKE_CXX_COMPILER_RANLIB-NOTFOUND"
  libfoo.a && :

It seems like CMake is unable to find ar and ranlib. So there is probably something wrong with the overrideCC approach. Does anyone know how to fix the problem?

I received a hint on another channel and the fix is:
stdenv = pkgs.overrideCC stdenv [ clang_9 llvmPackages_9.llvm ];

1 Like