Search code examples
c++cmakesymbolsconflict

CMake cannot detect symbol conflicts in different static libraries


I created a simple cmake project to reproduct it.

├── CMakeLists.txt
├── lib1
│   ├── CMakeLists.txt
│   ├── lib1.cpp
│   └── lib1.h
├── lib2
│   ├── CMakeLists.txt
│   ├── lib2.cpp
│   └── lib2.h
└── main.cpp

lib1/CMakeLists.txt:

add_library(lib1 "")
target_include_directories(lib1
  PUBLIC
      ${CMAKE_CURRENT_LIST_DIR}
)
target_sources(lib1
    PRIVATE
        lib1.cpp
        lib1.h
)

In lib1.cpp, there is a function "void say()":

#include <stdio.h>

void say()
{
    printf("hello from lib1\n");
}

lib2/CMakeLists.txt:

add_library(lib2 "")
target_include_directories(lib2
  PUBLIC
      ${CMAKE_CURRENT_LIST_DIR}
)
target_sources(lib2
    PRIVATE
        lib2.cpp
        lib2.h
)

And in lib2/lib2.cpp, there is a function of the same signature:

#include <stdio.h>
void say()
{
    printf("hello from lib2\n");
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
project(shell LANGUAGES CXX)
add_subdirectory(lib1)
add_subdirectory(lib2)
add_executable(test2
  main.cpp
)
target_link_libraries(test2
  PRIVATE
    lib1
    lib2
)

Here is the main.cpp:

void say();
int main()
{
    say();
    return 0;
} 

The output:

hello from lib1

There is no compile or link error, not even a warning. The linker just picked one and symply ignored the other one. I'm using cmake 3.16, and tested it with msvc 2017/2019 and g++ 7.5.

How to make the linker prompts errors when there are symbol conflicts in static libraries?

Thanks!


Solution

  • How to make the linker prompts errors when there are symbol conflicts in static libraries?

    With gcc use the --whole-archive option to include every object file in the archive rather then search the archives for the required symbol.

    As there is no cmake support that I know of, I find it's typically done when linking the executable:

    target_link_libraries(test2 PRIVATE
        -Wl,--whole-archive
        lib1
        lib2
        -Wl,--no-whole-archive
    )
    

    "Symbol conflicts" is rather vague term. This will only detect multiple symbol definitions. Types of symbols are not stored anywhere after compilation.