
【C/C++/CMake】ubuntu系统下安装引用第三方库libyaml找不到yaml.h
Windows11+WSL+vs2022+CMake项目,并编译运行至Ubuntu-20.04,引用第三方库libyaml找不到yaml.h。
文章目录
【C/C++/CMake】ubuntu系统下安装引用第三方库libyaml找不到yaml.h
一、环境说明
本项目使用Windows11+WSL功能,在编译器visual studio2022下建立CMake项目,并编译运行至Ubuntu-20.04上。
问题复现:在项目中引入yaml.h时一直划红线找不到该库:
二、安装libyaml库
官方地址:https://pyyaml.org/wiki/LibYAML
下载路径:http://pyyaml.org/download/libyaml/yaml-0.2.5.tar.gz
按照官方readme安装yaml,默认安装路径在/usr/local下:
$ bash ./configure
$ make
# sudo make install
三、.cpp文件中引入libyaml库
为排除问题,我首先新建了个test.cpp,使用最原始的办法gcc来编译。
#include <stdio.h>
#include <yaml.h>
int main(){
int majar = -1;
int minor = -1;
int patch = -1;
yaml_get_version(&major, &minor, &patch);
printf("%d.%d.%d\n", major, minor, patch);
return 0;
}
gcc test.cpp -o test
以上编译结果会报错找不到函数: undefined reference to `yaml_get_version’;
原因是没有链接yaml库,使用下述代码即编译成功。
gcc test.cpp -o test -lyaml
其中,-o test 表示指定输出文件名为test;-lyaml表示链接yaml库。
./test
运行test文件,能够正常输出yaml版本号,至此我认为yaml库的安装没有问题。
四、CMake链接libyaml库
通过gcc编译的过程,我认识到CMake也必须链接yaml库,在一步步排查问题前我也使用过include_directories、link_directories、link_libraries等链接库的方法,但还是链接不上,最后千辛万苦求助GPT找到:find_package命令。(GPT的详细回答见下一章节)
因此,我的CMakeLists.txt最终的相关代码为:
find_package(yaml REQUIRED)
add_executable (test "test.cpp")
include_directories(/usr/local/include/yaml.h)
target_link_libraries(test /usr/local/lib/libyaml.a)
find_package与include_directories与target_link_libraries缺一不可,target_link_libraries也在链接时使用,指明链接库的名字。
其中 “/usr/local/include/yaml.h” 和 “/usr/local/lib/libyaml.a” 为Ubuntu上yaml的安装路径。
(本节在2023/4/26更新:参考文章https://blog.csdn.net/qq_19280295/article/details/127910260)
五、GPT Q&A
1、find_package命令语法如下:
find_package(<package_name> [version] [EXACT] [QUIET] [MODULE] [REQUIRED] [[COMPONENTS] [component1] [component2] ...])
其中,<package_name>表示需要查找的库名。version表示要求的库版本,EXACT表示需要精确匹配版本,QUIET表示不输出查找过程中的信息,MODULE表示使用CMake模块查找库,REQUIRED表示该库是必须的,COMPONENTS表示要查找的库的组件名。
例如:
find_package(yaml REQUIRED)
该命令会在系统中查找名为yaml的库,REQUIRED表示该库是必须的。
2、find_package做了什么
在find_package查找库之后,CMake会自动设置一些变量,例如YAML_INCLUDE_DIR、YAML_LIBRARIES和YAML_FOUND等,这些变量可以在后续的命令中使用。例如,YAML_INCLUDE_DIR变量表示yaml库的头文件路径,YAML_LIBRARIES变量表示yaml库的链接选项。
3、find_library和find_path与之区别
find_library和find_path命令用于查找指定的库和头文件,而find_package命令则用于查找指定库的包。它们之间的区别在于,find_package命令会自动设置一些变量,例如包含路径、库文件路径、链接选项等,而find_library和find_path命令只是返回库文件路径和头文件路径,需要手动设置变量。此外,find_package命令还可以检查库的版本,查找库的组件等。
因此,一般情况下,我们建议使用find_package命令来查找和使用第三方库。但是,如果您只需要查找某个库的路径,而不需要设置其他变量,那么使用find_library命令可能更加简单和方便。
六、小结
虽然到最后还是没有完全搞明白include_directories、link_directories、link_libraries、find_package、find_library、find_path等命令之间的区别和用法,但是这个问题总算是暂时解决了,希望有大神可以讲解一下,或者给个思路如何系统学习这方面的知识。
更多推荐
所有评论(0)