CMake查找第三方或者自己的库文件

CMake查找库文件

使用cmake指定第三方库或者自己的工具库的相关目录
使用CMake可以方便的进行项目管理。作为初学者在使用过程中遇到了一些问题,做一些纪录。

问题描述
在windows下面做C++开发时,如果需要使用第三方库或者自己编译的工具库的时候,一般都是通过三步进行配置,这种方式在库文件比较少的时候可以通过手动完成配置(当然也可以通过bat脚本枚举库目录下面的文件,一起添加),然后导出属性表供以后使用。但是换一台PC,安装路径换了之后就还需要重新配置。

1)第三方库头文件路径的配置
为了能够让编译器在编译时能够找到第三方库的头文件(.h、.hpp等等扩展名的头文件)的位置,首先需要将第三方库的头文件路径添加到属性当中。具体配置的位置可以在属性当中的配置属性-VC++目录-Include目录中找到。否则编译时报找不到头文件(C1083)错误
找不到头文件
2)第三方库库文件路径以及引用库名称的配置
为了能够让链接器在编译时能够找到第三方库的库文件(.lib)的位置,还需要将第三方库的库文件路径添加到属性当中。具体配置的位置可以在属性当中的配置属性-VC++目录-Library目录中找到。否则报找不到输入文件*.lib错误(LNK1181)
CMake查找第三方或者自己的库文件_第1张图片
在添加库文件目录之后,我们还需要指定具体需要链接哪些库文件。添加库文件的名称可以参考第三方库的文档,当然有些库在引用头文件时,会自动的指明需要引用库的名字(例如boost),所以这个步骤在某些情况下也可以省略。但是由于大多数第三方库不支持这种自动指明引用库名字的方式,所以这个步骤还是必须走的过程。具体配置的位置可以在属性当中的配置属性-连接器-其他依赖中找到。否则报无法解析的外部符号(unresolved external symbol)错误(LNK2019)
CMake查找第三方或者自己的库文件_第2张图片
3) dll文件配置
为了让应用程序运行时正确找到dll文件,将第三方库dll文件所在目录添加到系统Path中(需要重启电脑生效)或者将dll文件拷贝到可执行文件(*.exe)同一级目录下(不推荐)。否则虽然编译通过,运行时报找不到dll文件。
CMake查找第三方或者自己的库文件_第3张图片

编写CMakeLists引用Xlnt库
编译完Xlnt C++库之后,安装Xlnt但是安装目录没有提供cmake配置文件,因此需要自己手动按照上面的操作步骤配置Xlnt,但是换一台电脑之后,还需要重新配置相关路径,比较繁琐。于是自己写了一个CMakeLists查找Xlnt库。
第一:通过CMakeGUI来让我们自己指定Xlnt安装目录。
第二:通过CmakeLists自动查找库文件。

1:通过CMakeGUI来让我们自己指定Xlnt安装目录。

Cmake的 set命令给我们提供了一个功能,通过CMakeGUI或者命令行来指定变量的值。

我们在CMakeLists中按照如下语句添加一个目录类型(PATH)的变量”XLNT_INSTALL_ROOT”
set(XLNT_INSTALL_ROOT “” CACHE PATH “xlnt install root directory”)
添加了该语句之后,CMakeGUI配置的时候会出现这个变量,我们可以指定这个变量的值为Xlnt的安装目录。
CMake查找第三方或者自己的库文件_第4张图片

2:通过CmakeLists在xlnt安装目录下自动查找库文件。

#可以通过下面的CMake语句判断指定的目录XLNT_INSTALL_ROOT是否存在

IF(EXISTS ${XLNT_INSTALL_ROOT})
  MESSAGE(STATUS “set XLNT_INSTALL_ROOT to ${XLNT_INSTALL_ROOT}”)
SET(XLNT_INCLUDE_DIR ${XLNT_INSTALL_ROOT}/include)
  SET(XLNT_LIBRARY_DIR ${XLNT_INSTALL_ROOT}/lib)
ELSE()
  message( FATAL_ERROR “XLNT_INSTALL_ROOT: ${XLNT_INSTALL_ROOT} is not a directory.” )
ENDIF()

#判断XLNT的include目录是否存在

#xlnt include dir
IF(EXISTS ${XLNT_INCLUDE_DIR})
  MESSAGE(STATUS “set XLNT_INCLUDE to ${XLNT_INCLUDE_DIR}”)
ELSE()
  message( FATAL_ERROR “XLNT_INCLUDE_DIR: ${XLNT_INSTALL_ROOT}/include is not exist.” )
