add_library
是写cmake必备的一个函数,但一直没仔细研究过,今天把它折解下。主要参考
cmake官方文档
add_library(<name> [STATIC | SHARED | MODULE]
[EXCLUDE_FROM_ALL]
[source1] [source2 ...])
添加名为name
的库,库的源文件可指定,也可用target_sources()
后续指定。
库的类型是STATIC(静态库)
/SHARED(动态库)
/MODULE(模块库)
之一。
name
属性必须全局唯一
生成的library名会根据STATIC
或SHARED
成为name.a
或name.lib
这里的STATIC
和SHARED
可不设置,通过全局的BUILD_SHARED_LIBS
的FALSE
或TRUE
来指定
windows下,如果dll没有export任何信息,则不能使用SHARED
,要标识为MODULE
添加的库会被输出到以下几个目录
ARCHIVE_OUTPUT_DIRECTORY
, LIBRARY_OUTPUT_DIRECTORY
和 RUNTIME_OUTPUT_DIRECTORY
,详见cmake 常用设定及函数
设置EXCLUDE_FROM_ALL
,可使这个library排除在all
之外,即必须明确点击生成才会生成
add_library(<name> <SHARED|STATIC|MODULE|OBJECT|UNKNOWN> IMPORTED
[GLOBAL])
这种用法直接导入已经生成的库,cmake不会给这类library添加编译规则。
这种用法的关键在于添加变量IMPORTED
。
另外,GLOBAL
可用于设置这个library为全局可见。
常规和imported的library的属性不同:
INTERFACE_
开头IMPORTED_
开头
INTERFACE_
和IMPORTED_
开头的变量有哪些,参见interface libraries,还需再研究。
imported的library最重要的几个属性是:
IMPORTED_LOCATION
:标明library在硬盘上的位置,可以用更具体的IMPORTED_LOCATION_
的标注,其中的
可以是DEBUG
/RELEASE
或其他IMPORTED_OBJECTS
:标明对象library在硬盘上的位置,相应的有IMPORTED_OBJECTS_
来标识具体编译类型PUBLIC_HEADER
:如果install这个library的话,这个值保存头文件的目录UNKNOWN
类型,在不需要明确library类型时使用。
add_library(<name> OBJECT <src>...)
库的类型固定为OBJECT
,这种库编译了源文件,但不链接。实际中没用过,没有仔细研究。使用方法:
add_library(... $<TARGET_OBJECTS:objlib> ...)
add_executable(... $<TARGET_OBJECTS:objlib> ...)
为给定library添加一个别名,后续可使用
来替代
。
add_library(<name> ALIAS <target>)
使用有如下限制:
不能是ALIAS
ALIAS
的library不能
修改属性,不能调用set_property()
, set_target_properties()
和target_link_libraries()
等方法不能
用于install()
创建一个接口库,
add_library(<name> INTERFACE [IMPORTED [GLOBAL]])
这类库有属性,能install()
,export
和imported
,但可能没有build过程。像纯头文件库
或完全针对target的设计
(这条参见interface libraries)
所有INTERFACE _*
属性从如下几个方法中设置
set_property()
、target_link_libraries(INTERFACE)
、target_link_options(INTERFACE)
、target_include_directories(INTERFACE)
、target_compile_options(INTERFACE)
、target_compile_definitions(INTERFACE)
和target_sources(INTERFACE)
。
参考 cmake引入外部库
静态库
add_library(baz STATIC IMPORTED)
set_target_properties(baz PROPERTIES
IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/libbaz.a
IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/libbazd.a)
静态库(添加依赖项)
add_library(bar STATIC IMPORTED)
set_target_properties(bar PROPERTIES
IMPORTED_LOCATION_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/libbar.a
IMPORTED_LOCATION_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/libbard.a
IMPORTED_LINK_INTERFACE_LIBRARIES baz) # <-- dependency is here
动态库
add_library(bar SHARED IMPORTED)
set_property(TARGET bar PROPERTY IMPORTED_LOCATION c:/path/to/bar.dll)
set_property(TARGET bar PROPERTY IMPORTED_IMPLIB c:/path/to/bar.lib) # 多了lib信息
add_executable(myexe src1.c src2.c)
target_link_libraries(myexe bar)
当然,也可以直接引用库文件
TARGET_LINK_LIBRARIES(skiaSampleCode
debug skiaCored.lib
optimized skiaCore.lib)