首页 > 代码库 > 简单程序的编译链接三种方法(编译多个源文件,静态链接库、动态链接库)

简单程序的编译链接三种方法(编译多个源文件,静态链接库、动态链接库)

一个程序简单的程序如下:

1 hello.h

#ifndef HELLO_H
#define HELLO_H

void hello(const char *name);

#endif 

 

2 hello.c

#include <stdio.h>
#include <stdlib.h>

void hello(const char *name)
{
printf("hello %s\n",name);
}

 

3 main.c

#include <stdio.h>
#include <stdlib.h>

void hello(const char *name)
{
printf("hello %s\n",name);
}

 

方法一:对每个源文件进行编译生成目标文件,再有目标文件生成可执行的文件:

  第一步:gcc -c hello.c

      gcc -c main.c

      这时生成了.o的目标文件,ls可以看到hello.o main.o

  第二步:gcc -o jia hello.o main.o

      此时生成可执行文件jia

 

  执行:./jia

      显示:hello jiayudong

 

方法二:通过静态链接库

  先生成静态链接库:(静态链接库和动态链接库都是有目标文件组成,所以先要生成目标文件)

   第一步:把hello函数生成为静态链接库:

        gcc -c hello.c                                    //生成hello.o的目标文件

        ar rcs libmyhello.a hello.o               //生成libmyhello.a的静态链接库

     第二步:通过静态链接库生成可执行的文件

        gcc -o jia main.c -static -L. -lmyhello   //生成可执行的文件jia

 

注意:   1)创建静态链接库的命令是ar,参数是rcs,静态库的命名都是以lib+库名+.a

    2)当链接静态库时,需要的命令参数是 -static -L. -l库名 ,gcc在链接时,会在静态库前面追加lib,在库名后面追加.a,然后去找对应的静态

      链接库,所以在gcc命令中,只写库名myhello。如若需要链接libmyhello.a,则只需要写-lmyhello。

    3)静态链接库在编译链接完成后,若删除,已经编译链接好的文件是不受影响的。因而在链接的时候,库文件的函数已经被链接到执行文件中了。

      比如:删除静态库:libmyhello.a    rm libmyhello.a

            再次执行./jia   显示:hello jiayudong!

 

方法三:通过动态链接库链接

    第一步:生成动态链接库:

        gcc -c hello.c                //生成目标文件hello.o

        gcc -shared -fPIC -o libmyhello.so hello.o     //生成动态链接库 libmyhello.so

 

    第二步:链接动态库生成执行文件:

        gcc -o jia main.c -L. -lmyhello                //生成jia

 

                 执行jia:./jia   出现错误提示:  

        ./jia: error while loading shared libraries: libmyhello.so: cannot open shared object file: No such file or directory

      错误提示为:找不到动态链接库。原因是程序在运行时,才会去链接动态链接库(静态链接库在生成程序时,就已经调用),而动态链接库  

            若不在gcc中明确指定,默认会到/usr/lib或者/lib中去寻找。

      解决方案一:把libmyhello.so拷比到/usr/lib或者/lib下

      解决方案二:在LD_LIBRARY_PATH路径中加入libmyhello.so所在的路径。若在libmyhello.so的当前目录下,则export LD_LIBRARY_PATH=$(pwd);  

            若不在当前目录下:export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/jiayudong/programme/pratice

      解决方案三:在root权限下,执行ldcongfig 目录名

            该命令的意思是:让该目录下的动态链接库被系统共享。实质是:在缓存文件/etc/ld.so.cache中追加进指定目录下的共享库,并重建

            /etc/ld.so.cache文件。

 

      注意:当删除动态链接库时,程序是不能运行的。