Cmake学习笔记

目录

目录

Cmake常用命令介绍

1、add_executable和add_subdirectory命令

3.aux_source_directory查找指定目录所以的文件添加成一个变量

4、include_directories指定头文件搜索路径

5.Cmake的变量

CMAKE常用变量介绍

6.install命令 

 CMAKE交叉编译

 举例,使用多个三方库opencv进行cmake

Cmake的编译方式 


cmake的使用场景和功能:cmake 的诞生主要是为了解决直接使用 make+Makefile 这种方式无法实现跨平台的问题,所以 cmake 是可以实现跨平台的编译工具这是它最大的特点。cmake 仅仅只是根据不同平台生成对应的 Makefile,最终还是通过 make工具来编译工程源码,但是 cmake 却是跨平台的

所以需要我们需要修改CMakeLists.txt文件,最后编译出Makefile

cmake --version
cmake ./
//检查版本和运行cmakelist.txt

执行完 cmake 之后,除了源文件 main.c 和 CMakeLists.txt 之外,可以看到当前目录下生成了很多其它的文件或文件夹,包括: CMakeCache.txt、 CmakeFiles、 cmake_install.cmake、 Makefile

通常是建立一个build文件夹,cmake ../让cmake产生的文件都在一个目录下,就不会看起来混乱

Cmake常用命令介绍

1、add_executable和add_subdirectory命令

add_executable(hello ./main.c)
add_executable 同样也是一个命令,用于生成一个可执行文件, 在本例中传入了两个参数,第一个参数表示生成的可执行文件对应的文件名,第二个参数表示对应的源文件;

add_executable(hello ./main.c)表示需要生成一个名为 hello 的可执行文件,所需源文件为当前目录下的 main.c。

add_subdirectory告诉 cmake 去指定的目录中寻找源码并执行CMakeLists.txt,这个命令在大型工程的时候用的特别多,每一级目录下都有自己的CMakeLists.txt的文件。

# 告诉 cmake 去 src 目录下寻找 CMakeLists.txt
add_subdirectory(src)

add_library 命令用于生成库文件,在本例中我们传入了两个参数,第一个参数表示库文件的名字,需要注意的是,这个名字是不包含前缀和后缀的名字; 在 Linux 系统中,库文件的前缀是 lib,动态库文件的后缀是.so,而静态库文件的后缀是.a;最终生成的库文件对应的名字会自动添加上前缀和后缀。

