简体   繁体   中英

Given a list of static libraries and search directories (in GCC/ld format), how to assemble them into a static library

I have a specific problem, but let me first take a stab at formulating it in a general way:

I am working in Linux (openSUSE 12.2 to be exact). The toolchain is quite standard, using make, OpenMPI mpicc (which uses GCC) and so on.

My problem is essentially that I am given a string of link commands as a macro in a makefile (ie, "-lsomelib -L/some/path -lanotherlib" and so on). I want to create a library (let's call it libmine) which uses these libraries, and I don't want the consumers of libmine to have to care about what libraries I use (ie, they should only have to do -lmine and not care about -lsomelib and so on).


Specifically I am dealing with petsc , which strongly suggests that I use one of its makefiles as a template instead of trying to roll my own. A minimal makefile for my purposes would be:

include ${PETSC_DIR}/conf/variables                                             
include ${PETSC_DIR}/conf/rules                                                 

mine.o: mine.c chkopts                                                            
        ${CC} ${CFLAGS} ${PETSC_CCPPFLAGS} -o mine.o -c mine.c ${PETSC_KSP_LIB}

Here mine.c is the source code for my library, and ${PETSC_KSP_LIB} is a string containing link instructions. On my machine it is specifically:

-L/usr/local/petsc/petsc-3.3-p5_user0/linux-gnu-user0/lib -lpetsc -lX11 -lpthread -Wl,-rpath,/usr/local/atlas -L/usr/local/atlas -llapack -lblas -L/usr/lib64/mpi/gcc/openmpi/lib64 -L/usr/lib64/gcc/x86_64-suse-linux/4.7 -L/usr/local/petsc/petsc-3.3-p5_user0 -L/opt/AMDAPP/lib/x86_64 -L/usr/x86_64-suse-linux/lib -lmpi_f90 -lmpi_f77 -lgfortran -lm -lgfortran -lm -lgfortran -lm -lm -lquadmath -lm -ldl -lmpi -lnsl -lutil -lgcc_s -lpthread -ldl

These libraries are mostly static libraries (though there are presumably some dynamic ones in there as well).

I am looking for a way to have mine.o (or a finished library libmine.a) contain all of the necessary information so that when some other application that uses libmine is compiled, it only needs to link to libmine, not to the whole host of libraries that is listed in ${PETSC_KSP_LIB} .

I would hope that this is easy to do(?), but I am very shaky on the whole linking process really. Would it for example be easier to do if all the libraries were either static or dynamic? Also note that it is not necessary for me to include dynamic libraries statically, as for example adding a folder to LD_LIBRARY_PATH is not a problem at all. The essential part is that I should not have to worry about the list of libraries used by my petsc-based library when I use said library in other project.

Converting a shared library into a static library is non-trivial .

To combine several static libraries into one, just unpack them and then build the new one (crude but effective):

ar -xv somelib.a
ar -xv anotherlib.a
...

ar -r libmine.a *.o

I have heard of a more elegant solution in one step, but I'd like to test it before I endorse it...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM