Linux--gcc的基本用法

gcc 是 GUN Compiler Collection的缩写,可以支持多种语言编译,比如 C,C++,Java, pascal 等。

一、gcc的编译过程

1.四个过程

在这里插入图片描述

  • 预处理(pre-processing)E
    编译器将C源代码中的包含的头文件如stdio.h编译进来,替换宏。
  • 编译(Compiling)S
    gcc首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc把代码翻译成汇编语言。
  • 汇编(Assembling) c
    把编译阶段生成的”.s”文件转成二进制目标代码。
  • 链接 (Linking)
    链接到库中,生成可执行文件。
    gcc -E hello.c -o hello.i
    gcc –S hello.i –o hello.s
    gcc –c hello.s –o hello.o
    gcc hello.o –o hello
    

2.一次性完成

gcc hello.c –o hello

但一般情况下生成.o文件比较好,可以重定位文件,让别人使用。

二、gcc常用选项

选项名 作用
E 激活预处理;头文件、宏等展开(.i文件)
S 激活预处理、编译;生成汇编代码(.s文件)
c 激活预处理、编译、汇编;生成目标文件(.o文件)
o 生成目标
Wall 打开编译告警(所有)
g 嵌入调试信息,方便gdb调试
llib 链接 lib 库 (这里是小写 L ) 相当于 C++ #pragma comment(lib, “xxx.lib”)
Idir 增加 include 目录 (这里是大写 i ) 头文件路径
LDir 增加 lib 目录 (编译静态库和动态库)

三、多模块编译

  • 一次性编译:
    gcc -Wall fun.c main_fun.c –o main_fun
    
  • 独立编译:
    gcc –Wall –c main_fun.c –o main_fun.o
    gcc –Wall –c fun.c –o fun.o
    gcc –Wall main_fun.o fun.o –o main_fun
    

多模块编译中如果某一个模块发生了变化,只需要编译更改的模块即可

四、静态库与动态库

1.静态库(.a)

程序在编译链接时候把库的代码链接到可执行文件中。程序运行时候,不再需要静态库,生成的可执行文件大,每个可执行文件都会加载一份拷贝到内存。

  • 静态库生成(libxxx.a)
    首先生成.o文件,然后通过.o文件生成.a文件,例如:
    gcc –c fun.c
    ar rcs libfun.a fun.o
    
  • 静态库使用
    gcc –Wall main.c libfun.a –o main
    gcc –Wall –L. main.c –o main –lfun
    
    -L. 表示在当前目录搜索 libfun.a
  • 静态库搜索路径
    1:编译使用选项 –L 指定的目录(建议)
    2:修改环境变量,搜索指定的目录,设置环境变量LIBRARY_PATH并导出:
     export LIBRARY_PATH=“库目录”
    
    3:lib文件放入系统指定目录,例如/usr/lib/

2.动态库(.so或.sa)

动态库编译链接时并没有把库文件的代码加入到可执行文件中,而是程序运行时候才去链接动态库代码,多个程序动态使用,使用时候只需要加载一份到内存,从而节省系统的开销。

  • 动态库生成(libxxx.so
    直接可以通过.c文件生成.so文件,例如:
    gcc –shared –fPIC fun.o –o libFun.so
    
    shared:生成动态库格式。
    fPIC: 产生位置无关码,允许在任何地址加载相对地址,否则只能从指定地址加载,无法控制。
  • 动态库使用
    gcc –Wall main.o –o main –L. -lFun
    
    只需要 -l + 文件名即可。
  • 配置方式
    1:拷贝到so文件到动态库目录 /usr/lib/。
    2:更改 LD_LIBRARY_PATH,如果已经有了一个这样的目录,要写成:
    export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:“库目录”
    
    如果没有的话就写成:
    export LD_LIBRARY_PATH=“库目录”
    
    3:配置 /etc/ld.so.conf;并使用 ldconfig 命令进行更新。
  • ldd查看动态库加载情况
    在这里插入图片描述

五、默认头文件路径

每个编译器都有自己的头文件和库文件,可以通过以下命令查看gcc默认搜索的头文件路径和库路径:

echo 'main'|gcc -E -v -

部分结果如下:

#include "..." search starts here:
#include <...> search starts here:
 /usr/lib/gcc/x86_64-linux-gnu/5/include
 /usr/local/include
 /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed
 /usr/include/x86_64-linux-gnu
 /usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"
main

使用该命令查询arm-linux-gcc时得到以下结果:

#include "..." search starts here:
#include <...> search starts here:
 /usr/local/arm/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/include
 /usr/local/arm/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/include-fixed
 /usr/local/arm/arm-2009q3/bin/../lib/gcc/arm-none-linux-gnueabi/4.4.1/../../../../arm-none-linux-gnueabi/include
 /usr/local/arm/arm-2009q3/bin/../arm-none-linux-gnueabi/libc/usr/include
End of search list.
# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "<stdin>"
main


转载地址:

猜你喜欢

转载自blog.csdn.net/Meteor_s/article/details/85208589
今日推荐