用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.解决方案

  1. 新建记事本
  2. 编辑内容
@echo off
call %1
echo.
echo.
pause
  1. 保存,重命名为run.bat
  2. 将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有所不同。

posted @ 2022-11-28 19:57  ImreW  阅读(746)  评论(0编辑  收藏  举报