# 1. CMAKE, 安装OPENCV,以及跑通一个opencv的程序

整个案例懒得话直接用这个操作看结果好了

rm -rf build
cmake -S . -B build
cmake --build build

1. Cmake 入门

#include <iostream>

int main()
{
    
    
    std::cout << "Hello World!" << std::endl;
    return 0;
}

同级目录

# 设置项目名字, 版本号(这个是自己项目的版本号), 项目描述, 项目语言
project(first_demo
        VERSION 1.0.0
        DESCRIPTION "项目描述"
        LANGUAGES CXX)

# first_file: 生成的可执行文件的名字
# main.cpp 编译的CXX文件
add_executable(first_file main.cpp)
# -S 指定源码目录,-B 指定构建目录  这里 . 是当前目录的意思 -B 是指定构建目录
cmake -S . -B build

# 生成可执行文件,  --build 在指定位置构建可执行文件
cmake --build build

案例

(base) root@ubuntu-01:/data/Github/trt_demo/1.Cmake/src/3.first_cmake# cmake -S . -B asd
-- The CXX compiler identification is GNU 7.5.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /data/Github/trt_demo/1.Cmake/src/3.first_cmake/asd
(base) root@ubuntu-01:/data/Github/trt_demo/1.Cmake/src/3.first_cmake# cmake --build asd
[ 50%] Building CXX object CMakeFiles/first_file.dir/main.cpp.o
[100%] Linking CXX executable first_file
[100%] Built target first_file
(base) root@ubuntu-01:/data/Github/trt_demo/1.Cmake/src/3.first_cmake# ./asd/first_file 
Hello World!

2. 生成动态库链接

经过了顺序的实验, 给可执行文件添加东西放在定义可执行文件后面就行了

默认情况下,add_library创建的是静态库。如果需要创建动态库,需要使用 add_library( SHARED ),其中 SHARED 选项指定创建的是动态库。

add_library(Accountsssss SHARED "./account_dir/Account.cpp" "./account_dir/Account.h")

像这句话就是把"./account_dir/Account.cpp" “./account_dir/Account.h” 变成动态库 Accountsssss

(base) root@ubuntu-01:/data/Github/trt_demo/1.Cmake/src_back/6.build_together# tree .
.
├── account_dir
│   ├── Account.cpp
│   └── Account.h
├── CMakeLists.txt
└── test_account
    └── main.cpp

#6.build_together/CMakeLists.txt`

# cmake的最低版本要求
cmake_minimum_required(VERSION 3.10)

# 项目信息
project(test_account)

# 添加可执行文件
add_executable(run_file "./test_account/main.cpp")

# 添加动态库
add_library(Accountsssss SHARED "./account_dir/Account.cpp" "./account_dir/Account.h")

# 添加链接库
target_link_libraries(run_file Accountsssss)

# 添加头文件
target_include_directories(run_file PUBLIC "./account_dir")

里面会生成一个动态库, 把他删掉了可执行文件也执行不了了

tree . 
ldd build/run_file
(base) root@ubuntu-01:/data/Github/trt_demo/1.Cmake/src_back/6.build_together# tree .
.
├── account_dir
│   ├── Account.cpp
│   └── Account.h
├── build
│   ├── libAccountsssss.so
│   ├── Makefile
│   └── run_file
├── CMakeLists.txt
└── test_account
    └── main.cpp

3 directories, 7 files
(base) root@ubuntu-01:/data/Github/trt_demo/1.Cmake/src_back/6.build_together# ldd build/run_file 
        linux-vdso.so.1 (0x00007fffa2b96000)
        libAccountsssss.so => /data/Github/trt_demo/1.Cmake/src_back/6.build_together/build/libAccountsssss.so (0x00007f374897f000)
        libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f37485f6000)
        libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f37483de000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f3747fed000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3747c4f000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f3748d84000)

3. Cmake中的PUBLIC PRIVATE INTERFACE

看一个案例

# 创建库, 这里创建了三个静态库
add_library(C c.cpp)
add_library(D d.cpp)
add_library(B b.cpp)

# C, D都是B的依赖项
# C是B的PUBLIC依赖项
target_link_libraries(B PUBLIC C)
# D是B的PRIVATE依赖项
target_link_libraries(B PRIVATE D)

# 添加可执行文件
add_executable(A a.cpp)

# 将B链接到A
target_link_libraries(A B)

C 是PUBLIC所以可以扩散到A

D是PRIVATE所以可以扩散到A

4. 变量和message()

根据自己的需求消除注释

# 最小的版本要求
cmake_minimum_required(VERSION 3.10)

# 项目名称
project(message_turtorial)

# 输出消息, 像python的print() 自动换行
message("输出消息")
message(输出消息1 " " 输出消息2) # 会做拼接的

# 设置变量, 变量的不同访问方法
set(My_Var "我的变量")
message("My_var = " ${
    
    My_Var}) 
message("My_Var = ${My_Var}")
message("\{My_Var} = {My_Var}") # 转义字符就没法打印了
unset(My_Var) 
message("My_Var = ${My_Var}")   # 删除后输出为空

# 提供信息变量: 这些特殊字符串打错了就输出为空
message("项目名称: ${PROJECT_NAME}")
message("源码目录: ${CMAKE_SOURCE_DIR}")
message("编译目录: ${CMAKE_BINARY_DIR}")
message("当前CMakeList.txt文件路径: ${CMAKE_CURRENT_LIST_FILE}")

