CMake添加链接目录命令link_directories简介
命令简介
为编译器添加库搜索目录,命令的格式为:
link_directories([AFTER|BEFORE] directory1 [directory2 ...])
要注意的是:该命令调用后,只有这个命令调用之后创建的目标(库、可执行文件等)才会起作用。也就是说已经调用add_executable()或add_library()创建目标后,再调用link_directories()是没有效果的。
该命令会将路径添加到当前CMakeLists.txt文件的目录LINK_DIRECTORIES属性中,
参数选项
-
AFTER或BEFORE
指定添加的目录是追加到搜索目录列表,还是在搜索目录列表的最前面插入,默认是AFTER。也可以通过设置CMAKE_LINK_DIRECTORIES_BEFORE变量为
ON
来达到使用BEFORE选项同样的效果。
示例
在我们的例子中,假设已经有一个test库静态库(名为libtest.a),提供如下接口供使用
void test_print();
目录结构如下:
link_directories/
├── CMakeLists.txt
├── lib
│ └── libtest.a
└── main.cpp
main.cpp的内容如下:
extern void test_print();
int main(int argc, char** argv)
{
test_print();
return 0;
}
-
在可执行文件创建后再包含libtest.a路径
CMakeLists.txt文件内容:
cmake_minimum_required(VERSION 3.22) project(link_directories_test) add_executable(main main.cpp) target_link_libraries(main test) link_directories(lib)
执行
cmake .
和make VERBOSE=1
输出如下:[ 50%] Linking CXX executable main /usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1 /usr/bin/c++ CMakeFiles/main.dir/main.cpp.o -o main -ltest /usr/bin/ld: 找不到 -ltest: 没有那个文件或目录 collect2: error: ld returned 1 exit status
-
在可执行文件前包含libtest.a路径
CMakeLists.txt文件内容:
cmake_minimum_required(VERSION 3.22) project(link_directories_test) link_directories(lib) add_executable(main main.cpp) target_link_libraries(main test)
执行
cmake .
和make VERBOSE=1
输出如下,可以看到-L
已经将对应的目录添加到链接搜索目录中:[ 50%] Linking CXX executable main /usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1 /usr/bin/c++ CMakeFiles/main.dir/main.cpp.o -o main -L/home/shengyi/code/gitee_repo/projects/cmake/link_directories/lib -Wl,-rpath,/XXX/link_directories/lib -ltest
执行
./main
输出结果:$ ./main In test: say hello!
-
创建一个与libtest.a提供相同接口test_print()的库libtest2.a,打印的内容不同,为"In test2: say hello!",看搜索目录的添加顺序的影响
目录结构为:
link_directories/ ├── CMakeLists.txt ├── lib │ └── libtest.a ├── main.cpp └── lib2 └── libtest2.a
1)先添加libtest.a后添加libtest2.a,使用默认选项AFTER
CMakeLists.txt文件内容:
cmake_minimum_required(VERSION 3.22) project(link_directories_test) link_directories(lib) link_directories(lib2) add_executable(main main.cpp) target_link_libraries(main test test2)
运行
cmake .
、make VERBOSE=1
,可以看到-L目录顺序是先lib后lib2(注意-l选项的顺序是先test后test2,按照target_link_libraries的顺序):[100%] Linking CXX executable main /usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=1 /usr/bin/c++ CMakeFiles/main.dir/main.cpp.o -o main -L/XXX/link_directories/lib -L/XXX/link_directories/lib2 -Wl,-rpath,/XXX/link_directories/lib:/XXX/link_directories/lib2 -ltest -ltest2
运行
./main
,输出如下:$ ./main In test: say hello!
2)先添加libtest.a后添加libtest2.a,使用选项BEFORE,这样libtest2.a对应的目录会在libtest1.a对应的目录之前。
CMakeLists.txt文件内容:
cmake_minimum_required(VERSION 3.22) project(link_directories_test) link_directories(lib) link_directories(BEFORE lib2) add_executable(main main.cpp) target_link_libraries(main test test2)
运行
cmake .
、make VERBOSE=1
,可以看到-L目录顺序是先lib2后lib,(注意-l选项的顺序仍然是先test后test2,按照target_link_libraries的顺序):[100%] Linking CXX executable main /usr/bin/cmake -E cmake_link_script CMakeFiles/main.dir/link.txt --verbose=14 /usr/bin/c++ CMakeFiles/main.dir/main.cpp.o -o main -L/XXX/link_directories/lib2 -L/XXX/link_directories/lib -Wl,-rpath,/XXX/link_directories/lib2:/XXX/link_directories/lib -ltest -ltest2
执行
./main
结果如下:$ ./main In test: say hello!
因为target_link_libraries添加的顺序,test库在test2库之前,所以main还是先匹配到test库提供的test_print()函数,其他地方不变,我们把
target_link_libraries(main test test2)
修改为target_link_libraries(main test2 test)
,重新构建之后,运行./main
输出:$ ./main In test2: say hello!
可以看到已经匹配到test2库提供的函数了,原因就在与target_link_libraries先添加了test2。