我在查找 bam_sqlite.c
中定义的名为 get_offsets()
的函数时遇到问题。
我使用以下 Makefile
创建一个静态库:
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
然后,我运行 nm libbamdb.a
并获得以下输出:
bam_sqlite.o
000000000000067b T get_offsets
因此,该函数在静态库中定义。最后,我运行另一个 Makefile(在更高的目录中),其中包含以下内容:
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
其他库是libsqlite3.so、libhts.a、liblmdb.a,似乎都找到了。唯一没有找到的是 libbamdb.a,这让我相信我以错误的方式定义了静态库。
请注意,bamdb 源代码(bam_api.c、bam_lmdb.c、bam_sqlite.c、bam_sqlite.c)依赖于其他静态库中定义的函数。我应该将它们包含在我将这些源代码编译到目标文件中吗?
最终解决了问题:Makevars 文件正在使用 g++ 编译器创建 .so 文件。之前的库是使用gcc编译的C库。 C源代码的头文件不包含以下内容:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
包括解决了问题。
最佳答案
如果您使用 gcc 和 gnu 链接器,那么 -l 命令行参数的描述可能会有所帮助
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.
因此,如果对 get_offsets() 的引用来自 -lbamdb 之后的 -l 库之一,那么您需要重新排列 -l 或使用 -( -) 。
关于c - 找不到静态库中定义的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41817867/