makefile 编写,编译动态库,编译静态库

1 我平时写的makefile分享

CROSS_COMPILE=
CC = $(CROSS_COMPILE)gcc
STRIP = $(CROSS_COMPILE)strip
CFLAG = -Wall -W -Os -g -o

LIBS := -L../lib -lfcgi 
LIBS += -L../lib -ltinyxml   
LIBS += -L../lib -lOnvif -lpthread
LIBS += -L. -lstdc++  

INCLUDE = -I ./ -I ../include -I../include/fcgi -I../include/Ctinyxml2

out-dir = /var/lighttpd/www

TARGET = MAINONVIF.fastcgi


UserInterface := UserInterface
COMM_SRC := $(wildcard *.c) $(wildcard $(UserInterface)/*.c)
COMM_OBJ := $(COMM_SRC:%.c=%.o)

.PHONY : all install clean

all: $(COMM_OBJ)
    $(CC) $^ -o $(TARGET) $(LIBS)  $(INCLUDE)
    @$(STRIP) --strip-unneeded $(TARGET)

$(COMM_OBJ):%.o:%.c
    $(CC) -c $< $(CFLAG) $@ $(LIBS)  $(INCLUDE)

install:
    rm -rf $(out-dir)/MAINONVIF.fastcgi 
    cp -rf MAINONVIF.fastcgi $(out-dir)

clean:
    rm -rf $(COMM_OBJ) 

解析:
@$(STRIP) 是使用 strip  对编译出来的程序裁剪,裁剪掉程序运行时用不到的段,减少体积。@ 是makefile的规则,是取消回显
$(COMM_OBJ):%.o:%.c  是makefile的静态模式,编译多个类似的目标很方便


2 makefile 中编译动态库

需要加上 -fPIC -shared 参数来编译动态库
TARGET = libOnvif.so
all: $(COMM_OBJ)
$(CC) $^ -fPIC -shared -o $(TARGET) $(LIBS) $(INCLUDE)


动态库导出表
一个功能决定编译成动态库,也不一定要把所有的函数都暴露出去,可以只暴露有限的接口。暴露的接口可以使用导出表控制。

详情请参考 <> 这本书。下面是一个例子




CFLAG = -Wall -W -fPIC -DWITH_FASTCGI -Os -o
STRIP = $(CROSS_COMPILE)strip
# -Wl,--version-script=./Interface.map  是要暴露的动态库接口
all: $(OBJ)
    $(CC) -shared $(CFLAG) $(TARGET) $(OBJ) $(LIBS)  -Wl,--version-script=./Interface.map
    @$(STRIP) --strip-unneeded $(TARGET)

Interface.map 文件可以这样写:

{
    global:
    OnvifgSoapPthreads;
    OnvifVideoSourceMotionAlarmEventHasCome;
    OnvifVideoSourceSignalLossEventHasCome;
    OnvifAudioSignalLossEventHasCome;
    OnvifRelayEventHasCome;
    OnvifPTZPresetsEventHasCome;
    local: *;
};

其中 global:声明的是要导出的动态库接口,local: 是不导出的函数

3 makefile 编译静态库

编译静态库实际上就是把 .o 文件打包,打包使用的指令是  ar

静态库是不能使用  strip 进行裁剪的。参考如下makefile片段,不难写出编译静态库的makefile

AR := ar crv
RANLIB := ranlib -t
all: $(OBJ)
    $(AR) $(TARGET) $(OBJ)
    $(RANLIB) $(TARGET)

makefile 编译静态库容易出错的是,静态库(比如 libA1.a)中引用了另外的静态库(比如 libA2.a),应用程序使用了libA1.a
那么makefile中的静态库的书写顺序一定要为
LIBS := -L./ -lA1 -L ./ -lA2


LIBS := -L./ -lA1 -L ./ -lA2
all: $(OBJ)
    $(CC) $(CFLAG) $(TARGET) $(OBJ) $(LIBS) $(INCLUDE)
    @$(STRIP) --strip-unneeded $(TARGET)



你可能感兴趣的:(linux,使用)