将静态库编译到动态库中

     最近做一个东西,需要采集硬件设备的音视频数据,然后做编码。以前做过编码部分直接拽过来使用,只写硬件采集部分即可。  调查发现,硬件采集驱动过于老旧,必须使用ffmpeg3的API,而编码部分则使用了ffmpeg4。

     改动编码部分降级为ffmpeg3不现实,引出来多少问题不太确定。由此设计一套方案:

  1. 编码部分使用ffmpeg4的动态库,链接位置自己指定
  2. 将硬件采集代码设计为动态库,并且将ffmpeg3的静态编译进去
  3. 由主体程序动态链接调用硬件采集代

     静态库被编译到动态库中,相当于内部代码,与其他部分不冲突。注意不要暴露任何关于ffmpeg3到内容,否则可能引起歧义。

将以上过程抽象为如下:

static.cpp static.h   --> libffmpeg3.a

capture.cpp capture.h  --> libcap_dev.so

test.cpp --> test (最终可执行程序)

1. 编译生成静态库

g++ -c -fPIC static.cpp -o static.o

-fPIC是必须要添加,目的是生成与位置无关的代码

ar -r libffmpeg3.a static.o

记得调试一下库是否OK。

 

2. 编译生成动态库,注意需要将静态库编译进去

g++ -c -fPIC capture.cpp -o capture.o

这里需要生成动态库,就更需要-fPIC选项了。

g++ -shared capture.o -L. -lffmpeg3 -o libcap_dev.so

编译时注意使用-L -l指定和链接目标静态库,-L和-l的作用及用法请自行查询。

至此libffmpeg3.a已经被编译到libcap_dev.so中,查看一下文件大小,会发现动态库会比较大。如果链接的是ffmpeg的静态库的话,会更大,几十兆都是不是事儿。

 

3. 编译生成最终目标

g++ test.cpp -I./ -L./ -lcap_dev -o test

同理需要用到-L和-l。

运行目标文件,正常使用两个库中的接口。

 

使用方法及注意事项测试完成,下面是将其用于实战。

首先,针对第一点,需要有ffmpeg3的静态库,下载编译,注意一定要是3版本的。编译是需要添加-fPIC选项。在configure时添加如下参数:

--extra-cflags='-fPIC' --extra-cxxflags='-fPIC' --enable-static

至此生成一堆ffmpeg相关的静态库,正好对应libffmpeg3.a。

其次,针对第二点,头文件中要规避开ffmpeg的头文件,实在避不开的转化一下或者自定义也行。

最后贴出生成动态库的Makefile文件。

CC	:= gcc
C++	:= g++
LINK := g++

# ffmpeg
FFMPEG_PATH :=  /usr/local/ffmpeg/3.0

# xxx driver
XXX_PATH := /usr/local/xxx_driver/include/

LIBS :=	-L$(FFMPEG_PATH)/lib \
		-Wl,-Bstatic -Wl,-Bsymbolic\
		-lavdevice -lavfilter -lpostproc \
		-lavformat -lavcodec -lavutil \
		-lswscale -lswresample \
		-Wl,-Bdynamic -lstdc++ -ldl -lstdc++ -ldl -lm -lz -lpthread \


C++FLAGS :=	-g -Wall -fPIC -std=c++11 \
			-D__STDC_CONSTANT_MACROS \


INCLUDES :=	-I$(FFMPEG_PATH)/include/ \
			-I$(XXX_PATH) \


C++FILES :=	dev_cap.cpp \


TARGET=libdev_cap.so
OBJS = $(C++FILES:.cpp=.o)


all: $(TARGET)

$(TARGET):$(OBJS)
	$(LINK) -shared $^ $(LIBS) -o $@


%.o:%.cpp  
	$(C++) -c $(C++FLAGS) $< $(INCLUDES) -o $@

clean:
	rm -f $(TARGET) $(OBJS)

在链接ffmpeg库时遇到了如下错误:

/usr/bin/ld: /usr/local/media_http_server/ffmpeg/3.0/lib/libavcodec.a(vc1dsp_mmx.o): relocation R_X86_64_PC32 against symbol `ff_pw_9' can not be used when making a shared object; recompile with -fPIC
/usr/bin/ld: final link failed: Bad value
collect2: error: ld returned 1 exit status
make: *** [libsdi.so] Error 1

网上好多人也遇到了同样问题,需要在链接ffmpeg库是添加“-Wl,-Bsymbolic”选项。

测试一下,正常使用,可惜涉及到库代码调试起来比较费劲,美中不足。

编译时这样那样到参数问题磕巴了好久,以此记录一下。

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值