4种方式的模块编译方法

C语言模块编译方法:


================== 1、一般方式开始 ===============
(1)创建文件fred.c
[root@localhost 1]# vi fred.c
#include <stdio.h>

void fred(int arg){

        printf("fred: we passed %d n",arg);

}

(2)创建文件bill.c
[root@localhost 1]# vi bill.c
#include <stdio.h>

void bill(char *arg){

        printf("bill: we passed %s n",arg);

}

(3)创建头文件lib.h
[root@localhost 1]# vi lib.h
void bill(char *);
void fred(int);

(4)创建主文件program.c
[root@localhost 1]# vi program.c
#include <stdio.h>
#include "lib.h"   //在主函数里面包含头文件,就可以调用该头文件里面的函数了。
                   //另外也可以不需要此头文件,在mian()函数所在文件中,对这两个函数
                   //进行外部函数声明,如加入extern void bill(char *);
                   //                       extern void fred(int);

int main(){

        bill("Hello Word");
        exit(0);
}

(5)编译生成目标文件
[root@localhost 1]# gcc -c bill.c fred.c program.c
[root@localhost 1]# ls -al *.o   //查看生成的目标文件
-rw-r--r--  1 root root 864 Aug  9 15:19 bill.o
-rw-r--r--  1 root root 864 Aug  9 15:19 fred.o
-rw-r--r--  1 root root 916 Aug  9 15:19 program.o

(6)生成main的可执行文件,并运行该文件
[root@localhost 1]# gcc -o program program.o bill.o
[root@localhost 1]# ls -al program  //查看生成的可执行文件
-rwxr-xr-x  1 root root 4949 Aug  9 15:21 program
[root@localhost 1]# ./program  //运行该可执行文件
bill: we passed Hello Word
================== 1、一般方式结束 ===============

================== 2、静态库方式开始 ===============
(1)创建文件fred.c
[root@localhost 1]# vi fred.c
#include <stdio.h>

void fred(int arg){

        printf("fred: we passed %d n",arg);

}

(2)创建文件bill.c
[root@localhost 1]# vi bill.c
#include <stdio.h>

void bill(char *arg){

        printf("bill: we passed %s n",arg);

}

(3)创建头文件lib.h
[root@localhost 1]# vi lib.h
void bill(char *);
void fred(int);

(4)创建主文件program.c
[root@localhost 1]# vi program.c
#include <stdio.h>
#include "lib.h"

int main(){

        bill("Hello Word");
        exit(0);
}

(5)编译生成目标文件
[root@localhost 1]# gcc -c bill.c fred.c program.c
[root@localhost 1]# ls -al *.o   //查看生成的目标文件
-rw-r--r--  1 root root 864 Aug  9 15:19 bill.o
-rw-r--r--  1 root root 864 Aug  9 15:19 fred.o
-rw-r--r--  1 root root 916 Aug  9 15:19 program.o

(6)创建你的静态库,并加入目标文件,之后为此静态库生成一个内容表
[root@localhost 1]# ar crv libtry.a bill.o fred.o  //生成的静态库名字是libtry.a,ar是创建、修改库的命令,该库加入了bill.o fred.o两个目标文件
a - bill.o
a - fred.o
[root@localhost 1]# ranlib libtry.a //现在你的静态库可以使用了

(7)生成main的可执行文件,并运行该文件
生成可执行文件方式一:
[root@localhost 1]# gcc -o program program.o libtry.a
生成可执行文件方式二:
[root@localhost 1]# gcc -o program program.o  -ltry  //-ltry是告诉编译器使用libtry.a的静态库
/usr/bin/ld: cannot find -ltry  //出错了,因为编译器在指定的路径并没有找到该静态库
collect2: ld returned 1 exit status
[root@localhost 1]# gcc -o program program.o -L. -ltry  //所以用-L. 指明在当前路径下搜索
[root@localhost 1]# ./program //运行该可执行文件
bill: we passed Hello Word
================== 2、静态库方式结束 ===============

================== 3、动态库方式开始 ===============
(1)创建文件fred.c
[root@localhost 1]# vi fred.c
#include <stdio.h>

void fred(int arg){

        printf("fred: we passed %d n",arg);

}

(2)创建文件bill.c
[root@localhost 1]# vi bill.c
#include <stdio.h>

void bill(char *arg){

        printf("bill: we passed %s n",arg);

}

(3)创建头文件lib.h
[root@localhost 1]# vi lib.h
void bill(char *);
void fred(int);

(4)创建主文件program.c
[root@localhost 1]# vi program.c
#include <stdio.h>
#include "lib.h"

int main(){

        bill("Hello Word");
        exit(0);
}

(5)编译生成目标文件
[root@localhost 1]# gcc -fPIC -c bill.c fred.c program.c  //-fPIC生成的目标文件可以用于创建共享库
[root@localhost 1]# ls -al *.o
-rw-r--r--  1 root root 932 Aug  9 16:13 bill.o
-rw-r--r--  1 root root 932 Aug  9 16:13 fred.o
-rw-r--r--  1 root root 976 Aug  9 16:13 program.o

