gcc简介及使用技巧带例子

关键字:GNU GCC gcc 编译 链接 搜索路径

目录

目标

脑图

内容

1 是什么

2 为什么

1 有什么

1.1 GCC gcc 和g++有什么区别?

1.2开发前的准备

1.3 gcc常用选项

1.4 gcc进阶

1.5 gcc编译路径问题

1.6 附录


目标

  • 什么是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编译器将对#开头的指令进行解析替换。

  • 删除了注释。

  • 其他头文件内的函数声明会包含进来,但.c内的实现并不会包含进来。

  • 宏常量被替换

  • 宏代码被替换

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在编译时会做以下额外的操作:

  • 创建符号表,符号表包含了程序中使用的变量名称的列表;

  • 关闭所有的优化机制,以便程序执行过程中严格按照原来的C代码进行。

 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 头文件

#include<>

直接到系统指定的某些目录中去搜索某些头文件

#include ""

先到源文件所在文件夹去找,然后再到系统指定的某些目录中去找某些头文件。

  重复引用问题:头文件定义方式。

#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!这次一定!!有什么建议也可以在评论区或私信我!千里之行始于足下,共勉!

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值