如何让 CMake 动态地 link 一个与系统库合并的静态库?
How do I get CMake to dynamically link a merged static library with system libraries?
我必须使用这个可怕的 CMake 代码将我的一个应用程序库与 NVIDIA CUDA 静态库合并:
GET_TARGET_PROPERTY(OUTPUT_LIB ${LIBNAME} LOCATION)
add_custom_command (TARGET ${LIBNAME}
POST_BUILD
COMMAND mv ${OUTPUT_LIB} ${OUTPUT_LIB}.old
COMMAND echo "create ${OUTPUT_LIB}" > combineLibs.mri
COMMAND echo "addlib ${OUTPUT_LIB}.old" >> combineLibs.mri
COMMAND echo "addlib ${CUDA_LOCATION}" >> combineLibs.mri
COMMAND echo "save" >> combineLibs.mri
COMMAND echo "end" >> combineLibs.mri
COMMAND ar -M <combineLibs.mri
COMMAND rm ${OUTPUT_LIB}.old
COMMENT "Building merged library for ${LIBNAME} at ${OUTPUT_LIB}, including ${CUDA_LOCATION}"
)
target_link_libraries(${LIBNAME} -pthread -c)
这成功生成了一个包含所有符号的合并静态库。然而,NVIDIA CUDA 静态库以未解析符号的形式带来了对 libpthread 和 libc 的依赖。现在合并后的库也有那些未解析的符号,target_link_libraries
行似乎并没有像我认为的那样做,因为这些符号在 link 时没有被解析。如何让合并的静态库动态地 link 针对 libpthread 和 libc?
the target_link_libraries
行确实不是你想的那样。
target_link_libraries(
target,
options)
可以达到想要的效果
仅当 target
是 linker 制作的东西。如果没有 linkage 发生在
生成 target 则此指令将无效。
您的目标是一个静态库。静态库——不像程序,也不像
dynamic/shared 库 - 不是由 linker 制作的。作为你的 custom_command
事实上说明,静态库是由 GNU 通用归档程序生成的,
ar
。它只不过是恰好是目标文件的文件存档,
但就 ar
而言,它们也可能是您的内容
文档、图片和音乐文件夹。由于没有 linkage 参与其中
生成静态库,什么都不能用静态库link编辑。
ar
存档可以用作 linker input 在 linkage 的东西
是 由 linker 制作的 - 程序或共享库。在那种情况下
linker 将查看存档以查看是否包含它需要的任何目标文件
继续 link 年龄。如果找到任何内容,它将从存档中提取它们
和 link 他们 进入程序。 linkage 将与 if 完全相同
您已经在 linker 命令行中列出了所需的目标文件,而不是
完全提到了存档。
但是如果 linker 从存档中提取的任何目标文件带来
与他们未定义的参考,然后让他们解决你必须 link 一些
在link时代定义这些引用的一个或多个图书馆
您希望 linker 制作 的程序或共享库 - 就像您一样
必须解决您在任何其他目标文件中的未定义引用
输入 linkage.
所以,
How do I get the merged static library to dynamically link against libpthread and libc?
你不能。这没有意义。目标文件的任何库依赖性
在静态库中只能在 link 程序或共享库 的年龄得到满足
通过 linking 这些目标文件获得了这些依赖关系。
最后,-c
不是 GCC linkage 选项,会产生请求的效果
linklibc
岁。它根本不是 linkage 选项。这是一个选项
指示 GCC 前端 not 调用 linker。它被传递给 GCC 以
请求没有 linkage 的编译,以及将其包含在
CMake target_link_libraries
指令将停止任何 linkage 的
目标发生。
如果要明确请求linklibc
的年龄,请使用-lc
,如下
linker 使用协议,-lname
请求 link年龄 libname
。
也许您从假设中推断出 -c
要求 linklibc
的年龄
-pthread
请求 link 年龄 libpthread
。事实上,-lpthread
会
请求 linklibpthread
的年龄。选项 -pthread
是一个更抽象的 GCC
选项,对于编译和 linkage,这意味着 做正确的事情,对于这个平台,link 与 Posix 线程
library - 这可能需要将 -lpthead
传递给 linker,也可能不需要。
因此 -pthread
是 可以作为 target_link_libraries
的参数
具有请求 Posix 线程 linkage 的效果,但请参阅
cmake and libpthread 的答案
对于 CMake 的正确方法。
我必须使用这个可怕的 CMake 代码将我的一个应用程序库与 NVIDIA CUDA 静态库合并:
GET_TARGET_PROPERTY(OUTPUT_LIB ${LIBNAME} LOCATION)
add_custom_command (TARGET ${LIBNAME}
POST_BUILD
COMMAND mv ${OUTPUT_LIB} ${OUTPUT_LIB}.old
COMMAND echo "create ${OUTPUT_LIB}" > combineLibs.mri
COMMAND echo "addlib ${OUTPUT_LIB}.old" >> combineLibs.mri
COMMAND echo "addlib ${CUDA_LOCATION}" >> combineLibs.mri
COMMAND echo "save" >> combineLibs.mri
COMMAND echo "end" >> combineLibs.mri
COMMAND ar -M <combineLibs.mri
COMMAND rm ${OUTPUT_LIB}.old
COMMENT "Building merged library for ${LIBNAME} at ${OUTPUT_LIB}, including ${CUDA_LOCATION}"
)
target_link_libraries(${LIBNAME} -pthread -c)
这成功生成了一个包含所有符号的合并静态库。然而,NVIDIA CUDA 静态库以未解析符号的形式带来了对 libpthread 和 libc 的依赖。现在合并后的库也有那些未解析的符号,target_link_libraries
行似乎并没有像我认为的那样做,因为这些符号在 link 时没有被解析。如何让合并的静态库动态地 link 针对 libpthread 和 libc?
the target_link_libraries
行确实不是你想的那样。
target_link_libraries(
target,
options)
可以达到想要的效果
仅当 target
是 linker 制作的东西。如果没有 linkage 发生在
生成 target 则此指令将无效。
您的目标是一个静态库。静态库——不像程序,也不像
dynamic/shared 库 - 不是由 linker 制作的。作为你的 custom_command
事实上说明,静态库是由 GNU 通用归档程序生成的,
ar
。它只不过是恰好是目标文件的文件存档,
但就 ar
而言,它们也可能是您的内容
文档、图片和音乐文件夹。由于没有 linkage 参与其中
生成静态库,什么都不能用静态库link编辑。
ar
存档可以用作 linker input 在 linkage 的东西
是 由 linker 制作的 - 程序或共享库。在那种情况下
linker 将查看存档以查看是否包含它需要的任何目标文件
继续 link 年龄。如果找到任何内容,它将从存档中提取它们
和 link 他们 进入程序。 linkage 将与 if 完全相同
您已经在 linker 命令行中列出了所需的目标文件,而不是
完全提到了存档。
但是如果 linker 从存档中提取的任何目标文件带来 与他们未定义的参考,然后让他们解决你必须 link 一些 在link时代定义这些引用的一个或多个图书馆 您希望 linker 制作 的程序或共享库 - 就像您一样 必须解决您在任何其他目标文件中的未定义引用 输入 linkage.
所以,
How do I get the merged static library to dynamically link against libpthread and libc?
你不能。这没有意义。目标文件的任何库依赖性 在静态库中只能在 link 程序或共享库 的年龄得到满足 通过 linking 这些目标文件获得了这些依赖关系。
最后,-c
不是 GCC linkage 选项,会产生请求的效果
linklibc
岁。它根本不是 linkage 选项。这是一个选项
指示 GCC 前端 not 调用 linker。它被传递给 GCC 以
请求没有 linkage 的编译,以及将其包含在
CMake target_link_libraries
指令将停止任何 linkage 的
目标发生。
如果要明确请求linklibc
的年龄,请使用-lc
,如下
linker 使用协议,-lname
请求 link年龄 libname
。
也许您从假设中推断出 -c
要求 linklibc
的年龄
-pthread
请求 link 年龄 libpthread
。事实上,-lpthread
会
请求 linklibpthread
的年龄。选项 -pthread
是一个更抽象的 GCC
选项,对于编译和 linkage,这意味着 做正确的事情,对于这个平台,link 与 Posix 线程
library - 这可能需要将 -lpthead
传递给 linker,也可能不需要。
因此 -pthread
是 可以作为 target_link_libraries
的参数
具有请求 Posix 线程 linkage 的效果,但请参阅
cmake and libpthread 的答案
对于 CMake 的正确方法。