Linux下C++程序多文件的编译运行同样有三种方法,使用g++命令,使用cmake,以及使用VsCode插件C/C++ Program Generator。
使用g++命令可以是我们了解编译链接的过程,对从源代码到可执行文件的过程有一个了解,有助于我们编写一些VsCode的js配置文件,使用g++命令编译运行多文件的教程可以看这篇博客:https://www.cnblogs.com/Fight-go/p/15836109.html
大型工程一般都使用cmake编译,cmake可以实现跨平台开发,同时,修改一个文件时,只需对该文件进行编译链接就可以了,不需要对其他未修改文件编译,可以节约时间。本文章重点介绍使用cmake和make进行C++开发。
使用VsCode插件C/C++ Program Generator进行开发可以查看这篇博客:https://www.cnblogs.com/Fight-go/p/15717719.html
本篇博客以一个简单的交换两个数的类Swap的程序为样例,交换两个数的程序的文件结构如下:
build文件夹用来存放Cmake产生的中间文件,out用来存放输出的可执行文件。
样例的源代码如下:
#pragma once
#include <iostream>
class swap
{
private :
int _a;
int _b;
public :
swap (int a, int b) : _a(a), _b(b){ }
void run () ;
void printInfo () ;
};
#include "swap.h"
void swap::run ()
{
int temp;
temp = _a;
_a = _b;
_b = temp;
}
void swap::printInfo ()
{
std::cout << "_a = " << _a << std::endl;
std::cout << "_b = " << _b << std::endl;
}
#include "swap.h"
int main ()
{
swap myswap123 (10 , 20 ) ;
std::cout << "Before swap:" << std::endl;
myswap123.printInfo ();
myswap123.run ();
std::cout << "After swap:" << std::endl;
myswap123.printInfo ();
return 0 ;
}
1. CMAKE重要指令和常用变量
1.1 重要指令
cmake_minimum_required -指定Cmake的最小版本要求
语法:cmake_minimum_required(VERSION versionNumber[FATAL_ERROR])
cmake_minimum_required (VERSION 3.22 .1 )
project -定义工程名称,并指定工程支持的语言
语法:project(projectname[CXX][C][Java])
# 指定工程名为HELLOWORLD
project (HELLOWORLD)
set -显式的定义变量
语法:set(VAR[VALUE][CACHE TYPE DOCSTRING [FORCE]])
# 定义SRC 变量,其值为main .cpp hello.cpp
set(SRC main .cpp hello.cpp )
include_directories -向工程添加多个特定的头文件搜索路径-->相当与g++的-I参数
语法:include_directories([AFTER|BEFORE] [SYSTEM] dir1 dir2)
include_directories(/usr/include/myincludefolder ./inculde)
link_directories -向工程添加多个特定的库文件搜索路径-->相当与g++的-L参数
语法:link_directories(dir1 dir2 ...)
link_directories(/usr/include/myincludefolder ./inculde)
add_library -生成库文件
语法:add_library(libname[SHARED|STATIC|MODULE][EXCULDE_FROM_ALL]source1 source2 ...sourceN)
# 通过变量 SRC 生成 libhello.so 共享库
add_library (hello SHARED ${SRC})
add_compile_options -添加编译参数
语法:add_compile_options(<option>...)
add_compile_options( - Wall - std= c + + 11 - O2)
add_executable -生成可执行文件
语法:add_executable(exname source1 source2...sourceN)
# 编译main .cpp 生成可执行文件main
add_executable(main main .cpp )
target_link_libraries -为target添加需要链接的共享库--->相当于指定g++编译-l参数
语法:target_link_libraries(target library1<debug|optimized> library2...)
# 将hello动态库文件链接到可执行文件main
target_link_libraries(main hello)
add_subdirectory -向当前工程目录添加存放源文件的子目录,并可以制定中间二进制和目标二进制存放的位置
语法:add_subdirectory(source_dir[binary_dir][EXCLUDE_FROM_ALL])
# 通过变量 SRC 子目录,src 中需要一个CMakeLists.txt
add_subdirectory (src)
aux_source_directory -发现一个目录下所有的源代码文件并将列表存储在一个变量中,这个指令临时被用来自动构建源文件列表
语法:aux_source_directory(dir VARIABLE)
# 定义SRC 变量,其值为当前目录下所有的源代码文件
aux_source_directory (. SRC)
# 编译SRC 变量所代码的源代码文件,生成main 可执行文件
add_excuatable (main ${SRC})
1.2 CMake常用变量
CMAKE_C_FLAGS gcc编译选项
CMAKE_CXX_FLAGS g++编译选项
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
CMAKE_BUILD_TYPE 编译类型(Debug, Release)
# 设定编译类型为debug,调试时需要选择debug
set (CMAKE_BUILD_TYPE Debug)
# 设定编译类型为release ,发布时需要选择release
set (CMAKE_BUILD_TYPE Release )
CMAKE_BINARY_DIR
PROJECT_BINARY_DIR
<projectname>_BINARY_DIR
1.这三个变量指代的内容是一致的。
2.如果是in source build,指的就是工程顶层目录
3.如果是out-of-source编译,指的是工程编译发生的目录
4.PROJECT_BINARY_DIR跟其他指令稍有区别,不过现在,你可以理解为他们是一致的。
CMAKE_SOURCE_DIR
PROJECT_SOURCE_DIR
<projectname>_SOURCE_DIR
1.这三个变量指代的内容是一致的,不论采用何种编译方式,都是更成顶层目录。
2.也就是在in source build时,它跟 CMAKE_BINARY_DIR等变量一致
3.如果是out-of-source编译,指的是工程编译发生的目录
4.PROJECT_SOURCE_DIR跟其他指令稍有区别,现在,你可以理解为他们是一致的。
CMAKE_C_COMPILER: 指定C编译器
CMAKE_CXX_COMPILER: 指定CXX编译器
EXCUTABLE_OUTPUT_PATH: 可执行文件输出的存放路径
LIBRARY_OUTPUT_PATH: 库文件输出的存放路径
2. 编写CMakeLists.txt文件
首先,编写CmakeLists.txt文件,在工作区文件夹创建CmakeLists.txt,编写如下代码:
cmake_minimum_required (VERSION 3.22 .1 )
project (SWAP)
include_directories (include )
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall" )
set (CMAKE_BUILD_TYPE Debug)
add_executable (main main.cpp src/swap.cpp)
set (EXECUTABLE_OUTPUT_PATH "../out" )
编写完成之后,可以使用终端命令,检验CMakeLists文件编写是否正确,在终端进入bulid目录,输入以下指令:
运行结果如下:
可以看到运行成功。
3. 配置launch.json文件和task.json文件
launch.json文件完成的是调试工作,有两个参数很关键,分别是
program和preLaunchTask,两个参数分别代表了调试运行程序的名称 和在调试运行前执行的任务。该两项需要修改,如图所示:
launch.json的代码如下:
{
"version" : "0.2.0" ,
"configurations" : [
{
"name" : "g++ - Build and debug active file" ,
"type" : "cppdbg" ,
"request" : "launch" ,
"program" : "${workspaceFolder} /out/${fileBasenameNoExtension} " ,
"args" : [],
"stopAtEntry" : false ,
"cwd" : "${fileDirname} " ,
"environment" : [],
"externalConsole" : false ,
"MIMode" : "gdb" ,
"setupCommands" : [
{
"description" : "Enable pretty-printing for gdb" ,
"text" : "-enable-pretty-printing" ,
"ignoreFailures" : true
}
],
"preLaunchTask" : "Build" ,
"miDebuggerPath" : "/usr/bin/gdb"
}
]
}
task.json执行的是编译产生可执行文件的工作,其代码如下:
{
"version" :"2.0.0" ,
"options" : {
"cwd" : "${workspaceFolder} /build"
},
"tasks" : [
{
"type" : "shell" ,
"label" : "cmake" ,
"command" : "cmake" ,
"args" : [
".."
]
},
{
"label" : "make" ,
"group" : "build" ,
"command" : "make" ,
"args" : [
]
},
{
"label" : "Build" ,
"dependsOrder" : "sequence" ,
"dependsOn" :[
"cmake" ,
"make"
]
}
],
}
配置好两个文件就可以按F5调试运行了,运行结果和之前一样,至此使用cmake和vscode编译运行多文件C++程序完成。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?