Crt Crt - 1 year ago 52
C Question

Function Defined in Static Library is not being found

I am having a problem finding a function called

get_offsets()
defined in
bam_sqlite.c
.

I define a static library with the following:

CC = gcc
CFLAGS = -Wall -g -std=c99 -fPIC
INC := -Iinclude -I./ -I/gpfs/commons/home/knagdimov/temp/git/Rbamdb/htslib/ -I/gpfs/commons/home/knagdimov/temp/git/Rbamdb/lmdb/libraries/liblmdb/ -I/gpfs/commons/home/knagdimov/temp/git/Rbamdb/sqlite3/

all:

@mkdir -p bin
$(CC) $(CFLAGS) $(INC) -c bamdb.c -o bin/bamdb.o
$(CC) $(CFLAGS) $(INC) -c src/bam_api.c -o bin/bam_api.o
$(CC) $(CFLAGS) $(INC) -c src/bam_lmdb.c -o bin/bam_lmdb.o
$(CC) $(CFLAGS) $(INC) -c src/bam_sqlite.c -o bin/bam_sqlite.o
ar -rcs bin/libbamdb.a bin/bamdb.o bin/bam_api.o bin/bam_lmdb.o bin/bam_sqlite.o


I then, run
nm libbamdb.a
and get the following output:

bam_sqlite.o
000000000000067b T get_offsets


Thus, the function is defined in the static library. Finally, I run the Makefile which contains the following:

PKG_BASE = $(shell pwd)/../
LIB_BASE = -Wl,-rpath,$(PKG_BASE)
PKG_CPPFLAGS = -I$(PKG_BASE)bamdb -I$(PKG_BASE)Rbamdb -I$(PKG_BASE)bamdb/include/ -I$(PKG_BASE)htslib/ -I$(PKG_BASE)lmdb/libraries/liblmdb/ -I$(PKG_BASE)sqlite3/
PKG_CXXFLAGS = -I$(PKG_BASE)badb -I$(PKG_BASE)Rbamdb -I$(PKG_BASE)bamdb/include/ -I$(PKG_BASE)htslib/ -I$(PKG_BASE)lmdb/libraries/liblmdb/ -I$(PKG_BASE)sqlite3/
PKG_LIBS = -L$(PKG_BASE)/ -L$(PKG_BASE)/bamdb/bin/ -L$(PKG_BASE)htslib/ -L$(PKG_BASE)lmdb/libraries/liblmdb/ -L$(PKG_BASE)sqlite3/ -lbamdb -lhts -llmdb -lsqlite3


The other libraries are libsqlite3.so, libhts.a, liblmdb.a, and they seem to all be found. The only one not being found is libbamdb.a which makes me believe I am defining the static library in a wrong way.

Please note that bamdb source code (bam_api.c, bam_lmdb.c, bam_sqlite.c, bam_sqlite.c) depend on functions defined in other static libraries. Should I include them them I'm compiling these source codes into object files?

Ultimately the following solved the problem: the Makevars file is creating a .so file using the g++ compiler. The previous libraries were C libraries compiled using gcc. The header files of the C source code didn't include the following:

#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}


Including that solved the problem.

Answer Source

If you are using gcc and the gnu linker, then this description of the -l command line argument may help

The linker will search an archive only once, at the location where it is specified on the command line. If the archive defines a symbol which was undefined in some object which appeared before the archive on the command line, the linker will include the appropriate file(s) from the archive. However, an undefined symbol in an object appearing later on the command line will not cause the linker to search the archive again.

See the -( option for a way to force the linker to search archives multiple times.

So if the reference to get_offsets() is coming from one of the -l library after -lbamdb then you need to rearrange the -l or use -( -) .

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download