cmakemakefilewindows-subsystem-for-linuxld-preload

How to invoke compiler with LD_PRELOAD in CMake


Is it possible to have CMake “export an environment variable” such as LD_PRELOAD before invoking a compiler/linker like you could in a shell?

I am building several projects in WSL2 with one of them using an old 32-bit cross-compiler. The source files are on Windows filesystem mounted into WSL, where the inodes are 64-bit thus not supported and cannot be read by the 32-bit compiler.

cc1plus: error: /mydir/.../source.cpp: Value too large for defined data type

I followed instructions from The 64 bit inode problem, built the inode64.so and manually verified it worked with the 32-bit cross-compiler in a shell:

export LD_PRELOAD=/mydir/.../inode64.so
arm-fsl-linux-gnueabi-g++ source.cpp

My question is, since I am building the projects with CMake, how can I invoke ONLY the 32-bit compiler/linker from CMake with

LD_PRELOAD=/mydir/.../inode64.so

In my project build script, I tried export LD_PRELOAD before calling cmake, but it didn't work (because the 32-bit .so doesn't work with native 64-bit cmake tools?)

cmake ./
export LD_PRELOAD=/mydir/.../inode64.so
make install
ERROR: ld.so: object '/mydir/.../inode64.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS32): ignored.

Solution

  • Set the variable CMAKE_CXX_COMPILER_LAUNCHER to env LD_PRELOAD=whatever.so. This will use the env command to launch the compiler.

    The variable is used to initialize target properties, and of 3.25 supports generator expressions, so if you are using multiple compilers in the same build, you can wrap the env command in a test for compiler version or compiler name.

    If instead you are using this compiler for all c++ builds in a particular configuration, just conditionally set the variable:

    if(MY_CROSS_COMPILING_32_BIT)
        set(CMAKE_CXX_COMPILER_LAUNCHER env LD_PRELOAD=whatever.so)
    endif()