Link against local/custom static library

Hi, I’m trying to experiment with a custom built of libav. libav is statically built and libraries files are in several inner directories of libav/

I’ve this directory structure :
myApps/libavTest
myApps/libav (just a temporary location of the libav directory, for experimentation)

I’ve modified config.make as (of is a symlink to of_v0.9.8_linuxarmv6l_release)

PROJECT_LDFLAGS += -L /home/pi/of/apps/myApps/libav/libavcodec/libavcodec.a -L /home/pi/of/apps/myApps/libav/libavformat/libavformat.a -L /home/pi/of/apps/myApps/libav/libavavutil/libavutil.a

But I get a bunch of undefined references at link stage, and surprisingly some concerning ofTessellator (which I don’t use in my code)

What is the right solution to link against custom static libraries ?

Console dump follows

make[1]: Entering directory '/home/pi/of_v0.9.8_linuxarmv6l_release/apps/myApps/libavTest'
HOST_OS=Linux
checking pkg-config libraries:   cairo zlib gstreamer-app-1.0 gstreamer-1.0 gstreamer-video-1.0 gstreamer-base-1.0 libudev freetype2 fontconfig sndfile openal openssl gtk+-3.0 libmpg123
Linking bin/libavTest for linuxarmv6l
g++ -o bin/libavTest  obj/linuxarmv6l/Release/src/ofApp.o obj/linuxarmv6l/Release/src/encoder.o obj/linuxarmv6l/Release/src/main.o /home/pi/of_v0.9.8_linuxarmv6l_release/addons/obj/linuxarmv6l/Release/ofxNetwork/src/ofxTCPManager.o /home/pi/of_v0.9.8_linuxarmv6l_release/addons/obj/linuxarmv6l/Release/ofxNetwork/src/ofxUDPManager.o /home/pi/of_v0.9.8_linuxarmv6l_release/addons/obj/linuxarmv6l/Release/ofxNetwork/src/ofxTCPClient.o /home/pi/of_v0.9.8_linuxarmv6l_release/addons/obj/linuxarmv6l/Release/ofxNetwork/src/ofxTCPServer.o /home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a   -Wl,-rpath=./libs:./bin/libs -Wl,--as-needed -Wl,--gc-sections -pthread -L ./libavcodec.a -L /home/pi/of_v0.9.8_linuxarmv6l_release/apps/myApps/libav/libavformat/libavformat.a -L /home/pi/of_v0.9.8_linuxarmv6l_release/apps/myApps/libav/libavavutil/libavutil.a -lm -L/opt/vc/lib   /home/pi/of_v0.9.8_linuxarmv6l_release/libs/poco/lib/linuxarmv6l/libPocoNetSSL.a /home/pi/of_v0.9.8_linuxarmv6l_release/libs/poco/lib/linuxarmv6l/libPocoNet.a /home/pi/of_v0.9.8_linuxarmv6l_release/libs/poco/lib/linuxarmv6l/libPocoCrypto.a /home/pi/of_v0.9.8_linuxarmv6l_release/libs/poco/lib/linuxarmv6l/libPocoUtil.a /home/pi/of_v0.9.8_linuxarmv6l_release/libs/poco/lib/linuxarmv6l/libPocoJSON.a /home/pi/of_v0.9.8_linuxarmv6l_release/libs/poco/lib/linuxarmv6l/libPocoXML.a /home/pi/of_v0.9.8_linuxarmv6l_release/libs/poco/lib/linuxarmv6l/libPocoFoundation.a  -L/usr/lib/arm-linux-gnueabihf -lz -lgstapp-1.0 -lgstvideo-1.0 -lgstbase-1.0 -lgstreamer-1.0 -ludev -lfontconfig -lfreetype -lsndfile -lopenal -lssl -lcrypto -lgtk-3 -lgdk-3 -lpangocairo-1.0 -lpango-1.0 -latk-1.0 -lcairo-gobject -lcairo -lgdk_pixbuf-2.0 -lgio-2.0 -lgobject-2.0 -lglib-2.0 -lmpg123  -lfreeimage -lboost_filesystem -lboost_system -lrtaudio -lGLESv2 -lGLESv1_CM -lEGL -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpcre -lrt -lX11 -ldl
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::~ofTessellator()':
ofTessellator.cpp:(.text+0x28): undefined reference to `tessDeleteTess'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::init()':
ofTessellator.cpp:(.text+0x88): undefined reference to `tessNewTess'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::operator=(ofTessellator const&)':
ofTessellator.cpp:(.text+0x100): undefined reference to `tessDeleteTess'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::performTessellation(ofPolyWindingMode, ofMesh&, bool)':
ofTessellator.cpp:(.text+0x13c): undefined reference to `tessTesselate'
ofTessellator.cpp:(.text+0x1fc): undefined reference to `tessGetVertexCount'
ofTessellator.cpp:(.text+0x208): undefined reference to `tessGetElementCount'
ofTessellator.cpp:(.text+0x21c): undefined reference to `tessGetVertices'
ofTessellator.cpp:(.text+0x234): undefined reference to `tessGetElements'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::tessellateToMesh(ofPolyline const&, ofPolyWindingMode, ofMesh&, bool)':
ofTessellator.cpp:(.text+0x364): undefined reference to `tessAddContour'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::tessellateToMesh(std::vector<ofPolyline, std::allocator<ofPolyline> > const&, ofPolyWindingMode, ofMesh&, bool)':
ofTessellator.cpp:(.text+0x410): undefined reference to `tessAddContour'
ofTessellator.cpp:(.text+0x4a0): undefined reference to `tessAddContour'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::performTessellation(ofPolyWindingMode, std::vector<ofPolyline, std::allocator<ofPolyline> >&, bool)':
ofTessellator.cpp:(.text+0x4f8): undefined reference to `tessTesselate'
ofTessellator.cpp:(.text+0x5b8): undefined reference to `tessGetVertices'
ofTessellator.cpp:(.text+0x5c4): undefined reference to `tessGetElements'
ofTessellator.cpp:(.text+0x5d0): undefined reference to `tessGetElementCount'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::tessellateToPolylines(ofPolyline const&, ofPolyWindingMode, std::vector<ofPolyline, std::allocator<ofPolyline> >&, bool)':
ofTessellator.cpp:(.text+0x860): undefined reference to `tessAddContour'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/lib/linuxarmv6l/libopenFrameworks.a(ofTessellator.o): In function `ofTessellator::tessellateToPolylines(std::vector<ofPolyline, std::allocator<ofPolyline> > const&, ofPolyWindingMode, std::vector<ofPolyline, std::allocator<ofPolyline> >&, bool)':
ofTessellator.cpp:(.text+0x90c): undefined reference to `tessAddContour'
ofTessellator.cpp:(.text+0x99c): undefined reference to `tessAddContour'
obj/linuxarmv6l/Release/src/encoder.o: In function `Encoder::init(int, int)':
encoder.cpp:(.text+0x18): undefined reference to `avcodec_register_all'
encoder.cpp:(.text+0x20): undefined reference to `avcodec_find_encoder'
encoder.cpp:(.text+0x38): undefined reference to `avcodec_alloc_context3'
encoder.cpp:(.text+0xa4): undefined reference to `avcodec_open2'
encoder.cpp:(.text+0xcc): undefined reference to `av_frame_alloc'
encoder.cpp:(.text+0xf4): undefined reference to `av_frame_get_buffer'
encoder.cpp:(.text+0x100): undefined reference to `av_packet_alloc'
obj/linuxarmv6l/Release/src/encoder.o: In function `Encoder::close()':
encoder.cpp:(.text+0x20c): undefined reference to `avcodec_free_context'
encoder.cpp:(.text+0x214): undefined reference to `av_frame_free'
encoder.cpp:(.text+0x220): undefined reference to `av_packet_free'
obj/linuxarmv6l/Release/src/encoder.o: In function `Encoder::encode(unsigned char*)':
encoder.cpp:(.text+0x24c): undefined reference to `av_freep'
collect2: error: ld returned 1 exit status
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk:382: recipe for target 'bin/libavTest' failed
make[1]: *** [bin/libavTest] Error 1
make[1]: Leaving directory '/home/pi/of_v0.9.8_linuxarmv6l_release/apps/myApps/libavTest'
/home/pi/of_v0.9.8_linuxarmv6l_release/libs/openFrameworksCompiled/project/makefileCommon/compile.project.mk:125: recipe for target 'Release' failed
make: *** [Release] Error 2

Found a solution, by trial/error

  1. copied all the needed libraries under at subfolder of my app (libs)
  2. modified config.make as PROJECT_LDFLAGS += -L ./libs -l avcodec -l avformat -l avutil -l avresample -lm

All errors gone !

yes, -L means library search path and -lname link against libname.* if you want to specify the exact file to link to, you can also just pass the full path to the binary in PROJECT_LDFLAGS without -L or -l

1 Like