gcc编译

本文深入探讨了gcc编译过程,包括预处理、编译、汇编和链接阶段,并详细解释了如何通过静态链接库和动态链接库进行程序的链接。同时,文章还演示了处理多个文件的方法,并对比了静态链接与动态链接的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

查看帮助一是man gcc,二是进入www.gnu.org,找到gcc的帮助文档(更详细)。

一、gcc编译过程
        hello.c源代码                      经过预处理(Pre-Processing),形成
        hello.i预编译文件,            经过编译(Compiling),形成
        hello.s汇编文件,               经过汇编(Assembling),形成
        hello.o目标文件(二进制)经过链接(Linking),形成

        hello可执行文件 

          

二、gcc编译命令
        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  

        gcc -Wall  hello.o  -o   hello 能够提示出更多的错误

        
三、处理以下三个文件的三种方式

        hello.c中的代码如下:

#include <stdio.h>
void hello()
{
        printf("Congratulation gcy\n");
}
        hello.h中的代码如下:

void hello();
  main.c中的代码如下:
#include <stdio.h>
#include <hello.h>
int main()
{
        printf("call hello()\n");
        hello();
        printf("\n");
        return 0;
}
        1、使用静态链接库(*.a)
         gcc   -c   hello.c   -o   libhello.o

         ar   crv   libhello.a   libhello.o     生成静态链接库

         gcc -c main.c -o main.o  -I./ 

         gcc   -static   main.o   -o   main   -L./   libhello.a    头文件和静态库都是在当前目录下

         ./main  执行不需要依赖其他文件,输出结果为call hello() Congratulation gcy。


         2、使用动态链接库(.so
         gcc   -fPIC   -c   hello.c   -o   libhello.o   

         gcc   -shared   libhello.o   -o   libhello.so    生成动态链接库

         gcc -c main.c -o main.o  -I./

         gcc   main.o  -o   main2   -L./   libhello.so    头文件和静态库都是在当前目录下
         ./main2  执行需要依赖/usr/lib中的libhello.so,故显示出错。改错办法:

         把libhello.so放到/usr/lib中,或者用下面的办法,

         ls /etc/*conf,vi ld.so.conf,显示内容,include /etc/ld.so.conf.d/*.conf,cd /etc/ld.so.conf.d/,vi libc.conf,再这里面增加路径。


         ldd main,可以查看所有的库,如果加上static ,ldd main,目标程序没有链接动态库,则打印“not a dynamic executable”
        linux-gate.so.1 =>  (0xb7716000)
        libhello.so => /usr/lib/libhello.so (0xb7701000)
        libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb755c000)

        /lib/ld-linux.so.2 (0xb7717000)


        3、编译多个文件

        gcc   -c  hello.c   -o   hello.o

        gcc   -c  main.c   -o   main.o

        gcc   main.o   hello.o   -o   main

        或者 gcc main.c hello.c -o main (此时不需要包含头文件)

        ./main ,输出结果为call hello() Congratulation gcy。


四、动态链接与静态链接
#include <stdio.h>
int main()
{
        printf("hello\n");
        return 0;
}
       stdio.h位于/usr/include/中,里面有printf的声明extern int printf (__const char *__restrict __format, ...);此处extern可以省略不写。

       静态链接:gcc  -static  main.c  -o  main 

       预处理时会到/usr/include下找到stdio.h,链接时到/usr/lib下找printf对应的静态库,执行之后不再需要依赖其他静态库,故文件较大。

      动态链接:gcc  main.c  -o  main2 

      预处理时会到/usr/include下找stdio.h,链接时到/usr/lib下找printf对应的动态库,执行之后,要依赖/usr/lib中的动态库,故文件较小。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值