【问题标题】:Function Defined in Static Library is not being found未找到静态库中定义的函数
【发布时间】:2017-01-24 00:04:11
【问题描述】:

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

包括解决了问题。

【问题讨论】:

  • 发布整个makefile
  • @NeilButterworth 是根目录的整个 Makefile。您想查看 bamdb、htslib、lmdb 或 sqlite3 的 Makefile 吗?
  • 我相信你听说过minimal complete examples。尝试编写链接到libbamdb.a 的代码,而不是其他库。向我们展示 Make 执行的命令。从命令行尝试该命令。 简化。
  • 除非我遗漏了什么,否则您发布的代码中没有目标,所以我看不出这是一个有效的 makefile。
  • 你有没有试过找到bam_sqlite.c中定义的其他函数?

标签: c makefile


【解决方案1】:

如果您使用 gcc 和 gnu 链接器,那么 -l 命令行参数的描述可能会有所帮助

链接器只会在存档位置搜索一次 在命令行中指定。如果档案定义了一个符号 在存档之前出现的某些对象中未定义 在命令行上,链接器将包含适当的文件 从档案中。但是,对象中出现未定义的符号 稍后在命令行上不会导致链接器搜索 再次存档。

查看 -( 选项以了解强制链接器搜索档案的方法 多次。

因此,如果对 get_offsets() 的引用来自 -lbamdb 之后的 -l 库之一,那么您需要重新排列 -l 或使用 -( -) 。

【讨论】:

  • 具体来说,我该怎么做呢?以下工作是否可行:PKG_LIBS = -L$(PKG_BASE)/ -L$(PKG_BASE)/bamdb/bin/ -L$(PKG_BASE)htslib/ -L$(PKG_BASE)lmdb/libraries/liblmdb/ -L$(PKG_BASE)sqlite3/ -Wl, --start-group -lbamdb -lhts -llmdb -lsqlite3 -Wl, --end-group
猜你喜欢
  • 2017-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多