用g++命令执行C++多文件项目
用g++命令执行C++多文件项目
(一)过程执行
C 或者 C++ 程序的执行过程分为 4 步,依次是预处理、编译、汇编和链接。
在执行 C++ 项目时,头文件是不需要经历以上这 4 个阶段的,只有项目中的所有源文件才必须经历这 4 个阶段。
假设,当前项目中有 1 个 student.h 头文件,student.cpp 和 main.cpp 2 个源文件。接下来就用 g++ 命令执行此项目,其过程依次是:
1.预处理阶段
g++ -E main.cpp -o main.i g++ -E student.cpp -o student.i
# -E 编译器对文件进行预处理
-E 选项用于限定 g++ 编译器只进行预处理而不进行后续的 3 个阶段;-o 选项用于指定生成文件的名称。Linux 系统中,通常用 ".i" 作为 C++ 程序预处理后所得文件的后缀名。
可运行 cat main.i 指令查看 main.i 文件中的内容
2.编译阶段
对预处理阶段得到的 -i 文件做进一步的语法分析,生成相应的汇编代码文件
g++ -S main.i -o main.s
g++ -S student.i -o student.s
# -S编译器告诉g++再为c++代码产生汇编语言后停止编译
-S 选项用于限定 g++ 编译器对指定文件进行编译,得到的汇编代码文件通常以“.s”作为后缀名。
可以使用 cat 命令查看生成文件的内容。
3.汇编阶段
将汇编代码文件转换成可以执行的机器指令
g++ -c main.s -o main.o g++ -c student.s -o student.o # -c 选项告诉g++仅把源代码编译为机器语言的目标代码
-c 指令用于限定 g++ 编译器只进行汇编操作,最终生成的目标文件(本质就是二进制文件,但还无法执行)通常以“.o”作为后缀名。
4.链接阶段
将所有的目标文件组织成一个可以执行的二进制文件
g++ main.o student.o -o student.exe
如果不用 -o 指定可执行文件的名称,默认情况下会生成 a.out 可执行文件。Linux 系统并不以文件的扩展名开分区文件类型,所以 a.out 和 student.exe 都是可执行文件,只是文件名称有区别罢了。
经历以上 4 步,最终会生成 student.exe 可执行文件,其执行方式为:
./student.exe
注意“./”表示当前目录,不能省略。
(二)直接执行
直接执行如下命令即可生成最终的可执行文件
g++ main.cpp student.cpp -o student.exe
./student.exe
(三)g++重要参数指令
1.-g 编译带调试信息的可执行文件
# -g 选项告诉GCC产生能被GNU调试器使用的调试信息,以调试程序 g++ -g test.cpp -o test # 产生带调试信息的可执行文件test(o小写)
2.-O[n] 优化源代码(O大写)
# -O 告诉g++ 对源码进行基本优化 -O2告诉g++产生尽可能小和尽可能快的代码(通常使用) # -O! 同时减小代码的长度和执行时间,等同于-O1 # -O0 表示不做优化 # -O1 默认优化 # -O2 除了完成-O1外,还进行一些额外工作,如指令调整 # -O3 包括循环展开和其他一些与预处理特性相关的优化工作 g++ -O2 test.cpp #使用-O2优化源代码,产生可执行文件
3.-l和 -L 指定库文件 | 指定库文件路径
# -l参数(小写)就是用来指定程序要链接的库,-l参数紧接着就是库名 # 在/lib和/usr/lib和/usr/local/lib里的库直接用-l参数就能链接 # 链接glog库 g++ -l glog test.cpp
# 如果库文件没放在上面三个目录里,需要使用-L参数(大写)指定库文件所在目录 # -L参数跟着的是库文件所在的目录名 # 链接mytest库,libmytest.so在/home/bing/mytestlibfolder目录下 g++ -L/home/bing/mytestlibfolder -lmytest test.cpp
"-fdiagnostics-color=always", "-g", //"${file}", // 仅编译当前打开的源文件 "${fileDirname}\\*.cpp", // 编译当前文件夹下的所有源文件 //配置MySQL,使用mysql.h "-I", "C:\\Program Files\\MySQL\\MySQL Server 8.0\\include", "-L", "C:\\Program Files\\MySQL\\MySQL Server 8.0\\lib", "-lmysql", "-o", "${fileDirname}\\${fileBasenameNoExtension}.exe",
4.-I (大写i) 指定头文件搜索目录
# -I # /usr/include目录一般是不用指定的,gcc知道去那里找,但是如果头文件不在/usr/icnclude里我们就要用-I参数指定了, 比如头文件放在/myinclude目录里,那编译命令行就要加上-I/myinclude 参数了, 如果不加你会得到一个”xxxx.h: No such file or directory”的错误。 -I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定。 上面我们提到的–cflags参数就是用来生成-I参数的。 g++ -I /myinclude test.cpp
5.-Wall 打印警告信息
# 打印出gcc提供的警告信息
g++ -Wall test.cpp
6.-w 关闭警告信息
# 关闭所有警告信息
g++ -w test.cpp
7.-std=c++11 设置编译标准
# 使用 c++11 标准编译 test.cpp g++ -std=c++11 test.cpp
8.-o 指定输出文件名
# 指定即将产生的文件名
# 指定输出可执行文件名为test
g++ test.cpp -o test
9.-D 定义宏
# 在使用gcc/g++编译的时候定义宏 # 常用场景: # -DDEBUG 定义DEBUG宏,可能文件中有DEBUG宏部分的相关信息,用个DDEBUG来选择开启或关闭 DEBUG
// -Dname 定义宏name,默认定义内容为字符串“1” #include <stdio.h> int main() { #ifdef DEBUG printf("DEBUG LOG\n"); #endif printf("in\n"); } // 1. 在编译的时候,使用gcc -DDEBUG main.cpp // 2. 输出 DEBUG LOG in //使用gcc -DDEBUG main.cpp,若为#ifndef,输出in
(四)阻止exe命令行文件执行完自动关闭
1.起因
双击运行命令行(DOS)下的软件,一旦程序执行完毕后命令行窗口就自动关闭,如果你想看运行结果的话就比较麻烦。
(当然可以在命令提示符下输入程序所在路径运行)
2.解决方案
- 新建记事本
- 编辑内容
@echo off call %1 echo. echo. pause
- 保存,重命名为
run.bat
- 将exe文件拖动到
run.bat
文件上执行
这样文件执行完以后就不会自行关闭了
(五)错误:'::main' must return 'int'
//main.cpp #include"a.h" #include"b.h" void main() { C_A a; C_B b; a.funA(); b.funB(); }
再IDE上可以和其他文件运行,但是运行g++ -S main.i -o main.s
解决方案:将void main()修改即可
在最新的 C99 标准中,只有以下两种定义方式是正确的:
int main(void){////}//整数类型主函数(无类型)
int main(int argc,char **argv)//整数类型主函数(整数类型 统计参数个数,字符类型*数组指针至字符[])
main 函数的返回值类型必须是 int ,这样返回值才能传递给程序的激活者(如操作系统)。
如果 main 函数的最后没有写 return 语句的话,C99 规定编译器要自动在生成的目标文件中(如 exe 文件)加入return 0; ,表示程序正常退出。不过,我还是建议你最好在main函数的最后加上return 语句,虽然没有这个必要,但这是一个好的习惯。
也就是说在最新的C语言标准中强制要求main函数的返回值类型为int,main函数的返回值是传递给操作系统,让操作系统判断程序的执行情况(是正常结束还是出现异常)
C++ 11语法中明确规定了main的返回类型必须是int,这和早期C/C++语法中允许main的返回类型为void有所不同。
译
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了