Dei*_*mos 50 cmake shared-libraries
我有以下布局:
top_project
+ subproject1
+ subproject2
Run Code Online (Sandbox Code Playgroud)
每个subproject1并subproject2创建一个静态库.我想在这个top_project级别的单个共享库中链接这些静态库.
我到目前为止收集的信息是:
-fPic(除了Windows之外的所有内容)进行编译以创建与位置无关的代码,这将允许将静态库链接到单个共享库或解压缩所有静态库(例如使用ar)并将它们重新链接到共享库(其中我认为这是一个不优雅和不便携的解决方案)add_library命令:由于某些我无法理解的原因,简单地写入add_library(${PROJECT_NAME} SHARED subproject1 subproject2)不能按预期工作(它实际上创建了一个空库并且没有正确地注册依赖项)有什么想法吗?
Dei*_*mos 32
好吧,我明白了:这比它应该更痛苦.直到最近,Kitware的人才不理解为什么有人想要从静态库创建DLL.他们的论点是主要(例如top_project在我的情况下)目录中应该始终存在源文件,因为它实际上是它自己的项目.我看到不同的东西,我需要top_project分成不应该独立存在的较小的子项目(即没有必要为它们创建一个完整的项目并使用它们添加它们ExternalProject_Add).此外,当我运送我的共享库(供使用,例如使用Java Native Interface)时,我不想发送数十个共享库,因为这相当于暴露了我的项目的内部布局.无论如何,我想 - 从静态库创建一个共享库,我将继续讨论技术细节.
在的的CMakeLists.txt subproject1和subproject2,你应该使用对象库功能(在CMake的2.8.8中引入)创建目标:
add_library(${PROJECT_NAME} OBJECT ${SRC})
Run Code Online (Sandbox Code Playgroud)
其中SRC指定源文件列表(请注意,这些文件应在CMakeLists.txt文件中明确设置,因为它允许make在检测到CMakeLists.txt的修改时重新启动CMake,例如添加或删除文件时)
在top_project,使用以下命令添加子项目:
add_subdirectory(subproject1)
add_subdirectory(subproject2)
Run Code Online (Sandbox Code Playgroud)
要查看静态库中的符号,请使用:
set(CMAKE_SHARED_LINKER_FLAGS "-Wl,--export-all-symbols")
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用以下命令创建共享库:
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:subproject1>
$<TARGET_OBJECTS:subproject2>)
Run Code Online (Sandbox Code Playgroud)
我发现任何"普通"库(即非对象)都需要在一个单独的add_library命令中添加,否则就会被忽略.
对于可执行文件,您可以使用:
add_executable(name_of_executable $<TARGET_OBJECTS:subproject1>
$<TARGET_OBJECTS:subproject2>)
set(LINK_FLAGS ${LINK_FLAGS} "-Wl,-whole-archive")
target_link_libraries(name_of_executable ${PROJECT_NAME}
Run Code Online (Sandbox Code Playgroud)
我再说一遍,这只适用于CMake的2.8.8版本.同样,CMake非常好地管理依赖关系并且是跨平台的,因为它比简单的旧Makefile并不那么痛苦,当然也不那么灵活.
我的解决方案只是添加/WHOLEARCHIVE,-all_load或添加--whole-archive到链接器标志,以便在链接主库时,包括所有子库,包括它们的所有符号(默认行为是仅包含子库的符号)主库使用.例如:
$ echo "void Func1() { }" > source1.cpp
$ echo "void Func2() { }" > source2.cpp
$ echo "void Func3() { }" > source3.cpp
$ echo "void Func4() { }" > source4.cpp
Run Code Online (Sandbox Code Playgroud)
cmake_minimum_required(VERSION 3.7)
# The 'sub' libraries, e.g. from an `add_subdirectory()` call.
add_library(sublib_a STATIC source1.cpp source2.cpp)
add_library(sublib_b STATIC source3.cpp source4.cpp)
# The main library that contains all of the sub libraries.
add_library(mainlib SHARED)
target_link_libraries(mainlib sublib_a sublib_b)
Run Code Online (Sandbox Code Playgroud)
运行它(在OSX上):
$ make VERBOSE=1
...
[100%] Linking CXX shared library libmainlib.dylib
/usr/local/Cellar/cmake/3.7.1/bin/cmake -E cmake_link_script CMakeFiles/mainlib.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/c++ -dynamiclib -Wl,-headerpad_max_install_names -o libmainlib.dylib -install_name @rpath/libmainlib.dylib libsublib_a.a libsublib_b.a
[100%] Built target mainlib
$ nm libmainlib.dylib | grep Func
$
Run Code Online (Sandbox Code Playgroud)
附加:
# By default, symbols provided by the sublibs that are not used by mainlib (which is all of them in this case)
# are not used. This changes that.
if (WIN32)
set_target_properties(mainlib PROPERTIES
LINK_FLAGS "/WHOLEARCHIVE"
)
elseif (APPLE)
set_target_properties(mainlib PROPERTIES
LINK_FLAGS "-Wl,-all_load"
)
else ()
set_target_properties(mainlib PROPERTIES
LINK_FLAGS "-Wl,--whole-archive"
)
endif ()
Run Code Online (Sandbox Code Playgroud)
运行它(注意额外-all_load):
$ make VERBOSE=1
[100%] Linking CXX shared library libmainlib.dylib
/usr/local/Cellar/cmake/3.7.1/bin/cmake -E cmake_link_script CMakeFiles/mainlib.dir/link.txt --verbose=1
/Library/Developer/CommandLineTools/usr/bin/c++ -dynamiclib -Wl,-headerpad_max_install_names -Wl,-all_load -o libmainlib.dylib -install_name @rpath/libmainlib.dylib libsublib_a.a libsublib_b.a
[100%] Built target mainlib
$ nm libmainlib.dylib | grep Func
0000000000001da0 T __Z5Func1v
0000000000001db0 T __Z5Func2v
0000000000001dc0 T __Z5Func3v
0000000000001dd0 T __Z5Func4v
Run Code Online (Sandbox Code Playgroud)
请注意,-all_load到目前为止我只进行了实际测试,并且/WHOLEARCHIVE是MSVC 2015选项.
| 归档时间: |
|
| 查看次数: |
40331 次 |
| 最近记录: |