Cmakelist指定包头及库

cmakelist.txt

Cmake中的包头和库的指定

cmake提供更简单的方式来解决编译依赖问题,通常遇到编译时,需要指定包来进行编译,可通过如下几种方式来指定参与链接的包

1、通过find_package查找包

1) find_package自动查找

在以下环境变量中查找cmake文件

<package>_DIR
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
PATH

1\通常ROS环境下:CMAKE_PREFIX_PATH/opt/ros/<melodic>,
因此ROS环境下find_package()首先会在/opt/ros/<melodic>下寻找,如/opt/ros/melodic/share/<packages>能找到关于集成在ros下的package的Config.cmake文件。

2\对于根目录PATH下的查找:
cmake会自动去/usr/(lib/<arch>|lib|share)/cmake/<name>*/寻找模块,这使得绝大部分我们直接通过apt-get安装的库可以被找到。
find_package()会在~/.cmake/packages//usr/local/share/中的各个包目录中查找,寻找<库名字的大写>Config.cmake 或者 <库名字的小写>-config.cmake(比如库Opencv,它会查找/usr/local/share/OpenCV中的OpenCVConfig.cmake或opencv-config.cmake)。
常用两种Config.cmake系统查找路径:
/usr/local/share/<package>
/usr/local/lib/cmake/<package>

以上来自:https://www.jianshu.com/p/243ff97bbbc6

2)package_DIR设定包的位置

比较重要的是<package>_DIR。我们可以在调用cmake时将这个目录传给cmake。由于其优先级最高,因此cmake会优先从该目录中寻找,当我们不想安装某些自编译的包时,可以通过这种方法来指定find_package的指定寻找路径。
如:

set(G2O_DIR ${PROJECT_SOURCE_DIR}/lib/g2o/build)
find_package(G2O REQUIRED)
include_directories(${G2O_INCLUDE_DIRS})
link_directories(${G2O_LIBRARY_DIRS})
link_libraries(${G2O_LIBRARIES})

find_package根据package名称寻找指定的package的.cmake文件,并对应赋值包对应的头文件地址(如${OpenCV_INCLUDE_DIRS})及库(如${OpenCV_LIBRARIES})
${OpenCV_LIBRARIES}不是库的存放地址,而是-lxxx,即用pkg-config opencv –libs打印出的内容,如:
-L/usr/local/lib -lopencv_dnn -lopencv_highgui -lopencv_ml -lopencv_objdetect -lopencv_shape -lopencv_stitching -lopencv_superres -lopencv_videostab -lopencv_calib3d -lopencv_videoio -lopencv_imgcodecs -lopencv_features2d -lopencv_video -lopencv_photo -lopencv_imgproc -lopencv_flann -lopencv_viz -lopencv_core

2、设定包的头文件及库

也可以通过cmakelist的set()重设${xxxINCLUDE_DIRS}${xxx_LIBRARIES},以及自定义变量,用法,set(变量名 变量值),如:

set(LIBS ${OpenCV_LIBS}
${PROJECT_SOURCE_DIR}/../../../Thirdparty/g2o/lib/libg2o.so
-lboost_system)

3、使用pkg-config在cmakelist中指定包

set(ENV{PKG_CONFIG_PATH} /packname.pc_path)
find_package(PkgConfig)
pkg_search_module(MyDepName REQUIRED packname)

之后可以使用${MyDepName_LIBRARIES}${MyDepName_INCLUDE_DIRS}来指定包的头文件及库

https://www.jianshu.com/p/eb6b06463da9

为编译指定全部头文件及库地址以及库名

通过include_directorieslink_directories指定额外的头文件及库文件路径。分别对应g++的-I和-L操作。
link_libraries添加需要链接的库文件路径,注意这里是全路径,如:

LINK_LIBRARIES("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so")

通过target_link_libraries指定链接库,即执行编译中对应的-lxxx操作

add_executable(GNtest src/test.cpp)
target_link_libraries(GNtest ${catkin_LIBRARIES} ${OpenCV_LIBRARIES} ${PCL_LIBRARIES} -lgtsam)

遇到问题