find_package(Boost REQUIRED COMPONENTS filesystem system:查找外部库BOOST,如果找到,会设置相关的变量(如 Boost_FOUNDBoost_INCLUDE_DIRSBoost_LIBRARIES 等),并提供目标(如 Boost::filesystem 和 Boost::system

add_library(libhello SHARED hello.c) #生成动态库文件
add_library(libhello STATIC hello.c) #生成静态库文件
add_executable(hello main.c)#可执行文件hello
target_link_libraries(hello liblibhello)#指定依赖库

target_link_libraries 命令为目标指定依赖库,hello.c 被编译为库文件, 并将其链接进 hello 程

3.aux_source_directory查找指定目录所以的文件添加成一个变量

Cmake的命令,刚刚的add_library就是命令。在 CMakeLists.txt 中,命令名不区分大小写,可以使用大写字母或小写字母书写命令名

# 查找 src 目录下的所有源文件
aux_source_directory(src SRC_LIST)
message("${SRC_LIST}") # 打印 SRC_LIST 变量

4、include_directories指定头文件搜索路径
 

如果需要包含多个头文件时,可以把头文件放在include文件夹中,当调用 add_subdirectory 命令加载子源码时, 会将 include_directories 命令包含的目录列表向下传递给子源码(子源码从父源码中继承过来)

include_directories(include)
add_executable(hello main.c)

5.Cmake的变量

 手动添加自定义变量,当然是变量就存在作用域,set变量作用域的范围如下:

# 全局作用域
set(GLOBAL_VAR "global" CACHE INTERNAL "")

# 目录作用域
set(DIR_VAR "directory")

function(my_function)
    # 函数作用域
    set(FUNC_VAR "function")
    # 提升到父作用域
    set(PARENT_VAR "parent" PARENT_SCOPE)
endfunction()

if(TRUE)
    # 块作用域
    set(BLOCK_VAR "block")
endif()

#设置变量 MY_VAL
set(MY_VAL "Hello World!")
#引用变量 MY_VAL
message(${MY_VAL})

CMAKE常用变量介绍


6.install命令 

install命令用于指定在构建过程中需要安装的文件、目录、可执行文件等。在构建大型工程的时候会将编译出来的文件最终都安装到一个目录下,例如/output

install安装命令解释:

TARGETS:表示要安装的是 CMake 构建目标(如可执行文件、库等),而不是普通文件my_executable 和 my_library:my_executable:通常是通过 add_executable 定义的可执行文件my_library:通常是通过 add_library 定义的库文件(可以是共享库 .so 或静态库 .a

install(TARGETS my_executable my_library
        RUNTIME DESTINATION bin   # 可执行文件安装到 bin 目录
        LIBRARY DESTINATION lib   # 共享库安装到 lib 目录
        ARCHIVE DESTINATION lib)  # 静态库安装到 lib 目录

# 安装头文件到 include 目录
install(FILES my_header.h DESTINATION include)

# 安装整个目录到 share 目录
install(DIRECTORY my_data/ DESTINATION share/my_project)

# 安装脚本到 bin 目录
install(PROGRAMS my_script.sh DESTINATION bin)

 CMAKE交叉编译

如果不设置交叉编译,默认情况下, cmake 会使用主机系统(运行 cmake 命令的操作系统)的编译器来编译我们的工程,那么得到的可执行文件或库文件只能在 Ubuntu 系统运行(X86架构),为了能在arm(arch)芯片上运行需要使用交叉编译器

# 配置 ARM 交叉编译
set(CMAKE_SYSTEM_NAME Linux) #设置目标系统名字
set(CMAKE_SYSTEM_PROCESSOR arm) #设置目标处理器架构
# 指定编译器的根目录
set(TOOLCHAIN_DIR /opt/fsl-imx-x11/4.1.15-2.1.0/sysroots)
set(CMAKE_SYSROOT ${TOOLCHAIN_DIR}/cortexa7hf-neon-poky-linux-gnueabi)
# 指定交叉编译器 arm-gcc 和 arm-g++
set(CMAKE_C_COMPILER ${TOOLCHAIN_DIR}/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/armpoky-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_DIR}/x86_64-pokysdk-linux/usr/bin/arm-poky-linuxgnueabi/arm-poky-linux-gnueabi-g++)

 举例,使用多个三方库opencv进行cmake

# CMake需要的最低版本号是3.4.1
cmake_minimum_required(VERSION 3.4.1)
# 指定了项目的名称为resnet18
project(example)

# 不使用任何C编译器标志,使用C++11标准进行编译
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

# rknn api
# CMAKE_SOURCE_DIR当前cmakelist的目录
set(RKNN_API_PATH ${CMAKE_SOURCE_DIR}/../3rdparty/librknn_api)  #该变量定义了RKNN API库的路径
set(LIB_ARCH aarch64)
set(RKNN_RT_LIB ${RKNN_API_PATH}/${LIB_ARCH}/librknnrt.so)  # 该变量定义了RKNN运行时库的路径。
include_directories(${RKNN_API_PATH}/include)  # 添加RKNN API的头文件

# opencv
set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/../3rdparty/opencv/share/OpenCV)  # 指定了OpenCV库的路径。
find_package(OpenCV REQUIRED)  # 自动查找OpenCV库,并将相关信息保存在CMake内置变量中

# 指定了程序运行时查找动态链接库的路径
set(CMAKE_INSTALL_RPATH "lib")

# 创建一个可执行文件
add_executable(${PROJECT_NAME}
    src/main.cc
)

# 指定工程需要链接的库文件
target_link_libraries(${PROJECT_NAME}
  ${RKNN_RT_LIB}
  ${OpenCV_LIBS}
)

# 指定了程序安装的路径
set(CMAKE_INSTALL_PREFIX ${CMAKE_SOURCE_DIR}/install/${PROJECT_NAME}_${CMAKE_SYSTEM_NAME})

# 拷贝可执行程序和需要用的库以及后面测试要用到的model测试文件
install(TARGETS ${PROJECT_NAME} DESTINATION ./)
install(DIRECTORY model DESTINATION ./)
install(PROGRAMS ${RKNN_RT_LIB} DESTINATION lib)

所以目录结构如下

my_rknn_resnet/
├── 00_example/
│   ├── build.sh                  # 构建脚本
│   ├── CMakeLists.txt            # CMake 配置文件
│   ├── src/
│   │   └── main.cc               # 主程序源代码
│   ├── model/                    # 模型文件夹(用于测试)
│   └── build/                    # 构建输出目录
│       └── build_linux_aarch64/  # 具体构建输出目录
├── 3rdparty/
│   ├── librknn_api/
│   │   ├── include/              # RKNN API 头文件
│   │   └── aarch64/             # RKNN 运行时库(aarch64架构)
│   │       └── librknnrt.so     # RKNN 运行时库文件
│   └── opencv/
│       ├── share/
│       │   └── OpenCV/           # OpenCV CMake 配置文件
│       └── lib/                  # OpenCV 库文件
└── install/                      # 安装输出目录
    └── example_Linux/            # 示例安装目录

Cmake的编译方式 

1.使用cmake工具链配置文件,通常建议将工具链配置放在一个单独的文件中,以便更好地管理和重用,指定工具链配置文件进行编译

cmake -DCMAKE_TOOLCHAIN_FILE=../Toolchain-rk3588.cmake ..

2.直接编译,将配置内容直接放在Cmakelist.txt 文件中,直接cmake .. 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值