前言
最近在调试ORB-SLAM3的代码,此前一直以为vscode不能调试,原来是没有配置好,然后顺便学习了一下标准工程中的CMakeLists.txt的编写,做个笔记。
1.一些准备
pangolin0.5
或者pangolin0.6
都可以(已经试过了),opencv3.4.5
以及opencv_contrib-3.4.5
有需要的可以参考配置
ORBSLAM3配置
2.配置VScode
通过vscode打开的项目是没有相应的配置环境的,需要用户自己进行配置,配置文件在.vscode
文件夹中,一般是需要以下3个文件【c_cpp_properties.json,task.json,launch.json
】(这几个json文件中不允许带注释,会有问题):
逐一讲解几个文件的功能和配置
首先生成.vscode
文件夹,crtl+shift+p
打开vscode控制台输入C/Cpp: Edit configurations
,就自动生成了一个c_cpp_properties.json
文件以及改文件夹。
1.c_cpp_properties.json 文件
最主要的事includePath的引用和库的路径,根据引用内容进行配置。一般生成的默认内容如下:
在"includePath"
中添加一些路径,这样可以防止在看代码的时候头文件报红,或者运行错误。
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"usr/bin/**"
],
"defines": [],
"compilerPath": "/usr/bin/clang",
"cStandard": "c17",
"cppStandard": "c++14",
"intelliSenseMode": "clang-x64",
"configurationProvider": "ms-vscode.cmake-tools"
}
],
"version": 4
}
2.task.json文件
crtl+shift+p
打开vscode控制台输入Task:Configure Task → 使用模版创建Tasks.json文件 → Others:
默认生成如下,这个文件一般和launch文件一起使用,主要是每次debug之前运行command中指令,相当于编译一下文件,生成可执行程序
{
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
"tasks": [
{
"label": "echo",// 任务名,用户自定义,会显示在侧边栏如下,后续使用在launch.json中的 "preLaunchTask"
"type": "shell",// 运行task的平台,一般是shell
"command": "echo Hello" // 可以运行的文件,一般可以是.sh文件,例如根目录下的xxx.sh
}
]
}
脚本文件xxx.sh,使用之前附加权限sudo chmod +x xxx.sh
#!/bin/bash
echo "This is a bash file..."
cd build
rm -rf *
// 设置模式debug可以调试,不设置会无法断点成功
cmake .. -DCMAKE_BUILD_TYPE=Debug
make
3.launch.json文件
点击左侧的Debug按钮,选择添加配置(Add configuration),然后选择C++(GDB/LLDB),然后点击默认生成,将自动生成launch.json文件,该文件的主要作用是设置可运行程序的参数以及可运行程序文件的位置。默认配置如下:
{
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "/home/xxx/ORB_SLAM3/Examples_old/Stereo/stereo_kitti_old", //只需要改这,设置可执行程序位置
"args": [
"/home/xxx/ORB_SLAM3/Vocabulary/ORBvoc.txt",
"/home/xxx/ORB_SLAM3/Examples_old/Stereo/KITTI00-02.yaml",
"/home/xxx/00"
],//如果可执行程序需要参数,在这设置
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": true,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "echo" //增加一条,执行launch前执行这个task
}
]
}
至此,配置vscode的debug就全部结束了。ORB-SLAM3的调试界面如下:
3.CMakeLists.txt文件
举例场景:编写一个自己的动态库,然后用在其他的程序上。
相比于Windows下的visual studio 自动打包成为动态库给其他应用程序调用,Ubuntu下更多是采取CMakeLists.txt文件来整理编写。
目录结构如下:
bin输出的可执行文件夹
build是cmake生成的中间文件
include是头文件夹
src是源文件夹
lib是自定义生成的库文件夹
test是mian函数所在的文件夹
首先编写根目录下的CMakeLists.txt
# 主要步骤
# 1.设置头文件路径
include_directories(${PROJECT_SOURCE_DIR}/include)
# 2.设置各种类型文件的输出路径
# 设置输出lib库路径,下面是最新用法,类似之前的LIBRARY_OUTPUT_PATH
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
# 设置输出可执行文件的路径,下面是最新用法,类似之前的LIBRARY_OUTPUT_PATH
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
# 3.设置编译器的一些标志
# 4.设置可执行文件
add_executable(myapp test/main.cpp)
# 5.设置链接
target_link_libraries(myapp myfunc)
# 1,4,5最重要
完整文件如下:
cmake_minimum_required(VERSION 2.8)
project(mytask)
# 检查构建类型
if(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Release)
endif()
MESSAGE("build type is " ${CMAKE_BUILD_TYPE})
# 设置编译标志
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -O3")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -O3")
set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -march=native")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -march=native")
# 设置添加调试信息,不然在cmake .. -DCMAKE_BUILD_TYPE=debug设置,否则断点无效
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
# 检查C++11或C++0x支持
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
# 添加预定义的宏 -D COMPILEDWITHC11
add_definitions(-DCOMPILEDWITHC11)
message(STATUS "Using flag -std=c++11.")
elseif(COMPILER_SUPPORTS_CXX0X)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
add_definitions(-DCOMPILEDWITHC0X)
message(STATUS "Using flag -std=c++0x.")
else()
message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
# 添加自定义的CMake模块,后续采用find_package()可以在这个路径下查找
LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
# 查找文件
find_package(OpenCV 3.4.5 REQUIRED)
if(NOT OpenCV_FOUND)
message(FATAL_ERROR "OpenCV > 4.4 not found.")
endif()
MESSAGE("OPENCV VERSION:${OpenCV_VERSION}")
# 包含的头文件路径
include_directories(
${PROJECT_SOURCE_DIR}/include
)
# 设置输出lib库路径,下面是最新用法,类似之前的LIBRARY_OUTPUT_PATH
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
# 设置输出可执行文件的路径,下面是最新用法,类似之前的LIBRARY_OUTPUT_PATH
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/bin)
# 添加子文件夹,当下cmakelists.txt文件下的设置会影响子文件夹中的设置
add_subdirectory(src)
# 生成可执行程序
add_executable(myapp
test/main.cpp
)
# 链接可执行程序
# target_link_libraries(myapp ${PROJECT_SOURCE_DIR}/lib/libmyfunc.so)
target_link_libraries(myapp myfunc)
其次是自定义库的文件目录下src的cmakelists.txt
cmake_minimum_required(VERSION 2.8)
project(myfunc)
# 如果制作自定义的库文件用到了其他的库,那么就需要link
add_library(${PROJECT_NAME} SHARED
myadd.cpp
)
# 如
# 这里使用链接的原因是因为自定义的库依赖于其他的库,如果不依赖,可以不需要
# target_link_libraries(${PROJECT_NAME}
# ${OpenCV_LIBS}
# ${EIGEN3_LIBS}
# ${Pangolin_LIBRARIES}
# ${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
# ${PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so
# -lboost_serialization
# -lcrypto
# )