Q1:Could not find a package configuration file

 By not providing "FindNLOPT.cmake" in CMAKE_MODULE_PATH this project has
  asked CMake to find a package configuration file provided by "NLOPT", but
  CMake did not find one.
  
  Could not find a package configuration file provided by "NLOPT" with any of
  the following names:
    NLOPTConfig.cmake
    nlopt-config.cmake
    
  Add the installation prefix of "NLOPT" to CMAKE_PREFIX_PATH or set
  "NLOPT_DIR" to a directory containing one of the above files.  If "NLOPT"
  provides a separate development package or SDK, be sure it has been
  installed.

R1:首先请确保是否是因为缺包引起的。
(1)是的话安装对应包,不是则找到xxx.cmake的存放位置

在CMakelist.txt中添加xxx.cmake所在的路径到查找路径。
解决以上报错的两种方法:

  1. 添加 set (CMAKE_PREFIX_PATH "pathtoxxx.cmake")
  2. 添加 list(APPEND CMAKE_FIND_ROOT_PATH "pathtoxxx.cmake")
    如果直接xxx.cmake直接在项目目录下,添加list(APPEND CMAKE_FIND_ROOT_PATH ${PROJECT_SOURCE_DIR})即可。

CMAKE_SOURCE_DIR does indeed refer to the folder where the top-level CMakeLists.txt is defined.
PROJECT_SOURCE_DIR refers to the folder of the CMakeLists.txt containing the most recent project() command.

(2)若包已安装,但是没有对应的xxx.cmake文件,find_package找不到xxx.cmake文件。
则可以利用pkg-config 找到对应的库。
在要编译的包的CMakeList.txt中对应修改,以下以fcl包为例。

find_package(PkgConfig REQUIRED)
pkg_check_modules(LIBFCL_PC REQUIRED fcl)
# find *absolute* paths to LIBFCL_INCLUDE_DIRS and LIBFCL_LIBRARIES
find_path(LIBFCL_INCLUDE_DIRS fcl/config.h HINTS ${LIBFCL_PC_INCLUDE_DIR} ${LIBFCL_PC_INCLUDE_DIRS})
find_library(LIBFCL_LIBRARIES fcl HINTS ${LIBFCL_PC_LIBRARY_DIRS})

include_directories(SYSTEM ${catkin_INCLUDE_DIRS}
                           ...
                           ${LIBFCL_INCLUDE_DIRS}
                           )
catkin_package(
...
  DEPENDS
    Boost
    EIGEN3
    LIBFCL
)

opencv solve test:cvsolve.cpp

#include <iostream>
#include <opencv/cv.h>
#include <opencv2/core/core.hpp>

using namespace std;

int main()
{
    cv::Mat A = (cv::Mat_<float>(2, 2) << 1,2,3,4);

    cv::Mat B = (cv::Mat_<float>(2, 1) <<5,11);
    cv::Mat C;
    cout << "A" << endl << A << endl;
    cout << "B" << endl << B << endl;

    cv::solve(A, B, C, CV_LU);

    cout << "X" << endl << C << endl;
    return 0;
}

编译命令:要主动链上opencv 否则会报未定义的错误。

g++ `pkg-config --libs --cflags opencv` -ldl xx.cpp
#下边这个命令常用
g++ opencv_test.cpp `pkg-config --cflags --libs opencv`

以上命令会自动找到并连接opencv的库。而不用在手动指定。
pkg-config 用于获得某一个库/模块的所有编译相关的信息。寻找对应的xxx.pc文件,来获取包及库的相关信息。
ldl: 链接动态库
如果你的程序中使用dlopen、dlsym、dlclose、dlerror 显示加载动态库,需要设置链接选项 -ldl

输出结果:
在这里插入图片描述

cmake用法:
add_subdirectory 添加下级编译目录,下级有CMakelist.txt的目录
add_definitions 添加可配置的宏定义:

#eg:如下示例可置宏定义ADVANCED_SENSING为1或0,进而可以再代码终用#ifdef打开或关闭对应的代码。
option(ADVANCED_SENSING "ADVANCED_SENSING set" ON)
if (ADVANCED_SENSING)
  add_definitions(-DADVANCED_SENSING)
endif()

cmake . -DADVANCED_SENSING=0

add_dependencies:添加编译依赖顺序,检查上级编译是否已经编译,否则先编译依赖上级

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值