关键字:GNU GCC gcc 编译 链接 搜索路径
目录
目标
-
什么是gcc,它能干什么?
-
GCC、gcc、g++三者有何关系?
-
开始开发前应该做些什么准备?
-
掌握gcc常用指令的使用。
脑图
内容
1 是什么
GCC(GNU Compiler Collection)即GNU编译器套件,属于一种编程语言编译器,其原名为GCC(GNU C Compiler)即GNU 。
c语言编译器,虽然缩写一样但是功能上区别很大。GCC的初衷是为GNU操作系统专门编写的一款编译器,原本的GNU是专用于编译C代码,现如今已扩展为可以编译C、C++、Java、Objective-C等多种编程语言的编译器集合了。
2 为什么
1 有什么
1.1 GCC gcc 和g++有什么区别?
GCC | GNU Compiler Collection |
gcc | GUN C Compiler是GCC中的C编译器 |
g++ | GUN c++ Compiler是GCC中的C++编译器 |
1.2开发前的准备
linux系统安装方式参考:Window上装Linux系统的便捷方法,简单又省事!
Linux ubuntu安装方式:sudo apt-get install gcc
VsCode安装方式:搜索插件安装
Windows上安装方式: https://osdn.net/projects/mingw/releases/
检查命令:gcc -v //查看版本号
1.3 gcc常用选项
相关用例代码以及目录请看附录!
命令行 | 解释 |
gcc ../code/src/test.c | 生成a.out可执行文件,通过./a.out可以执行该文件(执行时要指定目录,当前目录下要加./) |
gcc ../code/src/test.c -o ./test.out | 选项-o指定生成的可执行文件的名称,可选择生成文件放置的目录。 |
gcc -E ../code/src/demo.c -o demo.i | Preprocessing预处理,-E(大写)将执行预处理操作也即生成*.i文件。
gcc -E Demo.c不指定输出文件名时会直接将内容输出,而不产生文件。预处理阶段不会检查语法错误,但会检查头文件问题。 |
gcc -S demo.i -o demo.s | Compiling编译,-S(大写)是将*.i文件中源码转化为汇编代码*.s文件。 如果使用gcc -s demo.i即不指定输出文件名,默认也将在当前目录下产生文件demo.s 编译阶段会检查语法错误,只检查函数的声明调用是否符合函数的原型 |
gcc -c demo.s -o demo.o | Assembling汇编,-c(小写)指令将*.s文件中的汇编源码转化成机器能执行的二进制码,生成二进制文件*.o。 |
gcc demo.o -o demo.out | linking链接,经过汇编处理后生成的二进制文件demo.o虽然已经是机器码,但任然无法运行,因为少了链接操作。 检查函数的定义。 |
补充:自己定义了头文件,以及头文件中函数申明的定义.c文件并在demo.c中调用,那么执行gcc demo.o -o demo.out可能会报错。
详细原因请看: (11条消息) 浅显易懂的GCC使用教程——初级篇_大娱乐家-CSDN博客_gcc使用
处理方法:使用命令gcc -c ../code/srctest.c -o test.o生成test.o二进制文件,接着使用ar -rcs ../lib/libtest.a test.o(ar命令:创建或修改备存文件,或是从备存文件中抽取文件。-r:将文本插入备存文件中,-c:创建备存文件,-v:程序执行时显示详细的信息)生成静态库文件libtest.a,然后再次尝试对Demo.o执行链接操作gcc demo.o ../lib/libtest.a -o demo.out。
方法2:gcc ../code/src/demo.c ../code/src/test.c -o demo.out
1.4 gcc进阶
使用命令gcc -g ../code/src/demo.c -o demo.out时,gcc在编译时会做以下额外的操作:
|
gcc优化选项:gcc -O0:缺省情况下,不优化。相关了解请看: (11条消息) Linux下gcc 优化等级的介绍_yanghan1233的博客-CSDN博客 |
使用命令gcc ../code/src/demo.c -include ../code/test.c相当于在代码中使用#include"test.c" |
库相关:静态库、动态库 |
使用命令gcc -C -E ../code/src/demo.c -o demo.i不删除注释信息,一般和-E使用,分析程序。 |
使用命令gcc -M../code/src/demo.c -o head使用到的所有源代码,头文件输出到文件head中 |
使用命令gcc -MM ../code/src/demo.c -o head使用到的所有源代码,头文件输出到文件head中,忽略所有#include<file>造成的依赖关系。 |
使用命令gcc -I /usr/local/include/ |
1.5 gcc编译路径问题
1.5.1 头文件
| 直接到系统指定的某些目录中去搜索某些头文件 |
| 先到源文件所在文件夹去找,然后再到系统指定的某些目录中去找某些头文件。 |
重复引用问题:头文件定义方式。
#ifndef _TEST_H_
#define _TEST_H_
//codes
#endif
默认情况下,gcc在下面目录中搜索头文件(路径:include路径)
/usr/local/include/
/user/include/
gcc搜索include顺序:
""时,源文件所在目录,不会搜索源文件所在目录的子目录
-I指定目录
环境变量C_INCLUDE_PATH
系统默认路径 (路径下的次级目录是按序找搜索的)
gcc -E ../code/src/demo.c -o demo.i -I ../code/include/ | 把新的include目录添加到gcc搜索路径。 |
1.5.2 库文件
默认情况下,gcc在下面目录中搜索库:(搜索路径或链接路径):
/usr/local/lib/
/user/lib/
当有其他库被安装到另外的目录中,为了能找到这些库,需要扩展搜索路径
gcc ../code/src/demo.c -l test -L ../lib/ -o demo.out | 把新的搜索目录添加到库搜索路径中。库文件实际的名称libtest.a |
gcc搜索库路径顺序:
-L指定目录
环境变量LIBRARY_PATH
系统默认路径 (路径下的次级目录是按序找搜索的)
usr,unix system resource
/lib | 内核级,包含许多被/bin/和/sbin/中的程序使用到的库文件 |
/usr/lib | 系统级,用于用户程序的库文件 |
/usr/local/lib | 用户级的 |
/usr/bin | 几乎所有的系统可执行文件都会安装到这里 |
/usr/local/bin | 存放一些系统用户自己特定的可执行文件,不用担心被系统升级之类的行为覆盖、破坏,这个目录不是必须的。 |
思考:自己定义的库文件太多,使用gcc链接时每一个都要调用岂不是很麻烦?怎么解决的?
1.6 附录
1.6.1 目录结构
1.6.2 代码
test.h
#ifndef _TEST_H_
#define _TEST_H_
#define N 1
#define CODE if(c>2) { \
printf("c > 2\n"); \
}
void do_nothing(void); //函数申明(该函数未被调用)
#endif
test.c
#include"test.h"
void do_nothing(void)
{
;
return;
}
demo.c
#include<stdio.h>
#include<stdlib.h>
#include"test.h"
int main()
{
int a = N;
int b = 2;
int c = 0;
c = a + b;
printf("%d\n", c);
CODE
do_nothing();
system("pause");
return 0;
}
如果你觉得这篇文章对你有帮助,不妨点个赞支持一下ba!这次一定!!有什么建议也可以在评论区或私信我!千里之行始于足下,共勉!