ENDIF()

#判断XLNT的lib目录是否存在

#xlnt library dir
IF(EXISTS ${XLNT_LIBRARY_DIR})
  MESSAGE(STATUS “set XLNT_LIBRARY_DIR to ${XLNT_LIBRARY_DIR}”)
ELSE()
  message( FATAL_ERROR “XLNT_LIBRARY_DIR: ${XLNT_INSTALL_ROOT}/lib is not exist.” )
ENDIF()

#判断是否找到了xlnt库(find_library里面的库名字为xlnt,CMake为自己为我们查找xlnt.lib文件)

#xlnt library
find_library(XLNT_LIBS xlnt ${XLNT_LIBRARY_DIR})
IF(EXISTS ${XLNT_LIBS})
  MESSAGE(STATUS “set XLNT_LIBS to ${XLNT_LIBS}”)
ELSE()
  message( FATAL_ERROR “XLNT_LIBS: ${XLNT_LIBS} is not exist.” )
ENDIF()

#添加包含目录和库目录

include_directories($ {XLNT_INCLUDE_DIR})
link_directories(${XLNT_LIBRARY_DIR})

#添加可执行文件,编译链接生成xlnt_demo.exe文件

ADD_EXECUTABLE (xlnt_demo main.cpp)

#为可执行文件指定链接库XLNT_LIBS,即xlnt.lib

TARGET_LINK_LIBRARIES (xlnt_demo ${XLNT_LIBS})

CMakeLists内容

cmake_minimum_required (VERSION 2.6 FATAL_ERROR)

project (Xlnt_Test)

#xlnt install directory
set(XLNT_INSTALL_ROOT "" CACHE PATH "xlnt install root directory")
IF(EXISTS ${XLNT_INSTALL_ROOT})
  MESSAGE(STATUS "set XLNT_INSTALL_ROOT to ${XLNT_INSTALL_ROOT}")
  SET(XLNT_INCLUDE_DIR ${XLNT_INSTALL_ROOT}/include)
  SET(XLNT_LIBRARY_DIR ${XLNT_INSTALL_ROOT}/lib)
ELSE()
  message( FATAL_ERROR "XLNT_INSTALL_ROOT: ${XLNT_INSTALL_ROOT} is not a directory." )
ENDIF()

#xlnt include dir
IF(EXISTS ${XLNT_INCLUDE_DIR})
  MESSAGE(STATUS "set XLNT_INCLUDE to ${XLNT_INCLUDE_DIR}")
ELSE()
  message( FATAL_ERROR "XLNT_INCLUDE_DIR: ${XLNT_INSTALL_ROOT}/include is not exist." )
ENDIF()

#xlnt library dir
IF(EXISTS ${XLNT_LIBRARY_DIR})
  MESSAGE(STATUS "set XLNT_LIBRARY_DIR to ${XLNT_LIBRARY_DIR}")
ELSE()
  message( FATAL_ERROR "XLNT_LIBRARY_DIR: ${XLNT_INSTALL_ROOT}/lib is not exist." )
ENDIF()

#xlnt library
find_library(XLNT_LIBS xlnt ${XLNT_LIBRARY_DIR})
IF(EXISTS ${XLNT_LIBS})
  MESSAGE(STATUS "set XLNT_LIBS to ${XLNT_LIBS}")
ELSE()
  message( FATAL_ERROR "XLNT_LIBS: ${XLNT_LIBS} is not exist." )
ENDIF()

IF(XLNT_LIBS STREQUAL "")
MESSAGE("SUCCESS: FIND XLNT LIBRARY")
ENDIF()

include_directories(${XLNT_INCLUDE_DIR})
link_directories(${XLNT_LIBRARY_DIR})

SET(CMAKE_BUILD_TYPE Release)
ADD_DEFINITIONS(-D _XKEYCHECK_H)

ADD_EXECUTABLE  (xlnt_demo main.cpp)

#set vs startup project
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT xlnt_demo)
TARGET_LINK_LIBRARIES (xlnt_demo ${XLNT_LIBS})

参考资料
Visual Studio下C++第三方库的配置方法总结
https://www.linuxidc.com/Linux/2014-11/109153.htm?utm_source=tuicool
cmakelist 常见用法:https://blog.csdn.net/convpool/article/details/84956635
find_library命令使用:https://www.cnblogs.com/coderfenghc/archive/2012/07/14/2591135.html
cmake set命令使用:https://cmake.org/cmake/help/v3.0/command/set.html

你可能感兴趣的:(工具使用)