最近在编译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骗过去,先保证工程能够生成。