cmake详细教程(二)
admin
2024-01-20 18:30:04
0

一、参考资料

CMake 入门实战 | HaHack

Cmake入门和MindsporeLite Cmake文件分析 | 摸黑干活 (fazzie-key.cool)

GitHub - wzpan/cmake-demo: 《CMake入门实战》源码

User Interaction Guide — CMake 3.20.6 Documentation

Home · Wiki · CMake / Community · GitLab (kitware.com)

cmake的一些小经验 - 驭风万里无垠 - C++博客 (cppblog.com)

二、相关介绍

1. CMake预定义变量

CMake中常用的预定义变量

项目示例

D:\MyDocuments\cache\Demo>tree
.
├─build
│  ├─bin
│  └─lib
├─example
└─src├─base├─http└─net

PROJECT_NAME

通过PROJECT指定的项目名称:

project(Demo)

PROJECT_SOURCE_DIR

工程的根目录,项目示例中的Demo目录。

PROJECT_BINARY_DIR

执行cmake命令的目录,一般是在build目录,在此目录执行cmake ..

CMAKE_CURRENT_SOURCE_DIR

当前CMakeLists.txt文件所在目录。

CMAKE_CURRENT_BINARY_DIR

编译目录,可使用ADD_SUBDIRECTORY来修改此变量。

# 添加cmake执行子目录
ADD_SUBDIRECTORY(example)

EXECUTABLE_OUTPUT_PATH

二进制可执行文件输出位置。

# 设置可执行文件的输出路径为 build/bin
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

LIBRARY_OUTPUT_PATH

库文件输出位置。

set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

常用系统信息变量

liulinjun@LAPTOP-4DTD5D42:~$ cmake --version
cmake version 3.11.2

CMAKE_MAJOR_VERSION: cmake的主版本号cmake version 3.11.2中的3
CMAKE_MINOR_VERSION: cmake的次版本号cmake version 3.11.2中的11
CMAKE_PATCH_VERSION: cmake的补丁等级cmake version 3.11.2中的2

CMAKE_SYSTEM: 系统名称,带版本号;
CMAKE_SYSTEM_NAME: 系统名称,不带版本号;
CMAKE_SYSTEM_VERSION: 系统版本号;
CMAKE_SYSTEM_PROCESSOR: 处理器名称;

BUILD_SHARED_LIBS

默认的库编译方式(shared or static),默认为static,一般在ADD_LIBRARY时直接指定编译库的类型。

CMAKE_C_FLAGS

设置C编译选项。

SET(CMAKE_C_FLAGS_PUBLIC "-mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 -ffunction-sections -mno-unaligned-access -fno-aggressive-loop-optimizations -mapcs-frame -rdynamic")
SET(CMAKE_C_FLAGS_DEBUG "-Wall -ggdb3 -DNM_DEBUG ${CMAKE_C_FLAGS_PUBLIC}")
SET(CMAKE_C_FLAGS_RELEASE  "-Wall -O3  ${CMAKE_C_FLAGS_PUBLIC}")

CMAKE_CXX_FLAGS

设置C++编译选项。

  • CMAKE_CXX_FLAGS_DEBUG: 设置编译类型为Debug时的编译选项;
  • CMAKE_CXX_FLAGS_RELEASE: 设置编译类型为Release时的编译选项;

CMAKE_CXX_COMPILER

设置C++编译器。

# 设置C++编译器为g++
set(CMAKE_CXX_COMPILER "g++")
# 设置标准库版本为c++17 并开启警告
set(CMAKE_CXX_FLAGS "-std=c++17 -Wall")
# 设置Debug模式下,不开启优化,开启调试,生成更详细的gdb调试信息
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g -ggdb")
# 设置Release模式下,开启最高级优化
set(CMAKE_CXX_FLAGS_RELEASE "-O3")

2. CMake语法

STREQUAL

STREQUAL 用于比较字符串,相同返回 true

if(NOT("${X86_64_SIMD}" STREQUAL "sse" OR "${X86_64_SIMD}" STREQUAL "avx" OR "${X86_64_SIMD}" STREQUAL "avx512"))set(KERNEL_SRC_SSE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/fp32/convolution_im2col_sse_fp32.cc${CMAKE_CURRENT_SOURCE_DIR}/fp32/matmul_fp32_sse.cc${CMAKE_CURRENT_SOURCE_DIR}/fp32/convolution_winograd_sse_fp32.cc)list(REMOVE_ITEM KERNEL_SRC ${KERNEL_SRC_SSE_FILE})
endif()

