【Linux】GCC编译器的使用

目录

前言:

 一、GCC编译过程

1.预处理:

2.编译

3.汇编

4.链接

二、制作、使用动态库和静态库

1.静态库

2.动态库

 三、好用的选项

 1.gcc -E main.c

 2.gcc -E -dM main.c > 1.txt

  3.gcc -Wp,-MD,abc.dep -c -o main.o main.c

  4.echo 'main(){}'| gcc -E -v -


前言:

2-1.GCC编译过程_哔哩哔哩_bilibili

2-2.GCC常用选项_哔哩哔哩_bilibili

(1)PC机上的gcc编译工具链,编译出来的程序是可以在X86平台上运行,要编译出能在ARM平台上运行的程序,必须使用交叉编译工具xxx-gcc。

(2)一个C/C++文件要经过预处理(生成.i文件)编译(生成.s)汇编(生成.o文件)以及链接(链接上应用程序)四步才能变成可执行文件。如下:

(3)我们可以通过不同的gcc选项控制输出不同的文件,常用的选项如下:

 一、GCC编译过程

1.预处理:

C/C++源文件中常见的预处理命令,有包含命令(#inlcude),宏定义命令(#define)以及条件编译命令(#if、#ifdef)。

预处理就是将要包含(include)的文件插入原文件中、将宏定义展开、根据条件 编译命令选择要使用的代码,最后将这些东西输出到一个.i文件中等待进一 步处理

2.编译

编译就是将C/C++代码(上述.i文件)“翻译”成汇编代码。

3.汇编

 汇编就是将第二步输出的汇编代码翻译成符合一定格式的机器代码,在Linux 系统上一般表现为ELF 目标文件(OBJ 文件)。

4.链接

链接就是将上步生成的 OBJ 文件和系统库的 OBJ 文件、库文件链接起来,最终生成了可以在特定平台运行的可执行文件。 

二、制作、使用动态库和静态库

着重注意使用的库的路径。

1.静态库

利用静态库编译成的文件比较大,是将整个函数库的所有数据整合到目标代码中,它的优点是编译后的执行程序不需要外部的函数库支持。

gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
//由.o文件创建静态库
ar crs libsub.a sub.o 
//(如果.a 不在当前目录下,需要指定它的绝对或相对路径)
gcc -o test main.o libsub.a 

注:使用ar命令生成静态库,必须要用.o文件生成(不能用其它文件)。并且生成的.a文件必须要以lib开头(要不会找不到库)。

2.动态库

动态函数库在编译的时候没有编译进目标代码中,程序执行到相关函数时调用该函数库里的相应函数。

所以动态库相较于静态库来说,节省了系统空间,遇到库有bug时,只要用新的库把原来的库替换即可。

gcc -c -o main.o main.c
gcc -c -o sub.o sub.c
gcc -shared -o libsub.so sub.o
gcc -o test2 main.o -L   /所在目录/  -lsub 
//(以当前目录为例)
gcc -o test2 main.o -L ./ -lsub

 注:生成的动态库文件是在当前文件夹,编译时需要将其路径加入lib或者指定好所在路径。

如果没有lib时,运行时还需要运行下面的命令(指定路径):

export LD_LIBRARY_PATH=$LD_LIBRARY_PATH: ./
./test2

运行测试(指定路径): 

 三、好用的选项

 1.gcc -E main.c

查看预处理结果,比如头文件是哪个 ,具体结果:

 2.gcc -E -dM main.c > 1.txt

 把所有的宏展开,存在 1.txt 里,具体示例(打开1.txt): 

  3.gcc -Wp,-MD,abc.dep -c -o main.o main.c

生成依赖文件 abc.dep,后面 Makefile 会用,具体示例(打开abc.dep):

  4.echo 'main(){}'| gcc -E -v -

编译'main(){}'时列出其头文件目录、库目录(LIBRARY_PATH),具体示例:

猜你喜欢

转载自blog.csdn.net/weixin_42373086/article/details/129887540