Chr*_*uns 117
是的,这很容易.只需使用两个"add_library"命令:
add_library(MyLib SHARED source1.c source2.c)
add_library(MyLibStatic STATIC source1.c source2.c)
Run Code Online (Sandbox Code Playgroud)
即使您有许多源文件,也可以将源列表放在cmake变量中,因此它仍然很容易.
在Windows上,您应该为每个库指定一个不同的名称,因为共享和静态都有一个".lib"文件.但是在Linux和Mac上,您甚至可以为两个库提供相同的名称(例如libMyLib.a和libMyLib.so):
set_target_properties(MyLibStatic PROPERTIES OUTPUT_NAME MyLib)
Run Code Online (Sandbox Code Playgroud)
但我不建议同时给出库的静态和动态版本.我更喜欢使用不同的名称,因为这样可以更容易地在编译行上为链接到库的工具选择静态与动态链接.通常我选择libMyLib.so(共享)和libMyLib_static.a(静态)之类的名称.(那些将是linux上的名字.)
Lar*_*dua 80
从CMake版本2.8.8开始,您可以使用"对象库" 来避免重复编译目标文件.使用Christopher Bruns的两个源文件库的示例:
# list of source files
set(libsrc source1.c source2.c)
# this is the "object library" target: compiles the sources only once
add_library(objlib OBJECT ${libsrc})
# shared libraries need PIC
set_property(TARGET objlib PROPERTY POSITION_INDEPENDENT_CODE 1)
# shared and static libraries built from the same object files
add_library(MyLib_shared SHARED $<TARGET_OBJECTS:objlib>)
add_library(MyLib_static STATIC $<TARGET_OBJECTS:objlib>)
Run Code Online (Sandbox Code Playgroud)
来自CMake文档:
对象库编译源文件,但不将其目标文件存档或链接到库中.而是使用表单的表达式作为源创建
add_library()或者add_executable()可以引用对象的其他目标$<TARGET_OBJECTS:objlib>,其中objlib是对象库名称.
简单地说,该add_library(objlib OBJECT ${libsrc})命令指示CMake将源文件编译为*.o目标文件.*.o然后,$<TARGET_OBJECT:objlib>在两个add_library(...)命令中引用此文件集合,这两个命令调用相应的库创建命令,这些命令从同一组目标文件构建共享库和静态库.如果你有很多源文件,那么编译*.o文件可能需要很长时间; 使用对象库只需编译一次.
您支付的价格是必须将目标文件构建为与位置无关的代码,因为共享库需要这样(静态库不关心).请注意,与位置无关的代码可能效率较低,因此如果您的目标是获得最大性能,那么您将选择静态库.此外,分发静态链接的可执行文件更容易.
小智 23
通常无需为您的目的复制ADD_LIBRARY调用.只是利用
$> man cmake | grep -A6 '^ *BUILD_SHARED_LIBS$'
BUILD_SHARED_LIBS
Global flag to cause add_library to create shared libraries if on.
If present and true, this will cause all libraries to be built shared unless the library was
explicitly added as a static library. This variable is often added to projects as an OPTION
so that each user of a project can decide if they want to build the project using shared or
static libraries.
Run Code Online (Sandbox Code Playgroud)
使用-DBUILD_SHARED_LIBS构建第一个(在一个源外目录中):BOOL = ON并在另一个中使用OFF
请注意,以前的答案不适用于MSVC:
add_library(test SHARED ${SOURCES})
add_library(testStatic STATIC ${SOURCES})
set_target_properties(testStatic PROPERTIES OUTPUT_NAME test)
Run Code Online (Sandbox Code Playgroud)
CMake 将与目标test.dll一起创建。它将在同一目录中为目标创建并替换前一个目录。如果您尝试将某些可执行文件与目标链接,它将失败并出现如下错误:test.libtest.expsharedtest.libstaticshared
error LNK2001: unresolved external symbol __impl_*.`.
Run Code Online (Sandbox Code Playgroud)
请ARCHIVE_OUTPUT_DIRECTORY为目标使用并使用一些唯一的输出目录static:
add_library(test SHARED ${SOURCES})
add_library(testStatic STATIC ${SOURCES})
set_target_properties(
testStatic PROPERTIES
OUTPUT_NAME test
ARCHIVE_OUTPUT_DIRECTORY testStatic
)
Run Code Online (Sandbox Code Playgroud)
test.lib将在目录中创建testStatic并且不会test.lib从test目标覆盖。它与 完美配合MSVC。
| 归档时间: |
|
| 查看次数: |
64396 次 |
| 最近记录: |