3. 缓存变量

CMake语法—缓存变量(Cache Variable)

3.1 CMake缓存变量

  • Normal Variable,普通变量,相当于一个局部变量。在同一个CMake工程中使用,会有作用域限制或区分。

  • Cache Variable,缓存变量,相当于一个全局变量。在同一个CMake工程中任何地方都可以使用。

3.2 定义格式

set( ... CACHE   [FORCE])

参数解释

  • variable:变量名称;
  • value:变量值列表;
  • CACHE:cache变量的标志;
  • type:变量类型,取决于变量的值。类型分为:BOOL、FILEPATH、PATH、STRING、INTERNAL;
  • docstring:必须是字符串,作为变量概要说明;
  • FORCE:强制选项,强制修改变量值;

示例

set(MSLITE_REGISTRY_DEVICE "off" CACHE STRING "Compile Mindspore Lite that supports specific devices, currently supported devices: Hi3516D/Hi3519A/Hi3559A/SD3403")

3. 注意事项

  1. 缓存变量,本质是全局变量,可以把缓存变量当做C、C++中的全局变量理解即可。类比法理解与体会,更易于学习与应用。
  2. 缓存变量,都会存储在CMakeCache.txt文件中,当你确认某个变量是缓存变量时,理论上你一定可以在CMakeCache.txt中找到此变量的记录项。
  3. CMakeCache.txt文件中,还有很多默认的缓存变量,可自行查看与分析研究。
  4. 缓存变量发生问题,一定记得先删除build目录下的CMakeCache.txt文件,然后重新配置项目。

4. 环境变量(ENV)

CMake语法—环境变量(Environment Variable)

4.1 定义格式

set(ENV{} [])

参数解释

  • ENV:环境变量标志性前缀;
  • variable:变量名称;
  • value:变量值;

示例

# 定义环境变量
set(ENV{CMAKE_PATH} "F:/cmake")# 判断CMAKE_PATH环境变量是否定义
if(DEFINED ENV{CMAKE_PATH})message("CMAKE_PATH_1: $ENV{CMAKE_PATH}")
else()message("NOT DEFINED CMAKE_PATH VARIABLES")
endif()

4.2 CMakeLists.txt示例

