软件实现跨平台,必须保证其能够在不同平台下编译。CMake允许开发者编译一种平台无关的CMakeLists.txt文件来制定整个编译流程,然后再根据目标用户的平台进一步生成所需的本地化的Makefile和工程文件,从而做到
Write once, run everywhere
。
# 安装必须的包
$ sudo apt-get install build-essential
$ sudo apt-get install cmake git gcc g++
在linux平台使用CMake生成Makefile并编译的一般流程如下:
cmake PATH
或者 ccmake PATH
生成Makefile。PATH
是CMakeLists.txt所在目录, cmake
与 ccmake
的区别在于后者提供了一个交互界面;make -C PATH
命令进行编译。 -C
表示到指定目录下执行make, PATH
为Makefile文件所在目录。在Makefile文件所在目录执行make命令,可以不需要带任何参数,直接执行 make
命令进行编译。在Linux平台使用VSCode开发:
VSCode必要的插件:
项目模板的项目树:
.
└── .vscode
│ ├── c_cpp_properties.json
│ └── settings.json
├── build
├── CMakeLists.txt
├── .gitignore
├── main.cpp
├── README.md
.vscode
文件中包含了关于VSCode编辑器的一些配置文件。c_cpp_properties.json
文件中主要是配置头文件查找路径,当使用到第三方库,比如Boost,OpenCV等,就需要在这个文件中添加这些库的头文件路径。setting.json
文件对当前的工程进行了一些配置。build
是cmake构建工程是产生的,里面包含了cmake产生的所有内容,这是使用VSCode的好处,直接执行cmake .
,cmake文件将直接分散到整个工程中,不利于项目的管理。CMakeLists.txt
是整个工程的核心,它定义了整个工程的编译流程。使用介绍:
master*
表明当前处于master分支;
CMake: Debug: Ready
:表明你选择了构建类型为Debug
;
GCC 7.3.0
: 表明你选择了GCC 7.3.0
作为你的编译器;
Build: [all]
:表明可以构建所有可用的目标,点击Build
你将会构建所有可用的目标;
Debug demo
: 点击Debug
,你将运行调试demo;
这里的项目使用三个库,分别是Boost,OpenCV,OpenGL,有关它们的安装配置教程如下:
Boost安装使用方法:https://blog.csdn.net/qq_34347375/article/details/83589704
OpenCV安装使用方法:https://blog.csdn.net/qq_34347375/article/details/81137142
OpenGL安装使用方法:https://blog.csdn.net/qq_34347375/article/details/83575897
整个项目下载:https://github.com/AZMDDY/vscode_cpp_cmake_template.git
下面提供两个json文件的内容:
c_cpp_properties.json
{
"configurations": [
{
"name": "Mac",
"includePath": [
"/usr/include",
"/usr/local/include",
"${workspaceFolder}"
],
"defines": [],
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"macFrameworkPath": [
"/System/Library/Frameworks",
"/Library/Frameworks"
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17"
},
{
"name": "Linux",
"includePath": [
"/usr/include",
"/usr/local/include",
"${workspaceFolder}",
"/usr/include/linux",
"/usr/include/c++/7/tr1",
"/home/azmddy/Downloads/boost_1_68_0"
],
"defines": [],
"intelliSenseMode": "gcc-x64",
"browse": {
"path": [
"/usr/include",
"/usr/local/include",
"${workspaceFolder}",
"/home/azmddy/Downloads/boost_1_68_0"
],
"limitSymbolsToIncludedHeaders": false,
"databaseFilename": ""
},
"compilerPath": "/usr/bin/gcc",
"cStandard": "c11",
"cppStandard": "c++17",
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
},
{
"name": "Win32",
"includePath": [
"${workspaceFolder}"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "C:\\MinGW\\bin\\gcc.exe",
"intelliSenseMode": "clang-x64",
"browse": {
"path": [
"${workspaceFolder}"
],
"limitSymbolsToIncludedHeaders": true,
"databaseFilename": ""
},
"cStandard": "c11",
"cppStandard": "c++17"
}
],
"version": 4
}
setting.json
{
"C_Cpp.default.cppStandard": "c++14",
"C_Cpp.intelliSenseEngineFallback": "Enabled",
"C_Cpp.errorSquiggles": "Disabled",
"editor.mouseWheelZoom": true,
"files.autoSave": "afterDelay",
"files.autoSaveDelay": 100,
"editor.tabCompletion": "on",
"files.useExperimentalFileWatcher": true,
"files.associations": {
"iostream": "cpp",
"*.tcc": "cpp"
},
"cmake.debugConfig": {
"externalConsole": true
},
"cmake.configureOnOpen": true,
"cmake-tools-helper.cmake_download_path": "/home/undefined/.vscode/extensions/maddouri.cmake-tools-helper-0.2.1/cmake_download",
"explorer.confirmDelete": false
}
这里配置需要根据自己的实际情况做一些相应的修改。
CMakeLists.txt
# CMake 最低的版本要求
cmake_minimum_required(VERSION 3.12.0)
# 定义项目名称变量PROJECT_NAME, 默认值为demo
set(PROJECT_NAME demo)
# 项目名称以及版本
project(${PROJECT_NAME} VERSION 0.1.0)
# 查找当前目录下的所有源文件
# 并将名称保存到 DIR_SRCS 变量
aux_source_directory(. DIR_SRCS)
# 设置C++的版本
set(CMAKE_CXX_STANDARD 14)
# 指定生成目标
add_executable(${PROJECT_NAME} ${DIR_SRCS})
##############################################################################################################
################################### 有关第三方库的使用 ###############################################
############################################## OpenCV ########################################################
# 设置OpenCVModule的路径
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "/home/undefined/Downloads/opencv-3.4.1/build")
# 查找 OpenCV3.4.1的头文件和库文件路径以及库文件
find_package(OpenCV 3.4.1 REQUIRED)
# 包含OpenCV头文件目录
include_directories(${OpenCV_INCLUDE_DIRS})
message("OpenCV_INCLUDE_DIRS: ${OpenCV_INCLUDE_DIRS}")
message("OpenCV_LIBS: ${OpenCV_LIBS}")
# 链接OpenCV库文件
target_link_libraries(${PROJECT_NAME} ${OpenCV_LIBS})
##############################################################################################################
############################################## Boost #########################################################
# 查找 Boost_1_68_0的特定的库
find_package(Boost 1.68.0 REQUIRED COMPONENTS regex)
# 包含Boost头文件目录
include_directories(${Boost_INCLUDE_DIRS})
message("Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message("Boost_LIBRARIES: ${Boost_LIBRARIES}")
# 链接Boost库文件
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})
##############################################################################################################
############################################## OpenGL ########################################################
# opengl 头文件路径保存在 OPENGL_INC_DIR 变量
set(OPENGL_INC_DIR /usr/local/include /usr/include /usr/include/GL)
# opengl 链接库路径保存在 OPENGL_LDFLAGS 变量
set(OPENGL_LDFLAGS /usr/local/lib /usr/lib64)
# opengl 链接库名称保存在 OPENGL_LIBS 变量
set(OPENGL_LIBS GL GLU glut GLEW gltools glfw3 X11 Xxf86vm Xrandr pthread Xi dl Xinerama Xcursor m)
# OpenGL头文件目录
include_directories(${OPENGL_INC_DIR})
# OpenGL库文件目录
link_directories(${OPENGL_LDFLAGS})
# 链接OpenGL库文件
target_link_libraries(${PROJECT_NAME} ${OPENGL_LIBS})
###############################################################################################################
用于测试三个库的源码:
#include
#include
#include
#include
#include
using namespace cv;
#define ColoredVertex(c, v) \
do \
{ \
glColor3fv(c); \
glVertex3fv(v); \
} while (0)
static int angle = 0;
static int rotateMode = 0;
void myDisplay(void)
{
static int list = 0;
if (list == 0)
{
GLfloat
PointA[] = {0.5f, 0.5f, -0.5f},
PointB[] = {0.5f, -0.5f, -0.5f},
PointC[] = {-0.5f, -0.5f, -0.5f},
PointD[] = {-0.5f, 0.5f, -0.5f},
PointE[] = {0.5f, 0.5f, 0.5f},
PointF[] = {0.5f, -0.5f, 0.5f},
PointG[] = {-0.5f, -0.5f, 0.5f},
PointH[] = {-0.5f, 0.5f, 0.5f};
GLfloat
ColorA[] = {1, 0, 0},
ColorB[] = {0, 1, 0},
ColorC[] = {0, 0, 1},
ColorD[] = {1, 1, 0},
ColorE[] = {1, 0, 1},
ColorF[] = {0, 1, 1},
ColorG[] = {1, 1, 1},
ColorH[] = {0, 0, 0};
list = glGenLists(1);
glNewList(list, GL_COMPILE);
// 面1
glBegin(GL_POLYGON);
ColoredVertex(ColorA, PointA);
ColoredVertex(ColorE, PointE);
ColoredVertex(ColorH, PointH);
ColoredVertex(ColorD, PointD);
glEnd();
// 面2
glBegin(GL_POLYGON);
ColoredVertex(ColorD, PointD);
ColoredVertex(ColorC, PointC);
ColoredVertex(ColorB, PointB);
ColoredVertex(ColorA, PointA);
glEnd();
// 面3
glBegin(GL_POLYGON);
ColoredVertex(ColorA, PointA);
ColoredVertex(ColorB, PointB);
ColoredVertex(ColorF, PointF);
ColoredVertex(ColorE, PointE);
glEnd();
// 面4
glBegin(GL_POLYGON);
ColoredVertex(ColorE, PointE);
ColoredVertex(ColorH, PointH);
ColoredVertex(ColorG, PointG);
ColoredVertex(ColorF, PointF);
glEnd();
// 面5
glBegin(GL_POLYGON);
ColoredVertex(ColorF, PointF);
ColoredVertex(ColorB, PointB);
ColoredVertex(ColorC, PointC);
ColoredVertex(ColorG, PointG);
glEnd();
// 面6
glBegin(GL_POLYGON);
ColoredVertex(ColorG, PointG);
ColoredVertex(ColorH, PointH);
ColoredVertex(ColorD, PointD);
ColoredVertex(ColorC, PointC);
glEnd();
glEndList();
glEnable(GL_DEPTH_TEST);
}
// 已经创建了显示列表,在每次绘制正四面体时将调用它
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glRotatef(angle / 10, 1, 0.5, 0.0);
glCallList(list);
glPopMatrix();
glutSwapBuffers();
}
void myIdle(void)
{
++angle;
if (angle >= 3600.0f)
{
angle = 0.0f;
}
myDisplay();
}
int main(int argc, char *argv[])
{
VideoCapture testCamera;
testCamera.open(0);
int n = 100;
while (n)
{
Mat src;
testCamera >> src;
imshow("test", src);
waitKey(30);
n--;
}
testCamera.release();
std::string line;
boost::regex pat("^Subject: (Re: |Aw: )*(.*)");
while (std::cin)
{
std::getline(std::cin, line);
boost::smatch matches;
if (boost::regex_match(line, matches, pat))
std::cout << matches[2] << std::endl;
}
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE);
glutInitWindowPosition(100, 100);
glutInitWindowSize(700, 700);
glutCreateWindow("First OpenGL Program");
glutDisplayFunc(&myDisplay);
glutIdleFunc(&myIdle); //空闲调用
glutMainLoop();
return 0;
}
如果你的工程没有涉及第三方库的使用,可以直接在CMakeLists.txt
文件中将有关第三方库的内容删除。