linux编译器和自动化构建工具(gcc与Makeile)

Linux编译器与自动化构建工具详解

1.linux编译器

1.1.常见的linux编译器

(1)GCC (GNU Compiler Collection):
  - Linux 上最常用的编译器,支持 C、C++、Objective-C、Fortran、Ada 等多种语言。
  - 通常 Linux 系统默认安装,可通过命令 `gcc` 或 `g++` 调用。
  
(2)Clang:
  - 基于 LLVM 的轻量级编译器,支持 C、C++ 等语言。
  - 错误信息提示更加友好,编译速度快。
  
(3)Ninja:
  - 小巧高效的构建系统,专为并行构建设计,常配合 CMake 使用以提高构建速度。

自动化构建工具: 

Make:
  - Make 是一种构建自动化工具,虽然不是编译器,但用于管理编译过程
  - 使用 `Makefile` 组织编译规则,支持大型项目的构建。
  
CMake:
  - 跨平台构建系统生成器,生成适用于多种编译器的构建文件,常与 Make 或 Ninja 配合使用。 

1.2.gcc常见选项

gcc选项
 
-E:只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面
-S:编译到汇编语言,不进行汇编和链接
-c:只编译为目标文件(.o),不链接生成可执行文件。
-o <file>:指定输出文件名称。
-std=<标准>:指定标准版本(例如 `-std=c99`、`-std=c++11`)。
-static:强制使用静态链接,将所有依赖的库代码打包到可执行文件中
-shared:生成动态链接库(.so 文件,Windows 下为 .dll),而非可执行文件
-g:生成调试信息。GNU 调试器可利用该信息。
-O0, -O1, -O2, -O3:优化等级,从不优化(O0)到最大优化(O3)。
-w:不生成任何警告信息。
-Wall:生成所有警告信息。
-I<目录>:告诉编译器在默认头文件路径(如 /usr/include)之外,
额外从 <目录> 中查找 #include 的头文件,可多次使用 -I 指定多个路径
-L<目录>:告诉链接器在默认库路径(如 /usr/lib)之外,额外从 <目录> 中查找库文件
-l<库名>:指定要链接的库(省略前缀 lib 和后缀 .so/.a)
-D<宏定义>:在编译时定义宏,例如 `-DDEBUG`。

1.3.gcc如何完成

GCC 的编译过程主要分为四个阶段:预处理、编译、汇编、链接

1. 预处理:处理 #include、#define 等预处理指令,生成预处理后的代码文件。

2. 编译:将预处理后的代码转为汇编代码。可以使用 gcc -S file.i -o file.s 查看生成的汇编代码。

3. 汇编:将汇编代码转为目标文件(机器码),可以使用 gcc -c file.s -o file.o 查看目标文件。

4. 链接:将目标文件与库文件链接生成可执行文件。最终执行 gcc file.o -o program,生成program 可执行文件。

 (1) 预处理

gcc -E code.c -o code.i

-E:从现在开始进行程序的编译,一旦预处理做完,就停下来

-o:指定输出文件的名称

code.i:存储 code.c 预处理后的结果

展开宏定义,头文件展开 ,删除注释,生成纯粹的 C 代码文件等。

(2) 编译

gcc -S code.i -o code.s

-S:开始进行程序翻译,编译做完,形成汇编,就停下来 

(3) 汇编(生成机器可识别代码)

gcc -c code.s -o code.o

-c:开始进行程序翻译,汇编完成就停下来

code.o:重定位二进制目标文件,无法执行。

(4)链接(生成可执行文件或库文件)

gcc code.o -o code

.o库文件进行连接形成可执行文件

直接操作:

gcc file.c:直接生成目标文件的可执行程序

gcc -c file.c:直接生成目标文件的同名.o文件

1.4.动静态库简介

在 Linux 上,静态库和动态库的创建和使用方式有所不同,以下是如何生成和链接这两种库的详细步骤。

 在Linux中,ldd命令用于显示一个可执行文件或共享库所依赖的共享库及其路径。file命令用于识别文件的类型。它通过检查文件的内容而不仅仅是文件扩展名来确定文件类型。

 这里的dynamically表示a.out文件是动态链接的。

gcc默认的可执行程序是动态链接的。

1.4.1.动态库

动态库在程序运行时加载,不会将库的内容嵌入可执行文件。动态库的文件扩展名通常为 .so(shared object)。

生成动态库时需要使用 -fPIC 和 -shared 选项。假设我们仍然使用 file1.c 和 file2.c。

-fPIC:该选项确保编译生成的代码不依赖于特定的内存地址,
使得代码可以被加载到内存的任意位置执行。
这是动态库的核心特性之一,因为动态库在运行时可能被加载到进程地址空间的不同位置,
而位置无关代码能保证其正常工作。

-shared:该选项告诉编译器将目标文件链接为动态库,而不是可执行文件。

1. 编译源文件:使用 -fPIC 选项生成位置无关代码(Position-Independent Code)。

   gcc -fPIC -c file1.c -o file1.o
   gcc -fPIC -c file2.c -o file2.o

在Linux

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值