1. window系统 c++ 环境配置
1.1 配置MinGw编译器
(1)下载mingw64
mingw64 的按照包,我已经放在百度网盘上了,搭建可自行下载:
链接: https://pan.baidu.com/s/1NoPGAYFuP5ysXTf8wtvbEA?pwd=wd6w 提取码: wd6w
(2)配置环境变量
将下载好的mingw64.zip
解压,找到解压后bin
文件所在路径
然后将bin所在路径,如我这里的D:\install\mingw64\bin
添加到系统环境变量中。
(3)验证是否安装成功
命令提示符中cmd窗口输入gcc -v
或gcc --version
,若显示版本号则说明安装成功
1.2 配置C/C++环境
C++环境是通过c_pp_propertoes.json
,launch.json
和tasks.json
三个文件配置的。
方法1 利用工具自动配置
本文介绍一种非常简单的环境配置方法,借助网上提供的vscode c++配置器
来实现。
-
在https://v4.vscch.tk/ 下载安装包
-
解压安装包,并点击
vscch.exe
进行一步步按照;安装非常简单,按照默认安装方式即可。
该工具可以自动识别MinGW编译器的安装位置,如果没有添加到环境变量中,它会自动帮忙配置到环境变量。
-
如果未下载MinGW,它会提示你下载,然后帮忙自动配置环境变量。
-
完成安装后,会自动在你选择的工作路径下,生成配置好的
c_pp_propertoes.json
,launch.json
和tasks.json
, 以及helloworld.cpp
测试代码。可以运行,测试c++环境是否配置成功:
注意:
根据自动生成的json配置
,只能在安装时指定的工作目录下
,编写c++ code才有效,因此做了如下修改
,这样将3个json拷贝到其他目录,也可以运行和调试c++程序。 将single file build
改为build
launch.json
的修改如下:
tasks.json
的修改如下:
方法2 直接创建3个json文件
在项目目录上创建.vscode
目录,并创建c_cpp_properties.json
,launch.json
,tasks.json
,三个json文件的按照我提供的配置。
(1) c_cpp_properties.json
{
"configurations": [
{
"compilerPath": "D:\\install\\mingw64\\bin\\g++.exe",
"cppStandard": "c++17",
"includePath": [
"${{workspaceFolder}}/**"
],
"intelliSenseMode": "windows-gcc-x64",
"name": "Win32"
}
],
"version": 4
}
(2) launch.json
{
"configurations": [
{
"MIMode": "gdb",
"args": [],
"cwd": "${fileDirname}",
"env": {
"PATH": "D:\\install\\mingw64\\bin;${env:PATH}"
},
"environment": [],
"externalConsole": true,
"internalConsosleOptions": "neverOpen",
"miDebuggerPath": "D:\\install\\mingw64\\bin\\gdb.exe",
"name": "build",
"preLaunchTask": "build",
"program": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"request": "launch",
"stopAtEntry": false,
"type": "cppdbg"
}
],
"version": "0.2.0"
}
(3) tasks.json
{
"options": {
"env": {
"Path": "D:\\install\\mingw64\\bin;${env:Path}"
}
},
"tasks": [
{
"args": [
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe",
"-std=c++17"
],
"command": "D:\\install\\mingw64\\bin\\g++.exe",
"group": {
"isDefault": true,
"kind": "build"
},
"label": "build",
"presentation": {
"clear": true,
"echo": false,
"focus": false,
"panel": "shared",
"reveal": "silent",
"showReuseMessage": false
},
"problemMatcher": "$gcc",
"type": "process"
},
{
"args": [],
"command": "${fileDirname}\\${fileBasenameNoExtension}.exe",
"dependsOn": "single file build",
"label": "run and pause",
"options": {
"env": {
"Path": "D:\\install\\mingw64\\bin;${env:Path}"
}
},
"presentation": {
"clear": true,
"echo": false,
"focus": false,
"panel": "shared",
"reveal": "never",
"showReuseMessage": false
},
"problemMatcher": [],
"type": "pause-console"
}
],
"version": "2.0.0"
}
注意: 将这3个json
文件中的D:\\install\\mingw64
路径设置为你本机自己的路径
1.3 C/C++环境测试
编写一个测试的helloworld.cpp
,代码如下:
// 按下 F6 编译运行。
// 按下 F5 编译调试。
// 按下 Ctrl + Shift + B 编译。
#include <iostream>
int main() {
// 在标准输出中打印 "Hello, world!"
std::cout << "Hello, world!" << std::endl;
}
// 此文件编译运行将输出 "Hello, world!"。
// 按下 F6 后,你将在弹出的终端窗口中看到这一行字。
配置和代码见我已上传百度网盘:
链接:https://pan.baidu.com/s/13R79Wxn91Z4G7RCcXpr8fQ?pwd=xe2x
提取码:xe2x
参考: https://zhuanlan.zhihu.com/p/545908287?utm_id=0
2. linux系统 c++ 环境配置
2.1 配置详解
linux系统vsocde的配置和window系统配置基本上是一样的,通过c_pp_propertoes.json
,launch.json
和tasks.json
,settings.json
4个文件配置的c++环境
。
(1) settings.json
{
"files.associations": {
"*.cpp": "cpp",
"*.cu": "cuda-cpp",
"deque": "cpp",
"string": "cpp",
"vector": "cpp",
"*.tcc": "cpp",
"__hash_table": "cpp",
"__split_buffer": "cpp",
"__tree": "cpp",
"array": "cpp",
"bitset": "cpp",
"initializer_list": "cpp",
"iterator": "cpp",
"map": "cpp",
"queue": "cpp",
"random": "cpp",
"set": "cpp",
"stack": "cpp",
"string_view": "cpp",
"unordered_map": "cpp",
"utility": "cpp",
"__atomic": "cpp",
"__functional_base": "cpp",
"__functional_base_03": "cpp",
"__tuple": "cpp",
"algorithm": "cpp",
"chrono": "cpp",
"type_traits": "cpp",
"filesystem": "cpp",
"functional": "cpp",
"limits": "cpp",
"memory": "cpp",
"ratio": "cpp",
"tuple": "cpp",
"istream": "cpp",
"ostream": "cpp",
"future": "cpp",
"cctype": "cpp",
"clocale": "cpp",
"cmath": "cpp",
"cstdarg": "cpp",
"cstddef": "cpp",
"cstdio": "cpp",
"cstdlib": "cpp",
"cstring": "cpp",
"ctime": "cpp",
"cwchar": "cpp",
"cwctype": "cpp",
"atomic": "cpp",
"hash_map": "cpp",
"hash_set": "cpp",
"bit": "cpp",
"codecvt": "cpp",
"complex": "cpp",
"condition_variable": "cpp",
"cstdint": "cpp",
"list": "cpp",
"unordered_set": "cpp",
"exception": "cpp",
"memory_resource": "cpp",
"numeric": "cpp",
"optional": "cpp",
"system_error": "cpp",
"fstream": "cpp",
"iomanip": "cpp",
"iosfwd": "cpp",
"iostream": "cpp",
"mutex": "cpp",
"new": "cpp",
"sstream": "cpp",
"stdexcept": "cpp",
"streambuf": "cpp",
"thread": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp",
"typeindex": "cpp",
"typeinfo": "cpp",
"ios": "cpp",
"__nullptr": "cpp",
"__bit_reference": "cpp",
"__node_handle": "cpp",
"__locale": "cpp",
"variant": "cpp"
}
}
settings.json
可以上面提供的配置,不需要修改。
(2) c_cpp_propertoes.json
c_cpp_propertoes.json:
配置c++ 编译时的选项,包括编译器的路径、C/C++标注, 指定头文件的搜索路径(如opencv等)
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/trt8cuda112cudnn8/include/**",
"/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/cpp-packages/opencv4.2/include/**"
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "gnu11",
"cppStandard": "gnu++11",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
配置includePath
"includePath": [
"${workspaceFolder}/**",
"/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/trt8cuda112cudnn8/include/**",
"/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/cpp-packages/opencv4.2/include/**"
],
includePath
: 设置头文件的搜索路径,让编译器可以找打相应的头文件。
- 第一项:
"${workspaceFolder}/**"
添加项目的工作路径作为头文件的搜索路径,此项默认添加 - 第二项: 配置TensorRT部署时,需要依赖的
头文件
,包括tensorrt自身的、cuda、cudnn、protobuf下的头文件。(项目中如果不依赖TensorRT
、cuda
则不需要配置)
ls /home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/trt8cuda112cudnn8/include/
可以看到依赖的一些头文件:
cd 到其中一个比如cuda,可以详细看到cuda包含的.h文件
- 第三项:配置了依赖的opencv 头文件。(项目中如果不依赖与opencv,则不需要配置)
配置gcc编译器路径
"compilerPath": "/usr/bin/gcc" # 设置gcc编译器即可,不需要设置g++
通过ls /usr/bin
,可以看到gcc, g++
等编译器都在该目录下
指定C/C++语言标注版本
"cStandard": "gnu11",
"cppStandard": "gnu++11",
智能感知方式
"intelliSenseMode": "linux-gcc-x64"
(3) tasks.json
tasks.json:指定 编译时需要执行cmake命令
, 并且在每次launch(debug)
时,都会先运行运行tasks
(这里指的是都会编译一遍)。
因此tasks
下面label
名需要和launch.json
中的 "preLaunchTask"
参数设置的一样,比如都是build
。
{
"version": "2.0.0",
"tasks": [
{
"label": "build",
"type": "shell",
"command": "make pro -j6"
}
]
}
command
: 执行cmake的命令,其中pro
为可执行文件名(makefile
中指定的生成可执行文件的名称
),-j6
表示6个进程同时执行,如果想编译快点,可以将数字设置的大一点。
(4) launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "program-debug",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/workspace/pro",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}/workspace",
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb",
"environment": [
{
"name": "LD_LIBRARY_PATH",
"value": "/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/trt8cuda112cudnn8/lib64:/home/yuanwushui/anaconda3/lib:/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/trt8cuda112cudnn8/py39:/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/cpp-packages/opencv4.2/lib:/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/lib:$LD_LIBRARY_PATH"
}
],
"setupCommands": [
{
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "build"
}
]
}
launch.json
设置c++ debug的选项。 "configurations"
下面的配置参数说明如下:
program
:指定编译好的可执行文件pro
的路径, 其中pro
是在makefile中指定输出可执行文件名。
"program": "${workspaceFolder}/workspace/pro",
cwd
: 为可执行文件所在目录"externalConsole"
: 运行时,是否需要运行在外部的控制台。如果设为True
的话,会再CMD控制台运行(windows),如果false,会运行在编译器所在控制台。默认设为false
即可miDebuggerPath
: 指定调试器(gdb)的路径environment
: 配置环境变量。环境变量名为LD_LIBRARY_PATH
,环境变量值通过value
来指定。LD_LIBRARY_PATH主要用来指定需要一开的外部库文件的搜索路径
。在vlaue
中指定库文件的搜索路径,以:
隔开。如项目需要依赖tensorrt
,cuda
,anaconda
,opencv
, 则需要添加这些依赖的库文件。注意value需要以:
不同库的搜索路径隔开,最后需要以:$LD_LIBRARY_PATH
结尾。
"environment": [
{
"name": "LD_LIBRARY_PATH",
"value": "/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/trt8cuda112cudnn8/lib64:/home/yuanwushui/anaconda3/lib:/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/trt8cuda112cudnn8/py39:/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/cpp-packages/opencv4.2/lib:/home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/lib:$LD_LIBRARY_PATH"
}
],
setupCommands
: 设置打印选项,如对print输出进行美化,保持默认即可,不需要修改
"setupCommands": [
{
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
preLaunchTask
: Launch(debug)前需要依赖的task任务
,注意
需要与tasks.json
中任务的label
设置的名称一致,比如都为build,不然无法调试和编译
。通过设置该选项,在调试时不需要手动去编译可执行文件,系统通过preLaunchTask
自动帮忙编译。
"preLaunchTask": "build"
2.2 makefile详解
cc := g++
name := pro
workdir := workspace
srcdir := src
objdir := objs
stdcpp := c++11
cuda_home := /home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/trt8cuda112cudnn8
syslib := /home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/lib
cpp_pkg := /home/yuanwushui/anaconda3/lib/python3.9/site-packages/trtpy/cpp-packages #opencv4.2
cuda_arch :=
nvcc := $(cuda_home)/bin/nvcc -ccbin=$(cc)
# 定义cpp的路径查找和依赖项mk文件
cpp_srcs := $(shell find $(srcdir) -name "*.cpp")
cpp_objs := $(cpp_srcs:.cpp=.cpp.o)
cpp_objs := $(cpp_objs:$(srcdir)/%=$(objdir)/%)
cpp_mk := $(cpp_objs:.cpp.o=.cpp.mk)
# 定义cu文件的路径查找和依赖项mk文件
cu_srcs := $(shell find $(srcdir) -name "*.cu")
cu_objs := $(cu_srcs:.cu=.cu.o)
cu_objs := $(cu_objs:$(srcdir)/%=$(objdir)/%)
cu_mk := $(cu_objs:.cu.o=.cu.mk)
# 定义opencv和cuda需要用到的库文件
link_cuda := cudart cudnn
link_trtpro :=
link_tensorRT := nvinfer nvinfer_plugin
link_opencv := opencv_core opencv_imgproc opencv_imgcodecs
link_sys := stdc++ dl protobuf
link_librarys := $(link_cuda) $(link_tensorRT) $(link_sys) $(link_opencv)
# 定义头文件路径,请注意斜杠后边不能有空格
# 只需要写路径,不需要写-I
include_paths := src \
$(cuda_home)/include/cuda \
$(cuda_home)/include/tensorRT \
$(cpp_pkg)/opencv4.2/include \
$(cuda_home)/include/protobuf
# 定义库文件路径,只需要写路径,不需要写-L
library_paths := $(cuda_home)/lib64 $(syslib) $(cpp_pkg)/opencv4.2/lib
# 把library path给拼接为一个字符串,例如a b c => a:b:c
# 然后使得LD_LIBRARY_PATH=a:b:c
empty :=
library_path_export := $(subst $(empty) $(empty),:,$(library_paths))
# 把库路径和头文件路径拼接起来成一个,批量自动加-I、-L、-l
run_paths := $(foreach item,$(library_paths),-Wl,-rpath=$(item))
include_paths := $(foreach item,$(include_paths),-I$(item))
library_paths := $(foreach item,$(library_paths),-L$(item))
link_librarys := $(foreach item,$(link_librarys),-l$(item))
# 如果是其他显卡,请修改-gencode=arch=compute_75,code=sm_75为对应显卡的能力
# 显卡对应的号码参考这里:https://developer.nvidia.com/zh-cn/cuda-gpus#compute
# 如果是 jetson nano,提示找不到-m64指令,请删掉 -m64选项。不影响结果
cpp_compile_flags := -std=$(stdcpp) -w -g -O0 -m64 -fPIC -fopenmp -pthread
cu_compile_flags := -std=$(stdcpp) -w -g -O0 -m64 $(cuda_arch) -Xcompiler "$(cpp_compile_flags)"
link_flags := -pthread -fopenmp -Wl,-rpath='$$ORIGIN'
cpp_compile_flags += $(include_paths)
cu_compile_flags += $(include_paths)
link_flags += $(library_paths) $(link_librarys) $(run_paths)
# 如果头文件修改了,这里的指令可以让他自动编译依赖的cpp或者cu文件
ifneq ($(MAKECMDGOALS), clean)
-include $(cpp_mk) $(cu_mk)
endif
$(name) : $(workdir)/$(name)
all : $(name)
run : $(name)
@cd $(workdir) && ./$(name) $(run_args)
$(workdir)/$(name) : $(cpp_objs) $(cu_objs)
@echo Link $@
@mkdir -p $(dir $@)
@$(cc) $^ -o $@ $(link_flags)
$(objdir)/%.cpp.o : $(srcdir)/%.cpp
@echo Compile CXX $<
@mkdir -p $(dir $@)
@$(cc) -c $< -o $@ $(cpp_compile_flags)
$(objdir)/%.cu.o : $(srcdir)/%.cu
@echo Compile CUDA $<
@mkdir -p $(dir $@)
@$(nvcc) -c $< -o $@ $(cu_compile_flags)
# 编译cpp依赖项,生成mk文件
$(objdir)/%.cpp.mk : $(srcdir)/%.cpp
@echo Compile depends C++ $<
@mkdir -p $(dir $@)
@$(cc) -M $< -MF $@ -MT $(@:.cpp.mk=.cpp.o) $(cpp_compile_flags)
# 编译cu文件的依赖项,生成cumk文件
$(objdir)/%.cu.mk : $(srcdir)/%.cu
@echo Compile depends CUDA $<
@mkdir -p $(dir $@)
@$(nvcc) -M $< -MF $@ -MT $(@:.cu.mk=.cu.o) $(cu_compile_flags)
# 定义清理指令
clean :
@rm -rf $(objdir) $(workdir)/$(name) $(workdir)/*.trtmodel $(workdir)/*.onnx
@rm -rf $(workdir)/image-draw.jpg $(workdir)/input-image.jpg $(workdir)/pytorch.jpg
# 防止符号被当做文件
.PHONY : clean run $(name)
# 导出依赖库路径,使得能够运行起来
export LD_LIBRARY_PATH:=$(library_path_export)
2.3 案例说明
未完待续