cmake_minimum_required(VERSION 3.18)# 设置工程名称
set(PROJECT_NAME KAIZEN)# 设置工程版本号
set(PROJECT_VERSION "1.0.0.10" CACHE STRING "默认版本号")# 工程定义
project(${PROJECT_NAME}LANGUAGES CXX CVERSION ${PROJECT_VERSION}
)# 打印开始日志
message(STATUS "\n########## BEGIN_TEST_ENV_VARIABLE")# 判断JAVA_HOME变量是否定义
if(DEFINED ENV{JAVA_HOME})message("JAVA_HOME: $ENV{JAVA_HOME}")
else()message("NOT DEFINED JAVA_HOME VARIABLES")
endif()# 定义环境变量
set(ENV{CMAKE_PATH} "F:/cmake")# 判断CMAKE_PATH环境变量是否定义
if(DEFINED ENV{CMAKE_PATH})message("CMAKE_PATH_1: $ENV{CMAKE_PATH}")
else()message("NOT DEFINED CMAKE_PATH VARIABLES")
endif()# 定义测试函数,在函数中新定义环境变量
function(test_env_variable)# 访问环境变量CMAKE_PATHmessage("CMAKE_PATH_2: $ENV{CMAKE_PATH}")# 函数内定义环境变量set(ENV{CMAKE_FUNC} "F:/cmake/dir")# 判断CMAKE_FUNC环境变量是否定义if(DEFINED ENV{CMAKE_FUNC})message("CMAKE_FUNC_1: $ENV{CMAKE_FUNC}")else()message("NOT DEFINED CMAKE_FUNC_1 VARIABLES")endif()
endfunction()# 调用函数
test_env_variable()# 判断CMAKE_FUNC环境变量是否定义
if(DEFINED ENV{CMAKE_FUNC})message("CMAKE_FUNC_2: $ENV{CMAKE_FUNC}")
else()message("NOT DEFINED CMAKE_FUNC_2 VARIABLES")
endif()# 如果没有参数值
set(ENV{CMAKE_FUNC})# 判断CMAKE_FUNC环境变量是否定义
if(DEFINED ENV{CMAKE_FUNC})message("CMAKE_FUNC_3: $ENV{CMAKE_FUNC}")
else()message("NOT DEFINED CMAKE_FUNC_3 VARIABLES")
endif()# 定义测试宏,在函数中新定义环境变量
macro(test_env_var)# 访问环境变量CMAKE_PATHmessage("CMAKE_PATH_3: $ENV{CMAKE_PATH}")# 宏内定义环境变量set(ENV{CMAKE_MACRO} "F:/cmake/macro")# 判断CMAKE_MACRO环境变量是否定义if(DEFINED ENV{CMAKE_MACRO})message("CMAKE_MACRO_1: $ENV{CMAKE_MACRO}")else()message("NOT DEFINED CMAKE_MACRO_1 VARIABLES")endif()
endmacro()# 调用宏
test_env_var()# 判断CMAKE_MACRO环境变量是否定义
if(DEFINED ENV{CMAKE_MACRO})message("CMAKE_MACRO_2: $ENV{CMAKE_MACRO}")
else()message("NOT DEFINED CMAKE_MACRO_2 VARIABLES")
endif()# 如果多个参数值
set(ENV{CMAKE_FILE} "F:/cmake/cmake1.txt" "F:/cmake/cmake2.txt")# 判断CMAKE_FILE环境变量是否定义
if(DEFINED ENV{CMAKE_FILE})message("CMAKE_FILE: $ENV{CMAKE_FILE}")
else()message("NOT DEFINED CMAKE_FILE VARIABLES")
endif()# 打印结束日志
message(STATUS "########## END_TEST_ENV_VARIABLE\n")

输出结果

-- Selecting Windows SDK version 10.0.18362.0 to target Windows 10.0.17763.
-- The CXX compiler identification is MSVC 19.0.24245.0
-- The C compiler identification is MSVC 19.0.24245.0
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/amd64/cl.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
--
########## BEGIN_TEST_ENV_VARIABLE
JAVA_HOME: C:\Program Files\Java\jdk1.8.0_201
CMAKE_PATH_1: F:/cmake
CMAKE_PATH_2: F:/cmake
CMAKE_FUNC_1: F:/cmake/dir
CMAKE_FUNC_2: F:/cmake/dir
NOT DEFINED CMAKE_FUNC_3 VARIABLES
CMAKE_PATH_3: F:/cmake
CMAKE_MACRO_1: F:/cmake/macro
CMAKE_MACRO_2: F:/cmake/macro
CMake Warning (dev) at CMakeLists.txt:98 (set):Only the first value argument is used when setting an environment variable.Argument 'F:/cmake/cmake2.txt' and later are unused.
This warning is for project developers.  Use -Wno-dev to suppress it.CMAKE_FILE: F:/cmake/cmake1.txt
-- ########## END_TEST_ENV_VARIABLE-- Configuring done
-- Generating done
-- Build files have been written to: F:/learn_cmake/build
请按任意键继续. . .

5. gcc/g++编译(无CMake)

5.1 单文件编译

对于单文件"hello.cpp",
生成hello(hello.exe)所需要执行的bash命令:

gcc -v -o hello hello.c

5.2 多文件编译(无依赖)

但当涉及多文件编译时,我们的命令会十分复杂,比如一个main.cpp文件依赖于Foo1.cpp,Foo2.cpp,…Foo10,我们需要先将这10个文件编译成.o文件,再将各.o文件和main.o进行链接,代码如下:

