GCC编译原理与使用

发布于:2024-03-15 ⋅ 阅读:(44) ⋅ 点赞:(0)

介绍:

GCC 原名为 GNU C语言编译器,因为它原本只能处理 C 语言,但如今的 GCC 不仅可以编译 C、C++ 和 Objective-C,还可以通过不同的前端模块支持各种语言,包括 Java、Fortran、Ada、Pascal、Go 和 D 语言等等。

编译过程:

GCC的编译过程可以划分为四个阶段:

  • 预处理(Pre-Processing)
  • 编译(Compiling)
  • 汇编(Assembling)
  • 链接(Linking)

Linux 程序员可以根据自己的需要控制 GCC 的编译阶段,以便检查或使用编译器在该阶段的输出信息,帮助调试和优化程序。以 C 语言为例,从源文件的编译到可执行文件的运行,整个过程大致如下。

各文件后缀说明:

语法:

gcc [options] file ....

options:

  • -pass-exit-codes:从一个阶段以最高错误代码退出
  • --target-help:显示特定于目标的命令行选项
  • -dumpspecs:显示所有内置规范字符串
  • -dumpversion:显示编译器的版本
  • -dumpmachine: 显示编译器的的目标处理器
  • -print-search-dirs :显示编译器配套库的名称
  • -print-file-name= :显示库  的完整路径。
  • -print-prog-name= :显示编译器组件  的完整路径。
  • -print-multiarch :显示目标的规范化 GNU 三元组,用作库路径中的一个组件。
  • -print-multi-directory :显示 libgcc 版本的根目录。
  • -print-multi-lib :显示命令行选项和多个库搜索目录之间的映射。
  • -print-multi-os-directory :显示操作系统库的相对路径。
  • -print-sysroot :显示目标库目录。
  • -print-sysroot-headers-suffix :显示用于查找标题的 sysroot 后缀。
  • -Wa, :将逗号分隔的  传递给汇编器(assembler)。
  • -Wp, :将逗号分隔的  传递给预处理器(preprocessor)。
  • -Wl, :将逗号分隔的  传递给链接器(linker)。
  • -Xassembler  :将  传递给汇编器(assembler)。
  • -Xpreprocessor  :将  传递给预处理器(preprocessor)。
  • -Xlinker  :将  传递给链接器(linker)。
  • -save-temps :不用删除中间文件。
  • -save-temps= :不用删除指定的中间文件。
  • -no-canonical-prefixes :在构建其他 gcc 组件的相对前缀时,不要规范化路径
  • -pipe :使用管道而不是中间文件。
  • -time :为每个子流程的执行计时。
  • -specs= :使用  的内容覆盖内置规范。
  • -std= :假设输入源为 。
  • --sysroot= :使用  作为头文件和库的根目录。
  • -B  :将  添加到编译器的搜索路径。
  • -v :显示编译器调用的程序。
  • -E :仅执行预处理(不要编译、汇编或链接)。
  • -S :只编译(不汇编或链接)。
  • -c :编译和汇编,但不链接。
  • -o  :指定输出文件
  • -pie :创建一个动态链接、位置无关的可执行文件。
  • -I :指定头文件的包含路径
  • -L :指定链接库的包含路径。
  • -shared :创建共享库/动态库。
  • -static :使用静态链接。

使用

示例代码

#include <stdio.h>
void foo(void);
int main(void)
{
    printf("Hello, GetIoT\n");
    foo();
    return 0;
}
  • gcc 默认输出a.out
gcc hello.c

  • 指定输出 文件
gcc hello.c -o hello
  • 只执行预处理,输出hello.i的源文件
gcc -E hello.c -o hello.i
  • 执行性预处理和编译,输出hello.s汇编文件
gcc -S hello.c #或者 gcc -S hello.i -o hello.s
  • 只执行预处理,编译,汇编,输出hello.o目标文件
gcc -c hello.c #或者 gcc -c hello.i 或者 gcc -c hello.s
  • 由hello.o -o hello 链接成可只执行文件
gcc hello.o -o hello
  • 使用静态库
    1. 分别创建staticFoo.c和shardFoo.c
      #include <stdio.h>
      
      void foo(void)
      {
          printf("Here is a static library\n");
      }
      #include <stdio.h>
      
      void foo(void)
      {
          printf("Here is a shard library\n");
      }

    2. 分别创建静态库和动态库
      #创建静态库
       gcc -c staticFoo.c -o staticFoo.o
       ar rcs libfoo.a staticFoo.o #ar命令将目标文件打包成一个名为libname.a的静态库文件
      #创建动态库
      gcc -fPIC -c shardFoo.c #-fPIC选项用于生成位置独立代码,这是创建动态库所需的。
      gcc -shard -o libfoo.so shardFoo.o
         

    3. 将静态库和动态库分别链接到hello.c
      
      # 动态库链接
       gcc hello.c  libfoo.so -o shardFoo
      export LD_LIBRARY_PATH=/usr/lib64/
      #或者
       gcc hello.c -L. -lfoo -Wl,-rpath=`pwd` -o hello2
      rpath 即 run path,是种可以将共享库位置嵌入程序中的方法,从而不用依赖于默认位置和环境变量。这里在链接时使用 
      -Wl,-rpath=/path/to/yours 选项,-Wl 会发送以逗号分隔的选项到链接器
      #或者
      sudo cp libfoo.so /usr/lib/ #将llbfoo共享库添加到系统路径

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到