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 = ./lib
SRCDIR = ./src
VPATH = $(SRCDIR)
PROJ = iccp
OPT =
DEFS =
LIST = >> cc.lst 2>&1
CC = gcc
LIBRARY = $(LIBDIR)/$(PROJ).so
OBJECTS = $(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
注意在上面的代码中需要将
$(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