0

I'm trying to build a single library so that it can be linked easily by a single -l switch. Basically If I compile an executable and type out all the libraries my project needs like so:

g++ ncorr_test.cpp -o ncorr_test -I../include -I../../opencv/include/opencv2 -std=c++11 ../lib/ncorr.o ../lib/Strain2D.o ../lib/Disp2D.o ../lib/Data2D.o ../lib/ROI2D.o ../lib/Image2D.o ../lib/Array2D.o `pkg-config opencv --libs` ../../fftw/libs/libfftw3.a ../../SuiteSparse/SPQR/Lib/libspqr.a ../../SuiteSparse/CHOLMOD/Lib/libcholmod.a ../../SuiteSparse/SuiteSparse_config/libsuitesparseconfig.a ../../SuiteSparse/AMD/Lib/libamd.a ../../SuiteSparse/COLAMD/Lib/libcolamd.a ../../lapack/liblapack.a ../../blas/libs/libblas_LINUX.a /usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.a

The executable compiles and runs fine. However, when I compile all the libraries together:

ar rvs libncorr.a ../lib/ncorr.o ../lib/Strain2D.o ../lib/Disp2D.o ../lib/Data2D.o ../lib/ROI2D.o ../lib/Image2D.o ../lib/Array2D.o `pkg-config opencv --libs` ../../fftw/libs/libfftw3.a ../../SuiteSparse/SPQR/Lib/libspqr.a ../../SuiteSparse/CHOLMOD/Lib/libcholmod.a ../../SuiteSparse/SuiteSparse_config/libsuitesparseconfig.a ../../SuiteSparse/AMD/Lib/libamd.a ../../SuiteSparse/COLAMD/Lib/libcolamd.a ../../lapack/liblapack.a ../../blas/libs/libblas_LINUX.a /usr/lib/gcc/x86_64-linux-gnu/4.8/libgfortran.a

And then compile like:

g++ ncorr_test.cpp -o ncorr_test -I../include -I../../opencv/include/opencv2 -std=c++11 libncorr.a

I get a bunch of undefined reference errors. I've checked the contents of libncorr.a by using ar -t libncorr.a and it prints out all the libraries I need:

ncorr.o
Strain2D.o
Disp2D.o
Data2D.o
ROI2D.o
Image2D.o
Array2D.o
libopencv_calib3d.so
libopencv_core.so
libopencv_features2d.so
libopencv_flann.so
libopencv_highgui.so
libopencv_imgcodecs.so
libopencv_imgproc.so
libopencv_ml.so
libopencv_objdetect.so
libopencv_photo.so
libopencv_shape.so
libopencv_stitching.so
libopencv_superres.so
libopencv_ts.a
libopencv_video.so
libopencv_videoio.so
libopencv_videostab.so
libopencv_viz.so
libfftw3.a
libspqr.a
libcholmod.a
libsuitesparseconfig.a
libamd.a
libcolamd.a
liblapack.a
libblas_LINUX.a
libgfortran.a

The order of the libraries should be the exact same, so I'm a little lost as to why these undefined references exist. Sorry for the longish code but this is literally what I'm using, so I didn't want to truncate anything and possibly obfuscate the issue. Is there something I'm major I'm missing here?

JustinBlaber
  • 4,629
  • 2
  • 36
  • 57

1 Answers1

1

A static library is just an archive of object files, it's not complete. Whatever external libraries are referenced by the object files in the archive, you need to link with those. Linking with a static library is no different than listing the object files in the archive directly.

You also can't put any other files inside a static library, the linker will not use them.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • So I can only include the object files in the archive (I think I misunderstood how the archiver works)? The other .a libraries wont be linked by using the above method? If not, is there a way I could combine everything into a single .a file so it can be linked easily? Basically everytime I want to use my library I'd prefer to not have to link all those opencv, fftw, and sparse matrix libraries. Is there a recommended solution for this? – JustinBlaber Jun 17 '15 at 05:17
  • @jucestain No, using static libraries there's no way of including all libraries, you need to explicitly link with all libraries yourself. However, if installed correctly, shouldn't you be able to use e.g. [`pkg-config opencv --libs`](http://linux.die.net/man/1/pkg-config) (or something to that effect) to get all libraries needed for OpenCV? – Some programmer dude Jun 17 '15 at 05:21
  • Opencv isnt an issue since it uses pkg-config. The main problem is the sparse matrix library I used has a lot of .a files. Basically if you look there are like 5 libraries from suite sparse, and then I have to link blas, lapack, and lgfortran. It's a lot of files. Do you think maybe I should just use pkg-config for my library? – JustinBlaber Jun 17 '15 at 05:25
  • @jucestain If you really have such a large number of dependencies, and the other packages doesn't have `pkg-config` configurations, then yes you should probably create a `pkg-config` configuration for your library. Then you only need to list your libraries once, and all applications using your library will be able to use that. – Some programmer dude Jun 17 '15 at 05:27