[001][Linux] gcc基本命令

Linux
Contents
简介
基本语法与命令
使用方法
常用命令
Makefile的
引入及规则
基本规则
makefile实验

1 简介

GCC(GNU Compiler Collection,GNU编译器套件)是由GNU开发的编程语言译器,GNU工具链也包含了编译器、汇编器和连接器。一个C/C++文件要经过预处理(Preprocessing)、编译(Compilation)、汇编 (Assembly)和连接(Linking)才能变成可执行文件,过程如下图所示:

image-20220314200325225

▲ 基于GNU工具链的开发流程模式图
  • 预处理
    C/C++源文件中,以“#”开头的命令被称为预处理命令,如包含命令“#include”、宏定义命令“#define”、条件编译命令“#if”、“#ifdef”等。预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件编译命令选择要使用的代码,最后将这些东西输出到.i文件中等待进一步处理。
  • 编译
    编译就是把C/C++代码(比如上述的.i文件)“翻译”成汇编代码。
  • 汇编
    汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux系统上一般表现为ELF目标文件(OBJ文件)。(“反汇编”是指将机器代码转换为汇编代码,这在调试程序时常常用到。)
  • 链接
    链接就是将上步生成的OBJ文件和系统库的OBJ文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件。

GNU工具链的语法与ARM汇编语法有些不同,这些不同点包括变量定义、编译指示字、以及the like。

预处理不做语法检查,只是将include包含的文件插入原文件中、将宏定义展开、根据条件编译命令,如源文件hello.c预处理为hello.i

#include <stdio.h>

#define   MAX  20 
#define   MIN  10 

// #define  _DEBUG
#define   SetBit(x)  (1<<x) 

int main(int argc, char* argv[])
{
    printf("Hello World \n");
    printf("MAX = %d,MIN = %d,MAX + MIN = %d\n",MAX,MIN,MAX + MIN); 
    printf("SetBit(5) = %d,SetBit(6) = %d\n",SetBit(5),SetBit(6));
     
#ifdef _DEBUG
	printf("SetBit( SetBit(2) ) = %d\n",SetBit( SetBit(2) ));  
#endif    
	return 0;
}

#include <stdio.h>展开代码太多不做展示,上面的宏而预处理命令展开如下:

image-20220314203129228

MAXMINSetBit(x) 进行了展开,条件处理了#ifdef _DEBUG

因为不做语法检查,添加非法代码也能正常预编译:

image-20220314203415608

在编译阶段才会做语法检查:

image-20220314204651890

2 基本语法与命令

gcc命令区分大小写

2.1 使用方法

gcc  [选项]   文件名

gcc常用选项:

选项功能
-v查看gcc编译器的版本,显示gcc执行时的详细过程
-o <file>指定输出文件名为file,这个名称不能跟源文件名同名
-E只预处理,不会编译、汇编、链接
-S只编译,不会汇编、链接
-c编译和汇编,不会链接
-I<头文件目录>指令头文件(.h)目录(不指定优先从系统目录寻找)
-L<库目录>指定依赖的库目录(so、或lib、dll)

Linux下的库文件分为两大类分别是动态链接库(通常以.so结尾)和静态链接库(通常以.a结尾),二者的区别仅在于程序执行时所需的代码是在运行时动态加载的,还是在编译时静态加载的。

默认情况下, GCC在链接时优先使用动态链接库,只有当动态链接库不存在时才考虑使用静态链接库,如果需要的话可以在编译时加上-static选项,强制使用静态链接库。如:

gcc -L /usr/dev/test/lib -static -o hello hello.o  

2.2 常用命令

hello.c(预处理)->hello.i(编译)->hello.s(汇编)->hello.o(链接)->hello
详细的每一步命令如下:

gcc -E -o hello.i hello.c	// 预处理
gcc -S -o hello.s hello.i	// 编译
gcc -c -o hello.o hello.s	// 汇编
gcc -o hello hello.o		// 链接

gcc会对.c文件默认进行预处理操作,因此可使用-c再来指明了编译、汇编,从而得到.o文件,再将.o文件进行链接,得到可执行应用程序:

// 方法一
gcc -c -o hello.o hello.c  // 先编译(做了前三步,但不链接)
gcc -o hello hello.o       // 再链接
// 方法二
gcc -o hello hello.c 	   // 编译+链接  (多个文件每次都会全部编译,效率低下)

对于多个源文件,使用gcc -o <file> file.c 命令简单,如:

gcc -o hello a.c b.c c.c

同时编译三个源文件,但是效率低下,某个文件修改就会全部重新编译,所以一般使用方法一:

gcc -o a.o a.c 
gcc -o b.o b.c 
gcc -o c.o c.c 
gcc -o hello a.o b.o c.o   

3 Makefile的引入及规则

3.1 基本规则

对于MDK等IDE首次编译工程时会全部编译,后面点击单编译只会编译修改过的文件,该功能Makefile+gcc也可以做到。

makefie最基本的语法是规则,规则:

目标 : 依赖1 依赖2 ...
[TAB]命令

当“依赖”比“目标”新(依据文件修改时间),执行它们下面的命令。我们要把上面三个命令写成makefile规则,如下:

test :a.o b.o  // test是目标,它依赖于a.o b.o文件,一旦a.o或者b.o比test新的时候,就需要执行下面的命令,重新生成test可执行程序。
	gcc -o test a.o b.o
a.o : a.c  		// a.o依赖于a.c,当a.c更加新的话,执行下面的命令来生成a.o
	gcc -c -o a.o a.c
b.o : b.c  		// b.o依赖于b.c,当b.c更加新的话,执行下面的命令,来生成b.o
	gcc -c -o b.o b.c

3.2 makefile实验

  • a.c
#include <stdio.h>

int main()
{
	func_b();
	return 0;
}
  • b.c
#include <stdio.h>

void func_b()
{
	printf("This is B\n");
}
  • makefile
test:a.o b.o
		gcc -o test a.o b.o
a.o : a.c
		gcc -c -o a.o a.c
b.o : b.c
		gcc -c -o b.o b.c

输入make执行makefile:

image-20220314213120972

执行了三条命令:

gcc -c -o a.o a.c
gcc -c -o b.o b.c
gcc -o test a.o b.o

再次执行make

gcc -o test a.o b.o  // 按理说会显示make: `test' is up to date.

修改a.c后:

gcc -c -o a.o a.c
gcc -o test a.o b.o

END

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

柯西的彷徨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值