# 自己cmake一下才能够知道
# 不开的时候说呢工程的是*.a后缀的静态库文件
# 开了会生成*.so动态库文件, 在build的文件夹下面
set(BUILD_SHARED_LIBS ON)

# 描述系统的变量
message("是否是Windows系统: ${WIN32}")
message("是否是Linux系统: ${UNIX}")
message("系统名称: ${CMAKE_SYSTEM_NAME}")


# 生成库文件
add_library(${
    
    PROJECT_NAME} Account.cpp Account.h)

全部的输出

输出消息
输出消息1 输出消息2
My_var = 我的变量
My_Var = 我的变量
{My_Var} = {My_Var}
My_Var = 
项目名称: message_turtorial
源码目录: /data/Github/trt_demo/1.Cmake/src_back/7.message_var_demo
编译目录: /data/Github/trt_demo/1.Cmake/src_back/7.message_var_demo/build
当前CMakeList.txt文件路径: /data/Github/trt_demo/1.Cmake/src_back/7.message_var_demo/CMakeLists.txt
是否是Windows系统: 
是否是Linux系统: 1
系统名称: Linux

5. Include

# 8.include_demo
cmake_minimum_required(VERSION 3.10)

project(include_demo)

message("调用include前的信息")

# include,引用一次就导入一次
# CMAKE_CURRENT_SOURCE_DIR这个是相对路径, CMakeList.txt
# 写一次就是调用一次, 这里调用了四次
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/module_1.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/module_1.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/module_1.cmake")
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/module_1.cmake")

message("调用include后的信息")

在对应的路径下有一个module_1.cmake

message("模块内部被调用")

5. if

在 CMake 中,缩进(也就是 tab 或空格)是用来控制代码块的,从而组织 CMakeLists.txt 文件的结构和逻辑。CMakeLists.txt 文件中的命令通常按照一定的层次结构排列,缩进的数量用于表示命令所属的代码块。一个代码块的缩进是它上一级代码块的缩进加上一个固定的缩进量(通常是一个制表符或四个空格),用于表示代码块的开始和结束。

在 CMake 中,endif() 是必需的,用于结束 if() 命令的代码块。if() 命令用于指定一个条件,如果这个条件成立,将会执行一段代码,否则将会执行另一段代码。在 if() 命令之后的代码块必须使用 endif() 命令来结束。

例如,在下面的代码片段中,if 和 else 命令是一个代码块的开始和结束,其中缩进用于将这两个命令与其它代码分离:

if (SOME_CONDITION)
    # code to be executed if SOME_CONDITION is true
else ()
    # code to be executed if SOME_CONDITION is false
endif ()

6. 用OPENCV的案例学习CMake

6.1 安装OPENCV

  1. 安装git
  2. 安装cmake, 亲测有效的实用帖子 (https://zhuanlan.zhihu.com/p/494120239)
  3. 打开终端,更新系统:
sudo apt update && sudo apt upgrade

  1. 安装所需依赖包:
sudo apt install build-essential cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt install python3-dev python3-numpy libtbb2 libtbb-dev libjpeg-dev libpng-dev libtiff-dev libdc1394-22-dev

  1. 从 GitHub 克隆 OpenCV 和 OpenCV Contrib 的源代码:
cd ~
git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git

  1. 创建一个构建目录,用于存放编译后的文件:
cd opencv
mkdir build
cd build

  1. 运行 CMake 来配置编译选项。请确保在以下命令中将 -D OPENCV_EXTRA_MODULES_PATH 参数设置为你的 opencv_contrib/modules 目录的实际路径。如果需要,可以通过在命令中添加 -D CMAKE_INSTALL_PREFIX=/your/custom/install/path 参数自定义安装路径:
cmake -D CMAKE_BUILD_TYPE=RELEASE \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D INSTALL_C_EXAMPLES=ON \
      -D INSTALL_PYTHON_EXAMPLES=ON \
      -D OPENCV_GENERATE_PKGCONFIG=ON \
      -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
      -D BUILD_EXAMPLES=ON ..

**注意: -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \ **

这个contrib要写对路径

  1. 编译 OpenCV:
make -j$(nproc)

  1. 安装编译好的 OpenCV:
sudo make install

  1. 更新库链接:
sudo ldconfig

  1. 测试, 使用文本编辑器创建一个名为 opencv_version.cpp 的新文件,然后将以下代码粘贴到文件中:
#include <iostream>
#include <opencv2/core.hpp>

int main() {
    
    
    std::cout << "OpenCV version: " << CV_VERSION << std::endl;
    return 0;
}

g++ opencv_version.cpp -o opencv_version `pkg-config --cflags --libs opencv4`
./opencv_version

出现就说明成功了

OpenCV version: 4.7.0-dev

6.2 写一个CMakeList.txt

cmake_minimum_required(VERSION 3.10)

project(demo_opencv)

find_package(OpenCV REQUIRED)

if (OpenCV_FOUND)
    message(STATUS "OpenCV library status:")
    message(STATUS "    libraries: ${OpenCV_LIBS}")
    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
else ()
    message(FATAL_ERROR "Could not find OpenCV")
endif ()


add_executable(demo_opencv main.cpp)
target_include_directories(demo_opencv PRIVATE ${OpenCV_INCLUDE_DIRS})
target_link_libraries(demo_opencv ${OpenCV_LIBS})

猜你喜欢

转载自blog.csdn.net/bobchen1017/article/details/129776098
今日推荐