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!
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.