使用一个已经存在的动态库,需要用到CMake中两个命令,分别是:
- link_directories
- target_link_libraries
下面先介绍以下两个命令的格式及其含义,最后是一个使用已存在动态库的例子。
一、link_directories 链接库目录
为一个对象或者依赖项指定一个存放库的目录或标志,其基本格式是:
link_directories([AFTER|BEFORE] directory1 [directory2 ...])
与之前include_directories
一样,可以向已经存在的库目录列表向前或者向后追加。目录可以是多个,空格隔开,同样支持绝对路径和相对路径(相对路径的前缀是变量CMAKE_CURRENT_SOURCE_DIR
,也就是当前CMakeLists.txt所在)
Tips:如果有其他选择,应该尽量避免link_directories
,实在无法避免使用绝对路径增加工程的可移植性。绝对路径可以配合find_library()
+target_link_libraries()
二、target_link_libraries
该命令用于链接目标或者其依赖项时的库或者标志。语法定义如下:
target_link_libraries(<target> ... <item>... ...)
-
<target>
变量必须由add_excutable()
或者add_library()
创建,不能是别名目标 -
<item>
形式有多种,见下面解释
对于每一个item可以是以下几种形式:
- 一个目标库名字。CMake编译系统将会获得这个库的完整路径,一旦库的内容发生改变,cmake将会捕捉到这一信息,将变化更新到程序中。目标库的来源只能是两个:1.
add_library
命令创建的库对应变量名 2.IMPORTED的由外部编译的库
IMPORTED是用来表示对象是否为已经存在依赖。一个已经存在的对象,意味着它是由其他别的什么项目生成的,我们只需要使用它,而不需要负责去编译它。一旦一个对象被声明为“被导入”的,那么可以通过控制一系列的命令继续向这个已经存在的库传递信息,如:包含目录、目标编译选项和连接库。如果这个IMPORTED对象被指定了
IMPORTED_NO_SONAME
选项,那么cmake将会去搜索它,而不是用绝对路径去找它(如:/usr/lib/libfoo.so
变成lfoo
)
- 一个完整的带路径的库文件。和使用目标库一样,编译系统将会获得完整路径,一旦库发生变化,功能将会重新链接一份最新的库。有些时候,就算是给定一个完整路径,也会去搜索库(也就是
/usr/lib/libfoo.so
变成了-lfoo
) - 一个普通的库名。编译器将会直接去搜索这个库,注意:我们不需要额外的引号或者其他转移符号。如:库名为
foo
,编译器将会去找动态库或者静态库。 - 一个链接标记。这个项将会以
-
开头,但非-l
或者-framework
,将会被当成链接标志。 - 一个表达式生成器。一个表达式生成器
$<...>
三、例子
project(Demo)
cmake_minimum_required(VERSION 3.15)
include_directories(../libCreate)
link_directories("../libCreate")
add_executable(Demo main.cpp)
target_link_libraries(Demo Fun)