最近在编译FastDDS时,遇到了这个问题,使用CMake构建时提示找不到库。
下载的源代码不能一次性编过是最让人头疼的问题,这种开源代码通常都是迭代了很多版本,各种配置信息如果不在文档中说明,全靠自己去摸索确实会让人头大,所以,我尽可能的把我遇到的问题分享出来,供大家参考,而不要在这种环境问题上就栽了大跟头。
今天就来介绍一下CMake中的find_package在windows平台该怎么配置,怎么使用。
以一个全新的例子说明,比如我们要在这里使用Dll库中的fnDll1()函数,就这么简单:
#include "Dll1.h" #include <iostream> using namespace std; int main() { std::cout << fnDll1() << std::endl; return 0; }
为它编写一个CMakeLists.txt,方便生成vs工程:
cmake_minimum_required(VERSION 3.10) project(test) set(SRC_LIST src/main.cpp) set(CMAKE_PREFIX_PATH "D:/test/Dll1") set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "D:/test/Debug") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "D:/test/cmaketest/modules") #here find_package(DLL1 REQUIRED) add_executable(test ${SRC_LIST}) target_include_directories(test PRIVATE ${DLL1_INCLUDE_DIR}) target_link_directories(test PRIVATE "D:/test/Debug") target_link_libraries(test DLL1)
注意我们设置了一个CMAKE_MODULE_PATH
路径,在这个路径下有一个FindDLL1.cmake
# 设置查找脚本的名称 set(DLL1_FIND_SCRIPT "FindDLL1.cmake") # 定义查找库的过程 find_path(DLL1_INCLUDE_DIR NAMES Dll1.h PATHS ${CMAKE_PREFIX_PATH} ) find_library(DLL1_LIBRARY NAMES DLL1 PATHS ${CMAKE_PREFIX_PATH} ) # 检查是否找到库的头文件和链接库 if (DLL1_INCLUDE_DIR AND DLL1_LIBRARY) set(DLL1_FOUND TRUE) else () set(DLL1_FOUND FALSE) endif () # 提供库的相关变量 if (DLL1_FOUND) if (NOT DLL1_FIND_QUIETLY) message(STATUS "Found DLL1: ${DLL1_LIBRARY}") endif () else () if (DLL1_FIND_REQUIRED) message(FATAL_ERROR "DLL1 library not found") else () message(STATUS "DLL1 library not found") endif () endif ()
如果开源项目中没有形如FindDLL1.cmake的文件,通常就需要我们自己手写一个,这个文件的作用其实就是为了检查到底有没有这样的库存在。
或者如果你觉得写这样的文件太麻烦,不如生成工程后再手动配置三方库头文件和库文件,那你可以先创建一个空文件,把cmake骗过去,之后再自己手动配置。
最后来看一下目录结构:
(假设DLL1库已经编好了,并且头文件在“D:\test\Dll1”下,lib在“D:\test\Debug”目录下)
然后就可以使用cmake工具生成vs工程了:
打开工程,编译没有问题,查看配置项,可以发现cmake已经按我们指定的路径配置好了。
以上便是整个使用过程,之后再遇到这种问题不会头大了吧。
或者如文章中提到的,如果你觉得写这样的文件太麻烦,还不如手动配,那就可以先放置一个空文件,把CMake骗过去,先保证工程能够生成。