(6)创建你的共享库,并加入目标文件
[root@localhost 1]# gcc -shared -o libtry.so bill.o fred.o //共享库的名称是libtry.so,该库加入了bill.o fred.o两个目标文件
[root@localhost 1]# ls -al *.so
-rwxr-xr-x  1 root root 4582 Aug  9 16:17 libtry.so

(7)生成main的可执行文件,并运行该文件
生成可执行文件方式一:
[root@localhost 1]# gcc -o program -L. libtry.so program.o
生成可执行文件方式二:
[root@localhost 1]# gcc -o program program.o  -ltry  //-ltry是告诉编译器使用libtry.a的静态库
/usr/bin/ld: cannot find -ltry  //出错了,因为编译器在指定的路径并没有找到该静态库
collect2: ld returned 1 exit status
[root@localhost 1]# gcc -o program program.o -L. -ltry  //所以用-L. 指明在当前路径下搜索
[root@localhost 1]# ./program //运行该可执行文件
bill: we passed Hello Word

(8)可能存在的问题
[root@localhost 1]# ./program
./program
  ./program: error while loading shared libraries: libtry.so: cannot open shared object file: No such file or directory
[root@localhost 1]# ldd program  //用ldd工具查看运行program需要用到的共享库
  libtry.so => not found      //这里程序并没有找到你的这个libtry.so共享库
  libc.so.6 => /lib/tls/libc.so.6 (0x003d5000)
  /lib/ld-linux.so.2 (0x003bb000)
[root@localhost 1]# export LD_LIBRARY_PATH=`pwd`  //注意这里是反引号,通过设置环境变量告诉共享库libtry.so的搜索路径
[root@localhost 1]# echo $LD_LIBRARY_PATH   //显示该路径
/root/Desktop/Linux_book/1
[root@localhost 1]# ldd program  //再次查看该program所需要的共享库是否已经全部找到
    libtry.so => /root/Desktop/Linux_book/1/libtry.so (0x00d68000)
    libc.so.6 => /lib/tls/libc.so.6 (0x003d5000)
    /lib/ld-linux.so.2 (0x003bb000)
[root@localhost 1]# ./program  //运行之后,结果正确
bill: we passed Hello Word
================== 3、动态库方式结束 ===============

================== 4、makefile方式开始 ===============
(1)创建文件fred.c
[root@localhost 1]# vi fred.c
#include <stdio.h>

void fred(int arg){

        printf("fred: we passed %d n",arg);

}

(2)创建文件bill.c
[root@localhost 1]# vi bill.c
#include <stdio.h>

void bill(char *arg){

        printf("bill: we passed %s n",arg);

}

(3)创建头文件lib.h
[root@localhost 1]# vi lib.h
void bill(char *);
void fred(int);

(4)创建主文件program.c
[root@localhost 1]# vi program.c
#include <stdio.h>
#include "lib.h"

int main(){

        bill("Hello Word");
        exit(0);
}

(5)编写makefile文件,用于完成模块编译
[root@localhost 1]# vi makefile
all:    program

INCLUDE=.  #头文件目录为当前目录,因为用户的lib.h存放在当前目录

bill.o: bill.c
        gcc -c bill.c  #生成bill.o目标文件

fred.o: fred.c
        gcc -c fred.c  #生成fred.o目标文件

program.o: program.c lib.h
        gcc -c -I$(INCLUDE) program.c  #生成program.o目标文件

program: bill.o program.o
        gcc -o program bill.o program.o #生成program可执行文件,该可执行文件由bill.o和program.o两个目标文件及所需要的库文件连接而成

clean:       #clean的动作,删除*.o文件 以及program可执行文件
        rm -rf program *.o

(6)运行编译好的makefile文件,检验最终结果
[root@localhost 1]# make  //makefile文件通过make命令起作用
gcc -c bill.c
gcc -c -I. program.c
gcc -o program bill.o program.o
[root@localhost 1]# ls -al *.o program //显示编译过程
-rw-r--r--  1 root root  864 Aug  9 16:42 bill.o
-rwxr-xr-x  1 root root 4949 Aug  9 16:42 program
-rw-r--r--  1 root root  916 Aug  9 16:42 program.o
[root@localhost 1]# ./program //运行结果正确
bill: we passed Hello Word
[root@localhost 1]# make clean //clean的动作
rm -rf program *.o
[root@localhost 1]# ls -al *.o program  //查看删除结果
ls: *.o: No such file or directory
ls: program: No such file or directory

================== 4、makefile方式结束 ===============

本文由365bet体育在线投注网址发布于365bet体育在线投注网址,转载请注明出处:4种方式的模块编译方法

您可能还会对下面的文章感兴趣: