zoukankan      html  css  js  c++  java
  • GCC编译

    一、GCC编译选项解析

    1. 常用的编译选项

    命令格式: gcc [选项] [文件名]

      -E:仅执行编译预处理;

      -S:将C代码转换为汇编代码;

      -c:仅执行编译操作,不进行连接操作;  

      -o:指定生成的输出文件。

    2. gcc编译的四个阶段

      1) 将hello.c预处理输出hello.i文件

            gcc -E hello.c -o hello.i

      2) 将预处理输出文件hello.i汇编成hello.s文件

      gcc -S hello.i -o hello.s

      3) 将汇编输出文件hello.s编译输出hello.o文件

      gcc -c hello.s -o hello.o

      4) 将编译输出文件hello.o链接成最终可执行文件hello

          gcc hello.o -o hello

          或直接输入下面的代码,一步到位:

          gcc hello.c -o hello

          当有多个文件需要一起编译时,可输入

         gcc *.c -o hello

    二、多模块、多个文件一起编译

    1. 两种编译方式

    1)一起编译

        gcc test_a.c test_b.c -o test

    2)分别编译各个源文件,之后对编译后输出的目标文件链接

      gcc -c test_a.c   //生成test_a.o

      gcc -c test_b.c  //生成test_b.o

      gcc -o test_a.o test_b.o -o test

    比较:第一种方法编译时需要所有文件重新编译;第二种只需要编译修改的文件,未修改的不用重新编译;

    一个实例:-I参数的使用

    使用vim编辑生成相应代码,注意:.h文件应放入include中, .c文件应放入src中;

    编译指令:gcc -I/头文件所在路径  *.c  -o main  将执行文件命名为main

    -I参数可以用相对路径,比如头文件在当前目录,可以用-I.来指定

    三、静态库与动态库

    1. 静态库

      这类库的名字一般是libxxx.a;利用静态函数库编译成的文件比较大,因为整个 函数库的所有数据都会被整合进目标代码中,他的优点就显而易见了,即编译后的执行程序不需要外部的函数库支持,因为所有使用的函数都已经被编译进去了。当然这也会成为他的缺点,因为如果静态函数库改变了,那么你的程序必须重新编译。

    注:windows下静态库文件:*.lib

          linux下动态库文件:liib*.a

    2. 动态函数库

      这类库的名字一般是libxxx.so;相对于静态函数库,动态函数库在编译的时候 并没有被编译进目标代码中,你的程序执行到相关函数时才调用该函数库里的相应函数,因此动态函数库所产生的可执行文件比较小。由于函数库没有被整合进你的程序,而是程序运行时动态的申请并调用,所以程序的运行环境中必须提供相应的库。动态函数库的改变并不影响你的程序,所以动态函数库的升级比较方便。

    注:windows下动态库文件:*.dll

          linux下动态库文件:liib*.so

    例子:

      在上一个实例中有五个.c文件,除了main.c外,其他4个模块(add.c sub.c mul.c div.c)的源代码不想给别人,如何制作成一个静态库libmath.a和一个共享库libmath.so,制作完成后如何调用?

    我们先来看看静态库libmath.a的制作:

    1) 输入 gcc -c -I/头文件所在路径 add.c sub.c mul.c div.c生成四个 .o文件

    2)   输入 ar rcvs libmath.a add.o sub.o mul.o div.o 生成静态库;

    3) 如果之前已经生成了main,我们可以输入 rm main来删掉它,ls一下可以看到没有执行文件了。在输入 gcc main.c -o main -I/头文件所在路径 -L. -lmath,可以看到生成了可执行文件main,输入./main就可以实现调用金泰库来执行文件了;

      这里要注意,gcc会在静态库名前加上前缀lib,然后追加扩展名.a得到的静态库文件名来查找静态库文件。那么为什么要在math之前加-l呢?这是因为-l参数就是用来指定程序要链接的库,-l参数紧接着就是库名。而-L参数跟着的是库文件所在的目录名。题中的库文件在当前目录,故写为-L.

    我们再来看看动态库libmath.so的制作:

    1.输入gcc -fPIC -c -I/头文件所在路径 add.c sub.c mul.c div.c;

    2.输入gcc -shared -o libmath.so add.o sub.o mul.o div.o生成动态库。

    3.我们来输入gcc -I/头文件所在路径 -o main main.c -L. -lmath后执行一下main试一试,会发现出现下图的错误。

      这是为什么呢?原来是找不到动态库文件libmath.so。程序在运行时,会在/usr/lib和/lib等目录中查找需要的动态库文件。若找到,则载入动态库,否则将提示类似上述错误而终止程序运行。我们将文件libmath.so复制到目录/usr/lib中,再试试就可以执行啦!

    四、查看帮助文档

    通过man gcc查看关于gcc的帮助文档

    参考:https://www.cnblogs.com/roverliang/p/11493452.html

  • 相关阅读:
    java_oop_方法2
    POJ 3276 Face The Right Way(反转)
    POJ 3276 Face The Right Way(反转)
    POJ 2566 Bound Found(尺取法,前缀和)
    POJ 2566 Bound Found(尺取法,前缀和)
    POJ 3320 Jessica's Reading Problem(尺取法)
    POJ 3320 Jessica's Reading Problem(尺取法)
    POJ 3061 Subsequence(尺取法)
    POJ 3061 Subsequence(尺取法)
    HDU 1222 Wolf and Rabbit(欧几里得)
  • 原文地址:https://www.cnblogs.com/zhaopengpeng/p/12371924.html
Copyright © 2011-2022 走看看