g++ -std=c++17 -O2 -o Foo1.o -c Foo1.cpp
g++ -std=c++17 -O2 -o Foo2.o -c Foo2.cpp
g++ -std=c++17 -O2 -o Foo3.o -c Foo3.cpp
g++ -std=c++17 -O2 -o Foo4.o -c Foo4.cpp
g++ -std=c++17 -O2 -o Foo5.o -c Foo5.cpp
g++ -std=c++17 -O2 -o Foo6.o -c Foo6.cpp
g++ -std=c++17 -O2 -o Foo7.o -c Foo7.cpp
g++ -std=c++17 -O2 -o Foo8.o -c Foo8.cpp
g++ -std=c++17 -O2 -o Foo9.o -c Foo9.cpp
g++ -std=c++17 -O2 -o Foo10.o -c Foo10.cpp
g++ -std=c++17 -O2 -o main.o -c main.cpp
g++ -std=c++17 -O2 main.o Foo1.o Foo2.o Foo3.o Foo4.o Foo5.o Foo6.o Foo7.o Foo8.o Foo9.o Foo10.o -o main

5.3 多文件编译(有依赖)

上述编译过程还算简单,因为各子文件还不相互依赖,但如果子文件有相互依赖关系,比如foo1.cpp依赖于foo10.cpp我们编译的顺序有必须更改,在文件数目更大的工程中,一行一行输入命令进行编译是不现实的,所以我们引入了Makefile,对于上述编译任务,我们的MakeFile如下,我们只需输入make一句命令即可完成编译。

COMPILER = g++ -std=c++17 -O2 -I./include  
OBJECTS = Foo1.o Foo2.o Foo3.o Foo4.o Foo5.o Foo6.o Foo7.o Foo8.o Foo9.o Foo10.o main.o
TARGET = main$(TARGET): $(OBJECTS)$(COMPILER) -o $@ $^ -lprotobuf
$(OBJECTS): %.o: %.cpp$(COMPILER) -o $@ -c $<
$(DEPENDENCIES): %.d: %.cpp$(COMPILER) -o $@ -MM $

5.4 总结

Makefile 规定了一套编译规则,使用什么编译器,编译器使用什么样的编译选项,每个文件都有什么依赖关系。在编译的时候,能够直接根据 makefile 来确定哪些文件依赖于其他的哪些文件,从而把编译顺序、需不需要重新编译以及链接都自动检测出来。在Linux环境下,MakeFile本身可以看做一个shell脚本。

三、CMake编译

1. 问题引入

既然我们有了MakeFile,又为什么需要Cmake工具?对于不同环境下的编译,有着多种Make工具,例如 GNU Make ,QT 的 qmake ,微软的 MS nmake,BSD Make(pmake),Makepp,等等。这些 Make 工具遵循着不同的规范和标准,所执行的 Makefile 格式也千差万别。这样就带来了一个严峻的问题:如果软件想跨平台,必须要保证能够在不同平台编译。而如果使用上面的 Make 工具,就得为每一种标准写一次 Makefile,这将是一件让人抓狂的工作。

CMake 就是针对上面问题所设计的工具:它首先允许开发者编写一种平台无关的 CMakeList.txt 文件来定制整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化 Makefile 和工程文件,如 Unix 的 Makefile 或 Windows 的 Visual Studio 工程。从而做到“Write once, run everywhere”。显然,CMake 是一个比上述几种 make 更高级的编译配置工具。一些使用 CMake 作为项目架构系统的知名开源项目有 VTK、ITK、KDE、OpenCV、OSG 等 [1]。

对于深度学习框架而言,跨平台是一件非常重要的事,因为深度学习模型可能在不同的环境下运行,可能是x86的Linux或者Windows,也可能是ARM,涉及到跨平台交叉编译。

2. CMake流程

在 linux 平台下使用 CMake 生成 Makefile 并编译的流程如下:

  1. 编写 CMake 配置文件 CMakeLists.txt 。
  2. 执行命令 cmake PATH 或者 ccmake PATH 生成 Makefile(ccmakecmake 的区别在于前者提供了一个交互式的界面)。其中, PATH 是 CMakeLists.txt 所在的目录。
  3. 使用 make 命令进行编译。

2.1 单文件CmakeLists

单文件CmakeLists,执行命令后会编译一个名为Demo的 exe文件。

# CMake 最低版本号要求
cmake_minimum_required (VERSION 2.8)# 项目信息
project (mindsporelite)# 指定生成目标
add_executable(mindsporelite main.cc)

如果把add_executable改成add_library,那么会生成一个的静态或者动态库。

# 生成动态库
add_library(mindsporelite SHARED main.cc)
# 生成静态库
add_library(mindsporelite STATIC main.cc)

2.2 多文件编译

