Error when crosscompiling with WHOLE_ARCHIVE target link.

Hello all,
I’ve a problem linking libraries using the WHOLE_ARCHIVE generator feature when using cross compilation toolchains.

Here is it my toolchain file

# Toolchain File for the arm-none-eabi GCC Compiler
set(TOOLCHAIN_NAME "gcc-arm-none-eabi")
set(CMAKE_SYSTEM_NAME Generic-ELF)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(TRIPLET arm-none-eabi)

set(CMAKE_C_COMPILER ${TRIPLET}-gcc)
set(CMAKE_ASM_COMPILER ${TRIPLET}-gcc)
set(CMAKE_CXX_COMPILER ${TRIPLET}-g++)

set(GCC_MIN_VERSION 11.2.1)

# Perform compiler test with static library
set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs")

And the simplest CMakeLists.txt I could come up with to trigger the issue

cmake_minimum_required(VERSION 3.27)

project("TEST")
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED True)

add_executable(exp exp.cpp)

add_library(test STATIC test.c)
add_executable(main main.cpp)
target_link_libraries(main "$<LINK_LIBRARY:WHOLE_ARCHIVE,test>")

I get the following error

[cmake] Not searching for unused variables given on the command line.
[cmake] -- The C compiler identification is GNU 11.2.1
[cmake] -- The CXX compiler identification is GNU 11.2.1
[cmake] -- Detecting C compiler ABI info
[cmake] -- Detecting C compiler ABI info - done
[cmake] -- Check for working C compiler: C:/Program Files/Arm GNU Toolchain arm-none-eabi/11.2 2022.02/bin/arm-none-eabi-gcc.exe - skipped
[cmake] -- Detecting C compile features
[cmake] -- Detecting C compile features - done
[cmake] -- Detecting CXX compiler ABI info
[cmake] -- Detecting CXX compiler ABI info - done
[cmake] -- Check for working CXX compiler: C:/Program Files/Arm GNU Toolchain arm-none-eabi/11.2 2022.02/bin/arm-none-eabi-g++.exe - skipped
[cmake] -- Detecting CXX compile features
[cmake] -- Detecting CXX compile features - done
[cmake] -- Configuring done (4.0s)
[cmake] CMake Error at CMakeLists.txt:10 (add_executable):
[cmake]   Feature 'WHOLE_ARCHIVE', specified through generator-expression
[cmake]   '$<LINK_LIBRARY>' to link target 'main', is not supported for the 'CXX'
[cmake]   link language.
[cmake] 
[cmake] 
[cmake] -- Generating done (0.1s)

This works fine when I comment out CMAKE_SYSTEM_NAME and CMAKE_SYSTEM_NAME, but the documentation tells that these value should be set at the right value.
What am I doing wrong?

Thanks

The feature is only defined on well known platforms by CMake. So, for any other platforms, especially when you define a toolchain file, the feature is not defined. The main reason is the fact this feature depends on linker capabilities and, in case of a toolchain, CMake have no idea of the capabilities of the linker used.

But, you can easily define this feature by setting variables CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE and CMAKE_LINK_LIBRARY_USING_WHOLE_ARCGIVE_SUPPORTED.

That makes sense …
Changing the toolchain file as following it configures and compiles properly.

# Toolchain File for the arm-none-eabi GCC Compiler
set(TOOLCHAIN_NAME "gcc-arm-none-eabi")
set(CMAKE_SYSTEM_NAME Generic-ELF)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(TRIPLET arm-none-eabi)

set(CMAKE_C_COMPILER ${TRIPLET}-gcc)
set(CMAKE_ASM_COMPILER ${TRIPLET}-gcc)
set(CMAKE_CXX_COMPILER ${TRIPLET}-g++)

set(GCC_MIN_VERSION 11.2.1)

# Perform compiler test with static library
set(CMAKE_EXE_LINKER_FLAGS_INIT "--specs=nosys.specs")
set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE 
"-Wl,--whole-archive <LIBRARY> -Wl,--no-whole-archive"
)
set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE_SUPPORTED True)

Thanks for the fast reply.

1 Like

To enable a better generation, I suggest the following definition:

set(CMAKE_LINK_LIBRARY_USING_WHOLE_ARCHIVE 
"-Wl,--whole-archive" "<LINK_ITEM>" "-Wl,--no-whole-archive"
)

Specifying the expression as a list will avoid unnecessary keyword repetition: $<LINK_LIBRARY:WHOLE_ARCHIVE,target1,target2> will be generated as -Wl,--whole-archive /path/to/lib1 /path/to/lib2 -Wl,--no-whole-archive.
And <LINK_ITEM> ensure correct generation for targets as well as external libraries.

For more information, have a look at CMAKE_LINK_LIBRARY_USING_<FEATURE>.

Thanks.