Linux编译静态库和动态库的方法

来源:互联网 发布:前端wap 淘宝页面模板 编辑:程序博客网 时间:2024/06/06 04:29

1、Linux编译相关

1.1 编译

  • 编译单个源文件 
    例如:main.c 
    gcc main.c -o main 
    ./main

  • 编译多个源文件 
    例如:hello.h hello.c main.c 
    gcc mian.c hello.c -o hello 
    ./hello

gcc main.c -o main -v “加-v可以查看头文件以及库文件的搜索路径及具体的编译参数”

1.2 ar打包

将几个.c文件编译过后,常常可能需要用到打包指令,例如gcc -c main.c -o main.o编译后,需要将main.o打包,则需要采用ar指令,如ar -q mian.sa main.o

1.3将静态库编译成动态库

1.3.1 方法1:

ar -x xxx.a 
gcc -m32 -fPic -shared *.o -o xxx.so #针对linux32位库,如果是64位库,则将-m32改成-m64

参考:http://blog.csdn.net/yuanbinquan/article/details/45536131

1.3.2 方法2:

LIBDIR = ./libSRCDIR = ./srcVPATH  = $(SRCDIR)PROJ  = iccpOPT   =DEFS  =LIST  = >> cc.lst 2>&1CC = gccLIBRARY = $(LIBDIR)/$(PROJ).soOBJECTS = $(LIBDIR)/mem.a \          $(LIBDIR)/slog.a      all: $(LIBRARY)$(LIBRARY): $(OBJECTS)        rm -f $(LIBRARY)        $(CC) -shared -fPIC $(OBJECTS) -Wl,-soname -Wl,$@ -o $@ -lc $(LIST)        @echo "FINISHED CREATING $(LIBRARY) LIBRARY" $(LIST)        @echo "-----------------------------------------------------" $(LIST)$(LIBDIR)/mem.a:         $(MAKE) $(AM_MAKEFLAGS) -f mem.mk$(LIBDIR)/slog.a:         $(MAKE) $(AM_MAKEFLAGS) -f slog.mk
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

注意在上面的代码中需要将 
$(CC) -shared -fPIC $(OBJECTS) -Wl,-soname -Wl,$@ -o $
改成: 
$(CC) -shared -fPIC -Wl,–whole-archive $(OBJECTS) -Wl,–no-whole-archive -Wl,-soname -Wl, $@ -o $
即可

  • 相关知识点 
       
     1) 当使用–whole-archive时,其会把所有的–whole-archive之后的.sa中的所有函数全部加入到生成的文件中来,这样的情况下,如果有同名函数,则链接就不会通过; 
      
     2) 当使用–no-whole-archieve时,则此后的所有文件中的所有函数都不会加到生成的文件中,但下面的第3点情况例外; 
      
     3) 如果命令行中有.o文件,如test.o, 并且.o文件后面有.sa文件,则会把.o文件中用到的函数的.sa文件加入到生成的结果文件中来(即使.sa前有–no-whole-archieve);所以这和.o及.sa的顺序有关系。

     4) -Wl选项告诉编译器将后面的参数传递给链接器。 
      -soname则指定了动态库的soname(简单共享名,Short for shared object name)。实际上,每一个库都有一个soname,当连接器发现它正 在查找的程序库中有这样一个名称,连接器便会将soname嵌入连结中的二进制文件内,而不是它正在运行的实际文件名,在程序执行期间,程序会查找拥有 soname名字的文件,而不是库的文件名,换句话说,soname是库的区分标志。

参考:http://blog.csdn.net/liufang200706/article/details/54410272

0 0