对于多文件的情况,我们可以通过在add_libraryadd_executable的目标后意义列出所有文件,如下:

# 生成动态库
add_library(mindsporelite SHARED main.cc a.cc b.cc)
# 生成静态库
add_library(mindsporelite STATIC main.cc a.cc b.cc)

但是对于一个较大的工程,一一列举会显得Cmake代码十分冗长,我们可以用set设置一个变量,包含所有需要的.cc.cpp文件:

set(LITE_SRC${API_SRC}${CMAKE_CURRENT_SOURCE_DIR}/common/context_util.cc${CMAKE_CURRENT_SOURCE_DIR}/common/file_utils.cc${CMAKE_CURRENT_SOURCE_DIR}/common/config_file.cc${CMAKE_CURRENT_SOURCE_DIR}/common/utils.cc${CMAKE_CURRENT_SOURCE_DIR}/common/graph_util.cc${CMAKE_CURRENT_SOURCE_DIR}/common/log.cc${CMAKE_CURRENT_SOURCE_DIR}/common/lite_utils.cc${CMAKE_CURRENT_SOURCE_DIR}/common/prim_util.cc${CMAKE_CURRENT_SOURCE_DIR}/common/tensor_util.cc${CMAKE_CURRENT_SOURCE_DIR}/runtime/inner_allocator.cc${CMAKE_CURRENT_SOURCE_DIR}/runtime/runtime_allocator.cc${CMAKE_CURRENT_SOURCE_DIR}/runtime/infer_manager.cc${CMAKE_CURRENT_SOURCE_DIR}/schema_tensor_wrapper.cc${CMAKE_CURRENT_SOURCE_DIR}/tensor.cc${CMAKE_CURRENT_SOURCE_DIR}/ms_tensor.cc${CMAKE_CURRENT_SOURCE_DIR}/executor.cc${CMAKE_CURRENT_SOURCE_DIR}/inner_context.cc${CMAKE_CURRENT_SOURCE_DIR}/lite_model.cc${CMAKE_CURRENT_SOURCE_DIR}/kernel_registry.cc${CMAKE_CURRENT_SOURCE_DIR}/inner_kernel.cc${CMAKE_CURRENT_SOURCE_DIR}/lite_kernel.cc${CMAKE_CURRENT_SOURCE_DIR}/lite_kernel_util.cc${CMAKE_CURRENT_SOURCE_DIR}/sub_graph_kernel.cc${CMAKE_CURRENT_SOURCE_DIR}/scheduler.cc${CMAKE_CURRENT_SOURCE_DIR}/lite_session.cc${CMAKE_CURRENT_SOURCE_DIR}/errorcode.cc${CMAKE_CURRENT_SOURCE_DIR}/cpu_info.cc)# 生成动态库
add_library(mindsporelite SHARED ${LITE_SRC})
# 生成静态库
add_library(mindsporelite STATIC ${LITE_SRC})

当然除了动态库和静态库,我们还可以选择将代码编译成未链接的.o中间文件,在add_library使用OBJECT参数,使用方法如下:

add_library( OBJECT [...])
add_library(... $ ...)
add_executable(... $ ...)

对于生成的中间产物,这些文件并未被链接,所以并不能作为库或执行,我们对这些中间产物还可以进行如add_dependencies的操作,add_dependencies()会为顶层目标添加一个依赖关系,可以保证某个目标在其他的目标之前被构建。比如mindsporelite依赖于flatbuffers(一个谷歌开源的序列化库)生成的fbs文件。

ms_build_flatbuffers_lite(FBS_FILES ${CMAKE_CURRENT_SOURCE_DIR}/schema/ fbs_src ${CMAKE_BINARY_DIR}/schema "")#生成中间文件
add_library(lite_src_mid OBJECT ${LITE_SRC})
#添加依赖
add_dependencies(lite_src_mid fbs_src)# 生成动态库
add_library(mindsporelite SHARED $)
# 生成静态库
add_library(mindsporelite STATIC $)

2.3 生成多个库或者可执行文件

