一. 一个简单的例子
工程目录如下:
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── libmy_add.so
│ ├── Makefile
│ └── my_test
├── CMakeLists.txt
├── include
│ └── my_add.h
├── my_test.cpp
└── src
└── my_add.cpp
my_add.h
#include <iostream>
int my_add(int x, int y);
my_add.cpp
#include "my_add.h"
int my_add(int x, int y)
{
return x+y;
}
my_test.cpp
#include<iostream>
#include "my_add.h"
int main()
{
int c;
c = my_add(2,3);
std::cout << "test my_add:" << c << std::endl;
std::cout << "success" << std::endl;
}
CMakeLists.txt
#要求的Cmake最低版本
cmake_minimum_required(VERSION 3.18)
#工程名称
project(my_test)
set(CMAKE_CXX_STANDARD 11)
set(my_add ${PROJECT_SOURCE_DIR}/src/my_add.cpp)
include_directories("${PROJECT_SOURCE_DIR}/include")
#生成共享库
add_library(my_add SHARED ${my_add})
#生成可以执行的文件
add_executable(my_test my_test.cpp)
#连接共享库
target_link_libraries(my_test my_add)
编译
mkdir build
cd build
cmake ..
make
build文件夹下面有共享库 libmy_add.so,可执行文件my_test
二. 调用自己的共享库文件
所有的外部依赖库都是这样的,比如opencv ,openni, eigen等等,原理是一样的,只不过他们已经安装在系统里面了,可以查找,而这个则是需要我们自己去配置。
即我上面生成的共享库文件本质上和opencv的库是相同的。只不过这个共享库需要自己手动配置。
比如我又新建了一个工程,需要调用上面的共享库 libmy_add.so。
工程目录如下:
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── Makefile
│ └── my_test
├── CMakeLists.txt
├── include
│ └── my_add.h
├── lib
│ └── libmy_add.so
├── my_test.cpp
└── src
└── my_add.cpp
CMakeLists.txt
#要求的Cmake最低版本
cmake_minimum_required(VERSION 3.18)
#工程名称
project(my_test)
set(CMAKE_CXX_STANDARD 11)
include_directories("${PROJECT_SOURCE_DIR}/include")
set(ADD_SO "${PROJECT_SOURCE_DIR}/lib/libmy_add.so")
#生成可以执行的文件
add_executable(my_test my_test.cpp)
#连接共享库
target_link_libraries(my_test ${ADD_SO})
其实主要的就是指明这个调用这个共享库的时候,使用的头文件,以及共享库本身所在的位置,然后包含链接就可以了。
三.调用安装过的共享库
Opencv的依赖添加
比如Opencv, 它的头文件和.so文件都已经放在了系统变量里面,不用向上面自己定义了(上面例子里面的头文件和共享库文件的地址都是我自己设置的)
它的CMakeLists.txt如下:
find_package(OpenCV REQUIRED)
include_directories(${OPENCV_INCLUDE_DIRS})
target_link_libraries(MAIN ${OpenCV_LIBS})
只需要查找就可以了,OpenCV_LIBS 和 OPENCV_INCLUDE_DIRS 都是系统帮我们已经定义好的,所以比较容易
工程目录如下:
.
├── build
│ ├── CMakeCache.txt
│ ├── CMakeFiles
│ ├── cmake_install.cmake
│ ├── cv_example
│ └── Makefile
├── CMakeLists.txt
├── cv_example.cpp
└── test.jpg
cv_example.cpp
#include <iostream>
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/highgui.hpp"
int main() {
std::string img_path = "../test.jgp";
cv::Mat M = cv::imread(img_path);
std::cout << "load img success" << std::endl;
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(cv_example)
set(CMAKE_CXX_STANDARD 14)
add_executable(cv_example cv_example.cpp)
find_package(OpenCV REQUIRED)
include_directories(${OPENCV_INCLUDE_DIRS})
target_link_libraries(cv_example ${OpenCV_LIBS})
编译执行:
mkdir build
cd build
cmake ..
make
./cv_example
四. 一个完整工程的CMakeLists.txt
#工程名字
project(Camera_sugan)
#编译最低cmake版本
cmake_minimum_required(VERSION 2.6)
#设置c++编译器
set( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
#在整个电脑上找opencv包
find_package(OpenCV REQUIRED)
#包含头文件路径
include_directories(
./include/inudev/
./src/
)
#将所有的源文件列为一个集合,集合名字叫做SRC_LISTS
set(SRC_LISTS
./src/inuitive.cpp
./src/runCamera_Qfeeltech.cpp
)
#将集合里的所有的源文件生成一个静态库,该静态库的名字libsugan,
# 注意,在整个CmakeLists里都要用libsugan这个
add_library(libsugan ${SRC_LISTS})
#名字来代替之前那个集合生成的库。
target_link_libraries(libsugan #链接静态库需要的依赖库
${OpenCV_LIBS}
${PROJECT_SOURCE_DIR}/lib/libCommonUtilities.so
${PROJECT_SOURCE_DIR}/lib/libInuStreams.so
)
五. CMake指定g++版本编译
在CMakeLists.txt中调用编译器之前添加:
SET(CMAKE_C_COMPILER "/usr/local/bin/gcc")
执行cmake命令之前,在shell终端先设置如下两个变量:
export CXX=/usr/local/bin/g++
# /usr/local/gcc-xxx/lib 是你的新gcc的lib位置
export LD_LIBRARY_PATH=/usr/local/gcc-xxx/lib:$LD_LIBRARY_PATH
六. 设置编译时和程序运行时去哪个目录找动态库
程序运行时,搜索动态库的顺序(优先级)优先级是这样的:
- RPATH ,编译链接时加入 -rpath 参数 指定的目录
- LD_LIBRARY_PATH 这个环境变量指定的目录
- /etc/ld.so.conf 配置文件。
- /usr/lib 、 /lib 和 /usr/local/lib ,系统默认路径。
所以我们设置了RPATH ,并且RPATH 下有要找的动态库,程序就首先加载它
注意:
可以看到,RPATH与RUNPATH中间隔着LD_LIBRARY_PATH。为了让用户可以通过修改LD_LIBRARY_PATH来指定.so文件,大多数编译器都将输出的RPATH留空,并用RUNPATH代替RPATH。
七. 其他
# 把当前目录/src下的文件,指定在变量SRC_LIST中
aux_source_directory(${CMAKE_CURRENT_SOURCE_DIR}/src/ SRC_LIST)
add_subdirectory(my-sdk)
# 添加本地的so
set_target_properties(decode PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/lib/fastertransformer.so)
参考:https://blog.csdn.net/bandaoyu/article/details/115165199
https://blog.csdn.net/Guo_Python/article/details/124846646?spm=1001.2014.3001.5501
文章出处登录后可见!