CMake:如何在不重新编译源的情况下构建共享库和静态库

use*_*549 12 compilation cmake

我想构建所描述的相同库的静态和共享版本是否有可能让CMake构建同一个库的静态和共享版本?

但是,源代码被编译两次,每个版本一个,这是不必要的.有什么方法可以避免这种情况吗?

目前我有:

add_library(${LIB} SHARED ${${LIB}_srcs})

add_library(${LIB}_static STATIC ${${LIB}_srcs})
Run Code Online (Sandbox Code Playgroud)

为了只需要编译一次,我需要更改什么?仅供参考.我有相同的编译器标志和定义.

max*_*zig 8

这是不可行的,不建议从同一组目标文件创建共享/静态库版本 - 至少在许多平台上.

链接到共享库的目标文件必须编译为位置无关的代码(-fpic/ -FPIC在Linux/Solaris等上) - 而您的可执行文件和静态库(通常)不包含与位置无关的代码.另一方面,由于间接性,共享库通过运行时开销来共享代码页.由于这些间接对于静态库和二进制文件是不必要的,因此位置无关代码仅提供了与thoses相关的缺点.因此,如果要创建共享库和静态库版本,则需要创建两组不同的目标文件(一组与位置无关,另一组则相反).

  • 您的陈述的第一部分是正确的:共享库需要PIC.第二部分不是:您可以从PIC对象文件中构建静态存档.从同一对象文件构建静态和共享库时,只需确保使用PIC.在CMake中:`set_property(TARGET $ {objs} PROPERTY POSITION_INDEPENDENT_CODE 1)`其中`$ {objs}`是对象库的名称.有关详细信息,请查看Alexey的答案中的链接. (2认同)

Ale*_*xey 5

从CMake 2.8.8开始,您可以使用对象库:CMake:将为lib构建的对象文件重用到另一个lib目标中.

另见http://www.cmake.org/Wiki/CMake/Tutorials/Object_Library

  • 这个答案是令人不安的,因为它没有指出使用*位置无关代码*编译静态和共享库,你会对静态版本产生运行时性能损失!请改为查看[this anwer]. (2认同)