有时我们希望在一个项目中能编译多个独立的库或者可执行文件,比如在mindsporelite中,我们总共会生成以下可执行文件和动静态库

  • Mindsporelite
    • runtime
      • libminddata-lite.a (数据加载静态库)
      • libmindspore-lite-train.a(端侧训练静态库)
      • libmindspore-lite.a (端侧推理静态库)
      • libminddata-lite.so (数据加载动态库)
      • libmindspore-lite-train.so(端侧训练动态库)
      • libmindspore-lite.so (端侧推理动态库)
    • tools
      • benchmark(基准测试·工具)
      • cropper(裁剪工具)
      • converter(模型转化工具)
      • benchmark_train(训练基准测试工具)
      • codegen(代码生成工具)

而对于每个库或者可执行文件,一般在其相关的.cc文件目录下有一个CmakeLists文件,在最外侧目录的CmakeLists中通过add_subdirectory命令,指明本项目包含一个子目录 ,子目录也包含 CMakeLists.txt 文件,这样子目录下的 CMakeLists.txt 文件和源代码也会被处理。通过多层的CmakeLists我们一一构建各层的库和依赖。以下代码表示添加一个src的子目录。

add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/src)

2.4 链接库

add_subdirectory往往和target_link_libraries一起使用,在我们编译好一个可执行文件或者库时,如果它依赖其他库,我们可以使用target_link_libraries将其链接其他库,方法如下:

# 生成动态库
add_library(mindsporelite SHARED $)
# 生成静态库
add_library(mindsporelite-static STATIC $)
# 生成可执行文件
add_executable(benchmark main.cc)
# 动态链接
target_link_libraries(benchmark mindsporelite)
#静态链接
target_link_libraries(benchmark mindsporelite-static)

mindsporelite中的基准测试工具依赖于mindsporelite runtime库,链接代码如上,链接又分为动态链接和静态链接,静态链接会将库中所有的代码一起编译到可执行文件中,运行时速度更快,但包的大小更大,动态链接不会将库的代码编译到可执行文件中,文件更小,但在运行时会搜索动态库,运行速度慢。如果在系统目录和环境变量中找不到动态库,那么在运行时会报错,在Linux环境中,可以通过设置环境变量LD_LIBRARY_PATH指定动态库目录:

export LD_LIBRARY_PATH=/path/to/lib:${LD_LIBRARY_PATH}

这里有在链接库时,Cmake是如何找到对应库的位置的?在Cmake中,我们一般在文件开始添加 include_directories(包含指定目录)或aux_source_directory(包含所有子目录)命令,Cmake会在这些目录下进行搜索。

add_library (MathFunctions ${DIR_LIB_SRCS})

3. CMake编译安装OpenCV

NNIE模型转换环境搭建

3.1 下载OpenCV

OpenCV - https://opencv.org/
opencv_contrib - github

3.2 安装依赖

sudo apt-get install build-essential
sudo apt-get install cmake git libgtk2.0-dev pkg-config libavcodec-dev libavformat-dev libswscale-dev
sudo apt-get install python-dev python-numpy libtbb2 libtbb-dev libjpeg-dev libtiff-dev libjasper-dev libdc1394-22-dev

3.3 编译安装

tar -xvzf opencv-3.4.0.tar.gzcd opencv-3.4.0

3.4 配置opencv_contrib

如果编译过程出现问题,就不编译opencv_contrib即可

mv …/opencv_contrib-3.4.0 ./

3.5 cmake生成MakeFile

mkdir buildmkdir installcmake -D CMAKE_BUILD_TYPE=RELEASE \
-D CMAKE_INSTALL_PREFIX=/x/x \
–D WITH_VTK=ON \
-D OPENCV_EXTRA_MODULES_PATH=/x/x/opencv_contrib-3.4.0/modules/ \
-D CUDA_NVCC_FLAGS="-std=c++11 --expt-relaxed-constexpr" \
-D WITH_NVCUVID=OFF \
-D BUILD_opencv_cudacodec=OFF \
-D ENABLE_CXX11=YES  \
..

参数解释:

  • OPENCV_EXTRA_MODULES_PATHopencv_contrib/modules的路径;
  • CMAKE_INSTALL_PREFIX,安装的路径;
  • cuda10以上没有 dynlink_nvcuvid.h nvcuvid.h,所以要将 BUILD_opencv_cudacodec=OFF。如果编译 opencv-contrib 需要下载boost之类的可以不编译这个,即去掉OPENCV_EXTRA_MODULES_PATH。

3.6 编译安装

