1.概要
记忆要点
cmke几个常用命令
命令 | 作用 |
cmake_minimum_required | CMake需要的最低版本号 |
set | 设置 |
project | 指定了项目的名称 |
message | 消息 |
find_package | 自动查找某库 |
add_executable | 创建一个可执行文件 |
target_link_libraries | 指定工程需要链接的库文件 |
2.分析过程
1 .cmake是什么文件
.cmake
文件通常与 CMake 这一构建系统相关。CMake 是一个跨平台的构建工具,旨在帮助开发者编写与编译器和平台无关的构建脚本。这些脚本用于生成可以在特定平台(如 Windows、Linux 或 macOS)上使用的构建文件(如 Makefile 或 Visual Studio 项目文件)。
.cmake
文件可以是以下几种类型之一:
-
CMakeLists.txt:这是最常见的
.cmake
相关文件,尽管它的扩展名不是.cmake
,但它是 CMake 的核心输入文件。它包含了项目的构建指令,如定义项目、添加源文件、设置编译选项等。 -
模块文件(*.cmake):这些文件通常包含可以被多个项目共享的代码或功能。例如,你可以有一个 FindXXX.cmake 文件,用于查找并配置某个库的使用,或者一个宏(macro)或函数(function)集合,用于简化构建脚本的编写。
-
变量和宏定义文件:一些项目可能使用单独的
.cmake
文件来定义全局变量或宏,这些可以在项目的其他 CMake 文件中引用。 -
自定义命令或脚本:有时,开发者会编写自定义的 CMake 命令或脚本,扩展 CMake 的功能,这些也通常以
.cmake
结尾。
总的来说,.cmake
文件是 CMake 构建系统的一部分,用于定义如何构建软件项目。它们包含了项目配置、依赖管理、编译和链接指令等,使得软件可以在不同的平台上以一致的方式构建。
2 工程分析
# CMake需要的最低版本号是3.4.1
cmake_minimum_required(VERSION 3.4.1)
# 指定了项目的名称
project(rknn_sanli)
# 不使用任何C编译器标志,使用C++11标准进行编译
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# rknn api
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的头文件
message(STATUS "The value of RKNN_API_PATH is: ${RKNN_API_PATH}")
message(STATUS "The value of RKNN_RT_LIB is: ${RKNN_RT_LIB}")
# opencv
set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/3rdparty/opencv/share/OpenCV) # 指定了OpenCV库的路径。
find_package(OpenCV REQUIRED) # 自动查找OpenCV库,并将相关信息保存在CMake内置变量中
file (GLOB MAIN_SRC
${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp
)
file (GLOB MAIN_HEADERS
${CMAKE_CURRENT_SOURCE_DIR}/src/*.h
)
# 指定了程序运行时查找动态链接库的路径
set(CMAKE_INSTALL_RPATH "lib")
# 创建一个可执行文件
add_executable(${PROJECT_NAME}
${MAIN_SRC} ${MAIN_HEADERS}
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)
1.基本分析
您的 CMakeLists.txt 文件已经很好地配置了项目的基本构建需求。这里是一些关键点的解释和可能的改进建议:
-
CMake 版本和项目名称:
您已经指定了所需的 CMake 最低版本为 3.4.1,并给项目命名为rknn_sanli
。这些都是基本的项目配置。 -
编译器标志:
您设置了 C 和 C++ 的编译器标志。对于 C++,您指定了使用 C++11 标准。这是合理的,但如果您不需要特别的 C 编译器标志,您其实可以省略set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
这一行,因为它只是重复设置了默认的标志。 -
RKNN API 配置:
您定义了 RKNN API 和运行时库的路径,并添加了相应的头文件目录。这是处理外部依赖的正确方式。 -
OpenCV 配置:
您指定了 OpenCV 的路径,并使用find_package
来查找 OpenCV 库。这是处理外部库的标准方法。 -
源文件和头文件的收集:
您使用file(GLOB ...)
来收集源文件和头文件。这种方法在源文件数量不多时很方便,但如果项目规模较大,建议使用更明确的方式列出每个源文件,以避免意外遗漏。 -
可执行文件创建和链接:
您创建了一个可执行文件,并指定了需要链接的库。这里有一点需要注意:${OpenCV_LIBS}
变量可能在某些版本的 OpenCV 中不是自动定义的。通常,您应该使用target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBRARIES})
(注意是OpenCV_LIBRARIES
而不是OpenCV_LIBS
)。 -
安装配置:
您设置了安装前缀,并指定了要安装的目标、模型和库文件。这是很好的实践,但请确保model
目录和${RKNN_RT_LIB}
文件确实存在于您的项目目录中。 -
改进建议:
- 确保
${OpenCV_LIBRARIES}
变量在您的 OpenCV 版本中是有效的。 - 如果可能,避免在
src/main.cc
之外再次列出源文件和头文件,除非它们不在src/*.cpp
和src/*.h
的匹配范围内。 - 考虑为库和包含目录设置缓存变量,以便在 CMake 配置时能够更灵活地指定它们。
- 确保
-
调试和测试:
- 在实际构建项目之前,运行
cmake -LA
(列出所有缓存变量及其值)来检查您的配置是否正确。 - 如果构建失败,检查编译器输出和 CMake 错误消息,以找出问题所在。
- 在实际构建项目之前,运行
总的来说,您的 CMakeLists.txt 文件已经相当完善,只需根据具体情况进行一些微调即可。
2.语句分析 opencv 库配置
# opencv
set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/3rdparty/opencv/share/OpenCV) # 指定了OpenCV库的路径。
find_package(OpenCV REQUIRED) # 自动查找OpenCV库,并将相关信息保存在CMake内置变量中
在 CMake 中配置和查找 OpenCV 库的过程,您展示的代码段是关键步骤之一。这里详细解释一下这两行代码的作用和如何在实际项目中使用它们。
1. 设置 OpenCV 目录
set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/3rdparty/opencv/share/OpenCV) |
这行代码的作用是设置 OpenCV_DIR
变量,指向 OpenCV 安装目录中的一个特定位置。在这个例子中,它指向的是您项目目录(${CMAKE_SOURCE_DIR}
)下的 3rdparty/opencv/share/OpenCV
。这个路径应包含 OpenCV 的 OpenCVConfig.cmake
文件,该文件是 CMake 查找和配置 OpenCV 所必需的。
${CMAKE_SOURCE_DIR}
:这是一个 CMake 内置变量,指向当前项目的源代码目录。3rdparty/opencv/share/OpenCV
:这是相对于源代码目录的路径,指向 OpenCV 的配置文件位置。
2. 查找 OpenCV 包
find_package(OpenCV REQUIRED) |
这行代码使用 CMake 的 find_package
函数来查找和配置 OpenCV 库。REQUIRED
参数表示 OpenCV 是项目必需的,如果找不到,CMake 将停止处理并报错。
OpenCV
:这是要查找的包的名称。CMake 将根据OpenCV_DIR
变量中指定的路径查找OpenCVConfig.cmake
。
当 find_package
成功找到并配置 OpenCV 后,它会设置一系列变量和目标,您可以在项目中使用这些变量和目标来链接 OpenCV 库和包含其头文件。例如:
OpenCV_FOUND
:一个布尔变量,表示是否找到了 OpenCV。OpenCV_INCLUDE_DIRS
:包含 OpenCV 头文件的目录。OpenCV_LIBS
:需要链接的 OpenCV 库列表。
使用示例
在您的 CMakeLists.txt 中,您可能还需要包括 OpenCV 的头文件和链接库,如下所示:
include_directories(${OpenCV_INCLUDE_DIRS}) | |
target_link_libraries(your_target_name ${OpenCV_LIBS}) |
include_directories
:告诉编译器在哪里查找头文件。target_link_libraries
:指定目标(如可执行文件或库)需要链接的库。
总结
您提供的两行代码是正确配置和使用 OpenCV 库的关键。首先设置 OpenCV_DIR
变量以指向 OpenCV 的配置目录,然后使用 find_package
查找和配置 OpenCV。之后,您就可以在项目中自由使用 OpenCV 的功能了。
3.分解分析(install)
1.cmake install
在 CMake 中,install
命令是用于指定安装规则的,这些规则定义了在构建项目后,哪些文件、目录或目标(如可执行文件、库文件等)应该被复制到指定的安装位置。cmake install
并不是一个直接运行的命令,而是在 CMakeLists.txt
文件中配置的指令,它告诉 CMake 如何执行安装过程。
要在构建后执行安装,你通常会按照以下步骤操作:
-
配置项目:首先,你需要运行 CMake 来配置你的项目。这通常涉及到在项目的根目录中创建一个构建目录,并在该目录中运行
cmake ..
(假设你的CMakeLists.txt
文件位于上一级目录)。 -
构建项目:配置完成后,你需要构建项目。这通常是通过在构建目录中运行
make
(或ninja
、msbuild
等,取决于你使用的构建工具)来完成的。 -
安装项目:项目构建完成后,你可以运行
make install
(或相应的构建工具命令,如ninja install
)来执行安装。这个命令会根据你在CMakeLists.txt
文件中定义的install
规则来复制文件、目录或目标到指定的安装位置。
在 CMakeLists.txt
文件中,你可能会看到像这样的 install
指令:
# 安装可执行文件
install(TARGETS my_executable DESTINATION bin)
# 安装库文件
install(TARGETS my_library DESTINATION lib)
# 安装目录(及其内容)
install(DIRECTORY my_directory DESTINATION share/my_project)
# 安装文件
install(FILES my_file DESTINATION etc/my_project)
# 安装脚本或程序(不常用,通常用于可执行文件或脚本)
install(PROGRAMS my_script DESTINATION bin)
在这些例子中,my_executable
、my_library
、my_directory
和 my_file
是你在项目中定义的目标或文件的名称,而 DESTINATION
参数指定了它们应该被安装到的位置。这些位置通常是相对于 CMAKE_INSTALL_PREFIX
的,你可以在运行 CMake 配置命令时通过设置 -DCMAKE_INSTALL_PREFIX=/your/install/path
来指定安装的前缀。
总之,cmake install
不是直接运行的命令,而是通过在 CMakeLists.txt
文件中配置 install
规则,并在构建项目后运行相应的构建工具命令(如 make install
)来执行的。
2.CMAKE_INSTALL_PREFIX
CMAKE_INSTALL_PREFIX
是一个在 CMake 中用于指定安装目录的变量。当你在使用 CMake 构建项目时,这个变量定义了项目构建完成后,安装文件(如可执行文件、库文件、配置文件等)应该放置的根目录。
默认情况下,CMAKE_INSTALL_PREFIX
通常被设置为系统的标准安装路径,例如在大多数 Unix 系统上,它的默认值通常是 /usr/local
。在 Windows 上,默认值可能是一个与构建目录相关的路径。
你可以通过几种方式修改 CMAKE_INSTALL_PREFIX
的值:
-
在 CMake 命令行中设置:
当你运行 CMake 配置命令(如cmake ..
)时,可以通过-D
选项来设置CMAKE_INSTALL_PREFIX
。例如:cmake -DCMAKE_INSTALL_PREFIX=/my/custom/install/path ..
-
在 CMakeLists.txt 中设置:
如果你希望在项目的 CMake 配置文件中直接设置安装前缀,你可以在CMakeLists.txt
文件中添加一行设置命令:set(CMAKE_INSTALL_PREFIX "/my/custom/install/path")
但请注意,这种做法会让安装路径固定,不如通过命令行设置灵活。
-
使用环境变量:
你也可以通过设置环境变量CMAKE_INSTALL_PREFIX
来指定安装路径。这种方法的具体实现取决于你的操作系统和 shell 环境。
使用 CMAKE_INSTALL_PREFIX
可以让你灵活地控制软件的安装位置,特别是在需要将软件安装到非标准位置或者进行打包和分发时非常有用。在安装时,CMake 会使用这个变量来确定所有安装文件的绝对路径。
3.install(TARGETS ${PROJECT_NAME} DESTINATION ./)
在 CMake 中,install(TARGETS ...)
命令用于指定构建后目标(如可执行文件或库文件)的安装规则。你给出的代码片段:
install(TARGETS ${PROJECT_NAME} DESTINATION ./) |
这行代码的意思是,将名为 ${PROJECT_NAME}
的目标(通常是在你的 CMakeLists.txt
中通过 add_executable
或 add_library
命令定义的可执行文件或库)安装到由 DESTINATION
指定的目录。在这个例子中,DESTINATION
被设置为 ./
,这通常意味着目标将被安装到与 CMAKE_INSTALL_PREFIX
相对应的目录中,但没有额外的子路径。
然而,这里有一点需要注意:通常不建议将 DESTINATION
设置为 ./
,因为这可能会导致安装时文件被放置在不应该或不需要的位置。更常见的做法是指定一个相对路径(如 bin/
、lib/
等),这样安装的文件就会被组织在相应的目录中。
例如,如果你想要将可执行文件安装到 bin
目录下,你可以这样写:
install(TARGETS ${PROJECT_NAME} DESTINATION bin/) |
这样,当运行 make install
或等效的命令时,${PROJECT_NAME}
可执行文件将被复制到 ${CMAKE_INSTALL_PREFIX}/bin/
目录中。如果你没有更改 CMAKE_INSTALL_PREFIX
的默认值,那么在 Unix 系统上,这通常意味着文件将被安装到 /usr/local/bin/
。
总之,install(TARGETS ...)
命令是 CMake 中定义安装规则的关键部分,而 DESTINATION
参数则指定了安装文件的具体位置。在设置 DESTINATION
时,应该考虑到文件的组织结构和系统的标准目录布局。
4.install(DIRECTORY model DESTINATION ./)
在 CMake 中,install(DIRECTORY ...)
命令用于指定一个目录及其内容的安装规则。你给出的代码片段:
cmake复制代码
install(DIRECTORY model DESTINATION ./) |
这行代码的意思是,将名为 model
的目录及其所有内容(包括子目录和文件)安装到由 DESTINATION
指定的位置。在这个例子中,DESTINATION
被设置为 ./
,这通常意味着目录及其内容将被安装到与 CMAKE_INSTALL_PREFIX
相对应的目录中,但没有额外的子路径。
然而,这里有几点需要注意:
-
目录的复制:当使用
install(DIRECTORY ...)
时,CMake 实际上会复制指定的目录及其所有内容到安装位置。如果model
目录中包含子目录和文件,它们都将被复制。 -
目的地路径:将
DESTINATION
设置为./
可能会导致安装时文件被放置在不应该或不需要的位置。通常,你会想要指定一个更具体的路径,比如share/${PROJECT_NAME}/model
或其他与你的项目相关的路径。 -
文件权限和属性:在复制目录和文件时,CMake 通常会尝试保留它们的原始权限和属性。但是,这取决于构建系统和安装环境的配置。
-
排除文件:如果你不想复制
model
目录中的某些文件或子目录,你可以使用PATTERN
或REGEX
选项来排除它们。
一个更典型的用法可能是这样的:
install(DIRECTORY model DESTINATION share/${PROJECT_NAME}/model) |
这样,model
目录及其内容将被复制到 ${CMAKE_INSTALL_PREFIX}/share/${PROJECT_NAME}/model
目录中。如果你没有更改 CMAKE_INSTALL_PREFIX
的默认值,在 Unix 系统上,这通常意味着文件将被安装到 /usr/local/share/${PROJECT_NAME}/model
。
总之,install(DIRECTORY ...)
命令是 CMake 中用于安装目录及其内容的强大工具,但你应该谨慎地设置 DESTINATION
参数,以确保文件被正确地安装到预期的位置。
5.install(PROGRAMS ${RKNN_RT_LIB} DESTINATION lib)
在 CMake 中,install(PROGRAMS ...)
命令通常用于安装可执行文件或脚本,而不是库文件。然而,你给出的代码片段似乎试图使用 install(PROGRAMS ...)
来安装一个被命名为 ${RKNN_RT_LIB}
的文件到 lib
目录。这里有一点需要注意:如果 ${RKNN_RT_LIB}
实际上是一个库文件(如 .so
、.a
、.dll
等),那么使用 install(TARGETS ...)
可能是更合适的选择。
不过,如果我们假设 ${RKNN_RT_LIB}
确实是一个可执行文件或脚本,并且你确实想要使用 install(PROGRAMS ...)
来安装它,那么代码应该是这样的:
install(PROGRAMS ${RKNN_RT_LIB} DESTINATION lib) |
这行代码的意思是,将 ${RKNN_RT_LIB}
(应该是一个完整的路径或相对于当前 CMakeLists.txt
文件的路径)安装到 lib
目录下。这里的 DESTINATION
参数指定了安装时的目标目录,它是相对于 CMAKE_INSTALL_PREFIX
的。
但是,有几点需要注意:
-
确保路径正确:
${RKNN_RT_LIB}
应该是一个已经构建好的可执行文件或脚本的路径。如果它是一个目标名(如通过add_executable
定义的可执行文件),你应该使用install(TARGETS ...)
而不是install(PROGRAMS ...)
。 -
文件权限:安装时的文件权限可能会受到构建系统和安装环境的影响。确保你的构建系统配置正确,以便在安装时设置适当的权限。
-
目标目录:
lib
目录通常用于存放库文件,而不是可执行文件或脚本。如果你正在安装一个可执行文件或脚本,你可能想要选择一个更合适的目录,如bin
。
如果你实际上想要安装一个库文件,你应该使用类似以下的命令:
install(TARGETS ${RKNN_RT_LIB_TARGET} DESTINATION lib) |
在这里,${RKNN_RT_LIB_TARGET}
应该是你在 CMakeLists.txt
中通过 add_library
命令定义的库目标的名称。注意,这里没有使用 PROGRAMS
,而是使用了 TARGETS
,因为 TARGETS
是用于安装由 CMake 构建的目标(如可执行文件和库文件)的正确命令。
总之,请确保你根据要安装的文件类型(可执行文件、脚本或库文件)选择正确的 CMake 命令和适当的 DESTINATION
参数。
6.target_link_libraries
target_link_libraries
是一个在 CMake 中使用的命令,它用于指定一个目标(target)需要链接的外部库或其他目标。这是 CMake 中管理项目依赖关系和库链接的关键机制之一。
基本语法
target_link_libraries(<target> [<item>...]) |
<target>
: 你想要链接库或目标的名字。这通常是用add_executable
或add_library
命令定义的可执行文件或库。<item>
: 一个或多个库名或目标名,这些是你想要链接到<target>
的。这些可以是由 CMake 管理的目标名,也可以是系统库的名字。
示例
假设你有一个库叫做 mylibrary
和一个可执行文件 myapp
,并且你想要 myapp
链接到 mylibrary
,你的 CMakeLists.txt 文件可能看起来像这样:
# 声明一个库目标
add_library(mylibrary src/mylibrary.cpp)
# 声明一个可执行文件目标
add_executable(myapp src/main.cpp)
# 使 myapp 链接到 mylibrary
target_link_libraries(myapp mylibrary)
如果 mylibrary
是一个外部库,不是由当前 CMake 项目构建的,你可以使用 target_link_libraries
直接链接它,前提是 CMake 能找到这个库。例如,如果你想要链接到一个名为 pthread
的系统库(在类 Unix 系统上通常指 POSIX 线程库),你可以这样做:
target_link_libraries(myapp pthread) |
高级用法
-
私有和公共依赖:你可以指定链接是私有的(
PRIVATE
)、公共的(PUBLIC
)还是接口(INTERFACE
)的。这影响了依赖的传播方式。PRIVATE
: 依赖仅对当前目标可见。PUBLIC
: 依赖对当前目标和依赖这个目标的其他目标可见。INTERFACE
: 依赖不对当前目标可见,但对依赖这个目标的其他目标可见。
target_link_libraries(myapp PRIVATE mylibrary)
-
链接特定构建类型的库:你可以指定只为特定的构建类型(如
debug
或release
)链接库。target_link_libraries(myapp debug mylibrary_debug optimized mylibrary_release)
-
使用生成器表达式:你可以使用生成器表达式来根据配置或其他条件动态地设置链接的库。
target_link_libraries(myapp "$<$<CONFIG:Debug>:mylibrary_debug>")
注意事项
- 确保在调用
target_link_libraries
之前,相关的目标或库已经被声明(通过add_executable
,add_library
等)。 - 当链接外部库时,确保 CMake 能找到这些库。可能需要使用
find_package
或手动设置库的路径。
target_link_libraries
是 CMake 中一个非常强大和灵活的命令,正确地使用它可以帮助你更好地管理项目中的依赖关系和库链接。
7.语句分析
# 指定工程需要链接的库文件
target_link_libraries(${PROJECT_NAME}
${RKNN_RT_LIB}
${OpenCV_LIBS}
)
在您提供的 CMake 代码片段中,target_link_libraries
命令被用来指定一个名为 ${PROJECT_NAME}
的目标(通常是一个可执行文件或库)需要链接的库文件。这里,${RKNN_RT_LIB}
和 ${OpenCV_LIBS}
是两个变量,它们应该在这段代码之前被定义,并指向相应的库文件或库名。
解释
${PROJECT_NAME}
:- 这是一个变量,通常通过
project()
命令在 CMakeLists.txt 文件的开头设置。它代表您的项目的名称,也经常被用作生成的目标(如可执行文件或库)的名称。
- 这是一个变量,通常通过
${RKNN_RT_LIB}
:- 这是一个变量,指向您想要链接的 RKNN 运行时库(假设 RKNN 是一个某种神经网络库)。这个变量应该在这段代码之前通过某种方式(如
find_library
、set
命令或从一个外部 CMake 模块导入)被设置为正确的库路径或库名。
- 这是一个变量,指向您想要链接的 RKNN 运行时库(假设 RKNN 是一个某种神经网络库)。这个变量应该在这段代码之前通过某种方式(如
${OpenCV_LIBS}
:- 这是一个变量,指向 OpenCV 库。OpenCV 是一个流行的开源计算机视觉库。同样,这个变量应该在这段代码之前被设置为包含 OpenCV 库的正确路径或库名。通常,如果您使用
find_package(OpenCV REQUIRED)
来查找 OpenCV,CMake 会自动设置相关的变量,包括OpenCV_LIBS
(尽管实际变量名可能因 OpenCV 版本和 CMake 配置而异)。
- 这是一个变量,指向 OpenCV 库。OpenCV 是一个流行的开源计算机视觉库。同样,这个变量应该在这段代码之前被设置为包含 OpenCV 库的正确路径或库名。通常,如果您使用
示例
假设您的 CMakeLists.txt 文件看起来像这样:
cmake_minimum_required(VERSION 3.10)
project(MyProject)
# 查找 OpenCV
find_package(OpenCV REQUIRED)
# 假设 RKNN 库位于某个已知路径
set(RKNN_RT_LIB "/path/to/rknn_rt.lib") # 对于 Windows 的 .lib 文件
# 或者对于 Linux/Unix 系统,可能是这样:
# set(RKNN_RT_LIB "rknn_rt") # 假设库名为 rknn_rt,并且 CMake 能在标准库路径中找到它
# 添加您的可执行文件
add_executable(MyProject main.cpp)
# 链接库
target_link_libraries(MyProject
${RKNN_RT_LIB}
${OpenCV_LIBS}
)
在这个例子中,MyProject
是您的项目名称,也是生成的可执行文件的名称。CMake 将确保在构建 MyProject
可执行文件时链接到指定的 RKNN 运行时库和 OpenCV 库。
注意事项
- 确保
${RKNN_RT_LIB}
和${OpenCV_LIBS}
变量在这段代码之前被正确设置。 - 如果您的项目跨平台,您可能需要为不同的操作系统设置不同的库路径或库名。
- 如果 RKNN 或 OpenCV 库是动态链接库(如 .so 文件或 .dll 文件),确保它们在运行时可用。
- 如果使用
find_package
来查找 OpenCV,确保您的 CMake 环境配置正确,以便能够找到 OpenCV 包。
8.find_package
find_package
是 CMake 中的一个指令,用于查找并导入外部项目或库的配置信息。这个指令非常强大,它允许你的 CMake 项目轻松地与第三方库进行集成,而无需手动指定这些库的路径和编译选项。
当使用 find_package
查找 OpenCV 时,CMake 会尝试在系统的标准位置(如 /usr/local
或 C:/Program Files
)以及用户指定的额外位置中查找 OpenCV 的安装。如果找到了 OpenCV,CMake 会设置一组变量,这些变量包含了 OpenCV 的头文件路径、库文件路径和编译选项等信息。
以下是一个使用 find_package
查找 OpenCV 的基本示例:
cmake_minimum_required(VERSION 3.10)
project(MyOpenCVProject)
# 查找 OpenCV 包,指定 REQUIRED 表示如果找不到 OpenCV 则停止处理
find_package(OpenCV REQUIRED)
# 如果找到了 OpenCV,则包含其头文件目录
if(OpenCV_FOUND)
include_directories(${OpenCV_INCLUDE_DIRS})
endif()
# 添加可执行文件
add_executable(MyExecutable main.cpp)
# 链接 OpenCV 库到可执行文件
target_link_libraries(MyExecutable ${OpenCV_LIBS})
在这个示例中,find_package(OpenCV REQUIRED)
指令会尝试查找 OpenCV。如果找到了,OpenCV_FOUND
变量会被设置为 TRUE
,并且 OpenCV_INCLUDE_DIRS
和 OpenCV_LIBS
变量会被设置为包含 OpenCV 头文件和库文件的路径。然后,你可以使用 include_directories
和 target_link_libraries
指令来将这些路径添加到你的项目中。
需要注意的是,OpenCV_LIBS
变量通常包含了所有常用的 OpenCV 模块(如 opencv_core
, opencv_imgproc
, opencv_highgui
等)。但是,如果你的项目只需要部分模块,你可以手动指定要链接的模块,例如:
target_link_libraries(MyExecutable ${OpenCV_LIBS} opencv_core opencv_imgproc) |
另外,如果你的 OpenCV 安装在非标准路径下,你可以使用 CMAKE_PREFIX_PATH
变量来指定 OpenCV 的安装前缀,或者通过设置 OpenCV_DIR
变量来直接指定 OpenCV 的配置文件(通常是 OpenCVConfig.cmake
)的路径。例如:
set(CMAKE_PREFIX_PATH "/path/to/opencv")
# 或者
set(OpenCV_DIR "/path/to/opencv/build")
这样,CMake 就会在指定的路径中查找 OpenCV 的配置信息。
9.OpenCV_LIBS
在 CMake 中使用 OpenCV 时,你通常会需要链接 OpenCV 的库到你的项目中。OpenCV_LIBS
是一个变量,它在一些旧的教程或示例代码中可能被用来代表需要链接的 OpenCV 库列表。然而,在现代的 OpenCV 和 CMake 集成中,更推荐使用 OpenCV 提供的 CMake 配置和目标导入功能。
以下是一个基本的示例,展示如何在 CMake 项目中配置和使用 OpenCV:
-
找到 OpenCV 包
首先,你需要确保 CMake 能够找到 OpenCV。这通常通过
find_package
指令实现:find_package(OpenCV REQUIRED)
这条指令会搜索你的系统和 CMake 模块路径,以找到 OpenCV 的配置。
REQUIRED
选项表示如果找不到 OpenCV,配置过程将失败。 -
包含 OpenCV 的头文件
在你的源代码文件中,你需要包含 OpenCV 的头文件,例如:
#include <opencv2/opencv.hpp>
-
链接 OpenCV 的库
在 CMakeLists.txt 中,你需要将 OpenCV 的库链接到你的可执行文件或库。由于 OpenCV 4.x 及以后版本使用了目标导出的方式,你应该使用目标链接而不是直接指定库文件。这可以通过
target_link_libraries
指令实现:add_executable(your_executable your_source_files)
target_link_libraries(your_executable ${OpenCV_LIBS}) # 旧方式,不推荐
更现代和推荐的方式是直接链接 OpenCV 导出的目标,如:
add_executable(your_executable your_source_files)
target_link_libraries(your_executable opencv_core opencv_imgproc opencv_highgui opencv_imgcodecs) # 根据你的需要选择具体的模块
或者,如果 OpenCV 是通过
find_package
以配置模式找到的(这通常是现代 OpenCV 安装的情况),你可以简单地链接它导出的总目标(如果可用):target_link_libraries(your_executable opencv::opencv) # 链接所有 OpenCV 模块
或者链接特定的模块,如:
target_link_libraries(your_executable opencv::core opencv::imgproc opencv::highgui) # 只链接指定的模块
注意,根据你的 OpenCV 安装版本和配置,具体的细节可能有所不同。始终参考你正在使用的 OpenCV 版本的官方文档以获取最准确的信息。
10.OpenCV_LIBS是系统变量吗?是在什么时候设置的?是安装的时候设置的吗?
OpenCV_LIBS通常不是系统环境变量,而是在CMake配置OpenCV项目时,CMake通过find_package(OpenCV)
指令自动设置或识别的一个CMake变量。这个变量(如果确实在CMakeLists.txt中被显式使用的话)可能包含了OpenCV库的一系列路径或目标名称,用于链接OpenCV库到你的项目中。
然而,需要明确的是,在现代的OpenCV和CMake集成实践中,直接使用OpenCV_LIBS
变量的情况已经比较少见。相反,CMake提供了更加灵活和强大的方式来管理项目依赖,包括通过target_link_libraries
指令链接OpenCV导出的目标。这些目标名称通常以opencv::
为前缀,如opencv::core
、opencv::imgproc
等,代表OpenCV的不同模块。
关于OpenCV_LIBS
的设置时机,它并不是在安装OpenCV时设置的。相反,它是在CMake配置你的项目时,CMake通过解析OpenCV的配置文件(如OpenCVConfig.cmake
)来动态生成的。这个过程发生在CMakeLists.txt文件被CMake处理时,通常是在你运行CMake命令(如cmake ..
)来配置你的项目时发生的。
如果你在你的CMakeLists.txt文件中看到了OpenCV_LIBS
变量,那么这很可能是旧代码或特定项目配置的一部分。对于新的项目或遵循现代CMake实践的项目,建议直接使用OpenCV导出的目标进行链接,以获得更好的依赖管理和跨平台兼容性。
总结来说,OpenCV_LIBS
通常不是系统环境变量,而是在CMake配置OpenCV项目时由CMake动态生成的一个CMake变量(尽管其使用已经较少见)。它的设置时机是在CMake配置项目时,而不是在安装OpenCV时。对于新的项目,建议使用OpenCV导出的目标进行链接。
3.CMake的常用内置变量有多少
CMake的常用内置变量数量众多,这些变量在构建过程的各个阶段发挥着重要作用,包括获取系统信息、控制构建行为以及配置项目等。以下是一些常用的CMake内置变量:
一、系统信息相关变量
- CMAKE_SYSTEM_NAME:操作系统的名称(如 Windows, Linux, Darwin 等)。
- CMAKE_SYSTEM_VERSION:操作系统的版本号。
- CMAKE_SYSTEM_PROCESSOR:当前系统的处理器架构(如 x86_64, arm, aarch64)。
- CMAKE_HOST_SYSTEM_NAME:CMake 所在主机的操作系统名称(编译主机的系统)。
- CMAKE_HOST_SYSTEM_VERSION:CMake 所在主机的操作系统版本。
- CMAKE_HOST_SYSTEM_PROCESSOR:CMake 所在主机的处理器架构。
- CMAKE_MAJOR_VERSION、CMAKE_MINOR_VERSION、CMAKE_PATCH_VERSION:CMake 的主版本号、次版本号和补丁等级。
- UNIX、WIN32:在类 UNIX 和 Win32 平台下分别为 TRUE。
二、项目信息相关变量
- CMAKE_PROJECT_NAME:顶层项目的名称。
- CMAKE_PROJECT_VERSION:项目的版本号(需要在 CMakeLists.txt 中定义 project 时设置 VERSION)。
- PROJECT_NAME:当前项目的名称(如果在子目录中使用时,它表示当前目录的项目名称)。
- CMAKE_SOURCE_DIR:顶层 CMakeLists.txt 所在的源代码目录路径。
- CMAKE_BINARY_DIR:构建文件的输出目录,即 CMake 生成的二进制文件所在的路径。
- CMAKE_CURRENT_SOURCE_DIR:当前处理的 CMakeLists.txt 文件所在的源代码目录。
- CMAKE_CURRENT_BINARY_DIR:当前处理的 CMakeLists.txt 文件的构建目录。
- PROJECT_SOURCE_DIR:当前项目的源代码目录路径。
- PROJECT_BINARY_DIR:当前项目的构建目录路径。
三、编译器和编译选项相关变量
- CMAKE_C_COMPILER:C 编译器的路径。
- CMAKE_CXX_COMPILER:C++ 编译器的路径。
- CMAKE_C_FLAGS:C 编译器的编译选项。
- CMAKE_CXX_FLAGS:C++ 编译器的编译选项。
- CMAKE_EXE_LINKER_FLAGS:链接器的链接选项。
- CMAKE_C_STANDARD:指定 C 标准版本(如 11, 17)。
- CMAKE_CXX_STANDARD:指定 C++ 标准版本(如 11, 14, 17, 20)。
四、构建和安装相关变量
- CMAKE_BUILD_TYPE:指定编译类型,如 Debug, Release, MinSizeRel, RelWithDebInfo。
- CMAKE_INSTALL_PREFIX:指定 make install 时安装的根目录路径。
- CMAKE_LIBRARY_OUTPUT_DIRECTORY:共享库的输出目录。
- CMAKE_ARCHIVE_OUTPUT_DIRECTORY:静态库的输出目录。
- CMAKE_RUNTIME_OUTPUT_DIRECTORY:可执行文件的输出目录。
- BUILD_SHARED_LIBS:控制默认生成共享库还是静态库。
五、其他常用变量
- CMAKE_COMMAND:CMake 命令的路径。
- CMAKE_MAKE_PROGRAM:生成的构建系统中使用的 make 命令的路径(例如 make, ninja)。
- CMAKE_MODULE_PATH:指定 include 或 find_package 命令查找的路径。
- CMAKE_ERROR_DEPRECATED、CMAKE_WARN_DEPRECATED:控制废弃功能的使用是否报错或警告。
需要注意的是,这些变量只是CMake众多内置变量中的一部分,CMake还提供了许多其他用于不同场景和需求的内置变量。由于CMake的不断发展,新的变量可能会被引入,而旧的变量可能会被弃用,因此建议查阅最新的CMake文档以获取最准确和最新的信息。
4.CMake关于opencv的内置变量有多少
CMake本身并没有专门针对OpenCV的内置变量,因为内置变量通常是CMake系统为了支持通用构建过程而定义的,并不特定于某个库(如OpenCV)。然而,在使用CMake配置OpenCV库时,会用到一些CMake的内置变量来指定路径、编译选项等,同时也会通过find_package(OpenCV)
命令查找OpenCV并设置一系列与OpenCV相关的变量,这些变量虽然不是CMake的内置变量,但对于OpenCV的配置和使用非常重要。
当find_package(OpenCV)
命令成功找到并配置OpenCV库后,它会设置一系列与OpenCV相关的变量,这些变量可以在CMakeLists.txt文件中使用,以便包含OpenCV的头文件、链接OpenCV的库等。以下是一些常用的与OpenCV相关的变量,这些变量虽然不是CMake的内置变量,但在使用OpenCV时经常会被用到:
-
OpenCV_FOUND:布尔变量,表示OpenCV是否已经被找到。
-
OpenCV_INCLUDE_DIRS:包含OpenCV头文件的目录列表。
-
OpenCV_LIBRARIES(或在某些情况下是OpenCV_LIBS):需要链接的OpenCV库列表。
-
OpenCV_VERSION:OpenCV的版本号。
-
OpenCV_CONFIG_PATH:指向OpenCVConfig.cmake或类似配置文件的路径。
-
OpenCV_CXX_FLAGS(非标准,但可能由某些OpenCV配置脚本设置):与OpenCV相关的C++编译选项。
需要注意的是,这些变量的具体名称可能会因OpenCV版本的不同而有所差异。此外,OpenCV的某些特定模块或组件可能还会设置额外的变量。
除了通过find_package(OpenCV)
命令设置的变量外,用户还可以根据需要自定义变量来指定OpenCV的安装路径、编译选项等。例如,在CMakeLists.txt文件中使用set(OpenCV_DIR "/path/to/opencv")
命令来指定OpenCV的安装路径,以便find_package(OpenCV)
命令能够正确地找到并配置OpenCV库。
总之,CMake本身并没有专门针对OpenCV的内置变量,但通过使用find_package(OpenCV)
命令和自定义变量,用户可以灵活地配置和使用OpenCV库。
5. CMake的函数有多少
CMake的函数数量并没有一个固定的数字,因为CMake的功能和扩展性非常强,它提供了大量的内置函数和宏,同时用户也可以根据自己的需求定义自定义函数。以下是一些CMake中常用的函数和它们的简要描述:
常用内置函数
-
message():用于向终端打印消息,帮助调试CMake脚本。
-
project():用于定义项目名称,可以设置项目支持的语言等。
-
add_executable():用于添加一个可执行文件构建目标,指定源文件列表。
-
add_library():用于添加一个库文件构建目标,可以是静态库或动态库,指定源文件列表。
-
include_directories():用于添加头文件搜索路径。
-
target_include_directories():为指定的目标添加头文件搜索路径,可以指定是公共、私有还是接口路径。
-
find_package():用于查找并加载外部包,如Boost、OpenCV等,设置相关变量。
-
link_directories():添加库文件搜索路径(注意:现代CMake推荐使用target_link_libraries()代替)。
-
target_link_libraries():用于为目标(可执行文件或库)指定链接时需要的库文件。
-
set():用于设置变量的值。
-
if() / else() / endif():用于条件判断。
-
foreach() / endforeach():用于遍历列表或范围。
-
file():用于执行文件操作,如读取文件列表、复制文件等。
-
add_subdirectory():用于添加子目录,CMake会递归地处理子目录中的CMakeLists.txt文件。
-
install():用于指定安装规则,如安装可执行文件、库文件、头文件等。
-
target_compile_features():用于指定目标的语言特性。
扩展性和自定义函数
CMake还允许用户定义自定义函数。自定义函数可以通过function()
命令定义,并在CMakeLists.txt文件或其他包含的文件中使用。这些自定义函数可以执行复杂的逻辑,封装重复的代码,提高CMake脚本的可维护性。
总结
由于CMake的灵活性和扩展性,其内置函数数量众多,且不断有新函数和特性被添加。同时,用户还可以定义自定义函数来满足特定需求。因此,无法给出一个准确的CMake函数数量。在实际使用中,建议查阅CMake的官方文档或社区资源来了解更多关于CMake函数的信息。
6.CMake自定义变量如何设置,请举例
在CMake中,自定义变量是通过set
命令来设置的。这些变量可以用于存储路径、文件名、编译选项等信息,以便在CMake脚本中重复使用。以下是一个设置自定义变量的简单例子:
# 设置一个自定义变量 MY_VARIABLE,赋值为 "Hello, World!"
set(MY_VARIABLE "Hello, World!")
# 输出自定义变量的值,用于调试
message(STATUS "MY_VARIABLE: ${MY_VARIABLE}")
# 你可以在其他地方使用这个变量,比如作为编译选项或源文件路径
# 这里只是一个简单的例子,实际上你可能会根据变量的值来配置项目
在这个例子中,我们定义了一个名为MY_VARIABLE
的自定义变量,并将其值设置为"Hello, World!"
。然后,我们使用message
命令输出这个变量的值,以便在CMake配置过程中查看。
更实际的例子可能是设置源文件路径、库路径或编译选项:
# 设置源文件目录
set(SOURCE_DIR "${CMAKE_SOURCE_DIR}/src")
# 设置编译选项
set(COMPILE_OPTIONS "-Wall -Wextra -pedantic")
# 添加可执行文件,并使用自定义变量指定源文件
add_executable(MyExecutable "${SOURCE_DIR}/main.cpp" "${SOURCE_DIR}/utils.cpp")
# 为可执行文件设置编译选项
target_compile_options(MyExecutable PRIVATE ${COMPILE_OPTIONS})
在这个例子中,我们定义了SOURCE_DIR
和COMPILE_OPTIONS
两个自定义变量,分别用于指定源文件目录和编译选项。然后,我们使用这些变量来配置可执行文件的构建。
需要注意的是,自定义变量的命名应遵循一定的规范,以避免与CMake的内置变量或其他项目的变量发生冲突。通常,建议使用项目名称或特定功能的前缀来命名自定义变量。
3.相关链接
qt工程的 cmake modules文件夹一版是干啥用的-CSDN博客