c - 找不到静态库中定义的函数

标签 c makefile

我在查找 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/

相关文章:

linux -/usr/lib/libpthread.so : No such file or directory &&/usr/lib/libm. so: No such file or directory 已解决

c - 如何声明变量参数的数据类型?

c - 如何动态分配一个二维指针数组? (C)

c - NVCC:警告:允许所有异常与以前的功能不兼容

c - 将输入从标准输入传递到文件(C 编程)

c++ - 如何有条件地将文件包含到 Makefile 中?

makefile - 使用Premake链接到外部库

c - 与其他 Linux 发行版相比,fork() 在 Ubuntu 上的工作方式是否不同?

makefile - 动态目标中的目标变量

c++ - 编译前将终端输出插入源文件