CMake 无法检测不同静态库中的符号冲突
CMake cannot detect symbol conflicts in different static libraries
我创建了一个简单的 cmake 项目来重现它。
├── 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
)
在lib1.cpp中有一个函数"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
)
而在lib2/lib2.cpp中,有一个相同签名的函数:
#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
)
这里是 main.cpp:
void say();
int main()
{
say();
return 0;
}
输出:
hello from lib1
没有编译或link错误,甚至没有警告。
linker 只是选择了一个而忽略了另一个。
我正在使用 cmake 3.16,并使用 msvc 2017/2019 和 g++ 7.5 对其进行了测试。
如何让linker在静态库中出现符号冲突时提示错误?
谢谢!
How to make the linker prompts errors when there are symbol conflicts in static libraries?
与 gcc
一起使用 --whole-archive
选项将每个目标文件包含在存档中,而不是在存档中搜索所需的符号。
由于据我所知没有 cmake
支持,我发现通常在链接可执行文件时完成:
target_link_libraries(test2 PRIVATE
-Wl,--whole-archive
lib1
lib2
-Wl,--no-whole-archive
)
"Symbol conflicts" 是一个相当模糊的术语。这只会检测多个符号定义。符号类型在编译后不会存储在任何地方。
我创建了一个简单的 cmake 项目来重现它。
├── 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
)
在lib1.cpp中有一个函数"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
)
而在lib2/lib2.cpp中,有一个相同签名的函数:
#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
)
这里是 main.cpp:
void say();
int main()
{
say();
return 0;
}
输出:
hello from lib1
没有编译或link错误,甚至没有警告。 linker 只是选择了一个而忽略了另一个。 我正在使用 cmake 3.16,并使用 msvc 2017/2019 和 g++ 7.5 对其进行了测试。
如何让linker在静态库中出现符号冲突时提示错误?
谢谢!
How to make the linker prompts errors when there are symbol conflicts in static libraries?
与 gcc
一起使用 --whole-archive
选项将每个目标文件包含在存档中,而不是在存档中搜索所需的符号。
由于据我所知没有 cmake
支持,我发现通常在链接可执行文件时完成:
target_link_libraries(test2 PRIVATE
-Wl,--whole-archive
lib1
lib2
-Wl,--no-whole-archive
)
"Symbol conflicts" 是一个相当模糊的术语。这只会检测多个符号定义。符号类型在编译后不会存储在任何地方。