【问题标题】:CMake: How can I build a shared and a static library without recompiling the sources twiceCMake:如何在不重新编译源代码的情况下构建共享库和静态库
【发布时间】:2012-10-05 15:51:16
【问题描述】:

我想为Is it possible to get CMake to build both a static and shared version of the same library? 描述的同一库构建静态版本和共享版本

但是,源代码被编译两次,每个版本编译一次,这不是必需的。有什么办法可以避免吗?

目前我有:

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

add_library(${LIB}_static STATIC ${${LIB}_srcs})

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

【问题讨论】:

  • 这不是不同的编译器设置吗?我知道在 Visual Studio 上你肯定需要编译这 2 次(因为 dll 与静态库会有不同的编译器、链接器设置和定义)但是我不确定 gcc。
  • @drescherjm,在 Linux/Solaris 等上,您必须编译共享库对象文件以定位独立代码 - 使用 GCC/Solaris Studio/Clang 等,您提供 -fpic/-fPIC 来归档它。参照。我的回答。

标签: compilation cmake


【解决方案1】:

unfeasible and not recommended 从同一组目标文件创建共享/静态库版本 - 至少在许多平台上。

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

【讨论】:

  • 您陈述的第一部分是正确的:共享库需要 PIC。第二部分不是:您可以从 PIC 目标文件构建一个静态存档。从相同的目标文件构建静态和共享库时,只需确保使用 PIC。在 CMake 中:set_property(TARGET ${objs} PROPERTY POSITION_INDEPENDENT_CODE 1) 其中${objs} 是对象库的名称。详情请查看 Alexey 答案中的链接。
  • @user465139,我已经更新了我的答案并删除了“不可能”部分。
【解决方案2】:

【讨论】:

  • 这个答案令人担忧,因为它没有指出使用 位置无关代码 编译静态库和共享库会降低静态库的运行时性能版本!请参阅 [this anwer]。
猜你喜欢
  • 1970-01-01
  • 2018-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多