make -j${nproc}make check# 安装
make install

4. 编译protobuf

NNIE模型转换环境搭建

4.1 下载protobuf

下载地址

4.2 编译安装

tar -xvf protobufcd protobuf
autogen.shconfigure -prefix=/you/want/to/install/make
make check
make install

4.3 配置环境变量

把lib路径加入到LD_LIBRARY_PATH中,把bin加到PATH中(通过编辑~/.bashrc即可)。

相关内容

热门资讯

怎么写软文 怎么写软文多看书,多看报,多看小说多看动漫,多看电视节目(相关),最重要的一点——多写!根据人的心理...
韶关北江监狱大概有多少个人 韶关北江监狱大概有多少个人 大概有七千五百人。韶关北江监狱有十五个监区,按照规定,监狱的监区可按...
红袖添香网上面的短篇小说和长篇... 红袖添香网上面的短篇小说和长篇小说的字数要求是什么呢?请说的详细一点,谢谢。还有,在红袖上发表小说好...
教育学原理的同学们吗 教育学原理的同学们吗1、现在恐怕晚了,大部分学校已经完成一次调剂筛选工作了,但也可能有机会,够了二区...
李乐衡爸爸是谁 李乐衡爸爸是谁 李乐衡爸爸是张建新。李乐衡是《武林外传》中邱小冬的扮演者,他是著名演员张建新的儿...
女主姓凤,女尊紫眸有风,火,木... 女主姓凤,女尊紫眸有风,火,木三星种异能特工傻后、女主天下、绝代凤华、倾世皇妃、歌尽桃花
盗墓笔记电视剧出藏海花了吗 盗墓笔记电视剧出藏海花了吗没有吧,只有沙海和盗墓笔记。没有 藏海花很久很久之前断更了 恐怕不会被拍成...
苏柏斗的介绍 苏柏斗的介绍 苏柏斗,生于1971年,1997年毕业于解放军艺术学院美术系;2008年毕业于中国艺术...
一切法无我。得成于忍。不取于相... 一切法无我。得成于忍。不取于相。如如不动。是什么意思?你若不动,别人也动。一切皆空,存在是一种相,色...
男人会在夜晚想念暗恋的人吗? 男人会在夜晚想念暗恋的人吗?当然会啦,如果喜欢一个人的话日思梦想都会有的,有时候睡不着吃不下饭,满脑...
推理(墓地死者) 推理(墓地死者)有个人 接到一封信 信上让他半夜12点去 墓地 结果 那个人去了墓地,第2天就死在墓...
十诫诗在仓央嘉措的哪本书里 十诫诗在仓央嘉措的哪本书里不能说是仓央嘉措的哪本书,这本来是藏文,被宇道泉译成中文后才成诗,而且所谓...
失眠是怎么回事 失眠是怎么回事我周岁12岁,刚上初一,累了一天后,为什么睡着后在床上反过来折过去的翻身还老是醒睡眠的...
慕容复要复哪个燕国 慕容复要复哪个燕国 慕容复要复东晋时我国北方出现的多个燕国其中一个。慕容氏是鲜卑姓氏,而鲜卑人是...
誓约用英语怎么说 誓约用英语怎么说誓约用英语怎么说promise1.a vow; a pledge; an oath;...
4399皮卡堂过家家收铜色藏宝... 4399皮卡堂过家家收铜色藏宝图,我拿2金色藏宝图换5个铜色藏宝图,或500收一个4399皮卡堂过家...
排骨一般炖多长时间最好,及做法 排骨一般炖多长时间最好,及做法排骨汤做法大火炖开,中小火炖40 - 50分钟为宜,时间过长,营养损...
贝克汉姆一共写过几本书,都叫什... 贝克汉姆一共写过几本书,都叫什么名字还有日期,越详细越好你们说的都不对!!小贝的第一本自传是《我的天...
黑曜石灵摆消磁的问题 黑曜石灵摆消磁的问题有个100克的晶簇,要消磁多久?还有,用矿泉水的话是那种矿泉水,市面上买的农夫山...
每当夜幕降临,八角楼上的灯光就... 每当夜幕降临,八角楼上的灯光就亮了起来。缩句答案‘每当夜幕降临,八角楼上的灯光就亮了起来。(缩句)灯...