链接到 bzip2 库时未定义对“_fdopen”的引用

Undefined reference to '_fdopen' when linking against bzip2 library

我是在 linux 上进行编译的新手,所以我正在涉足一些不熟悉的领域。 我在 Ubuntu 14.04 上使用 G++ 和 GCC 编译器。

我正在尝试将 bzip2 (1.0.6) 编译为共享库并在另一个应用程序中使用它。

为了构建共享库,我使用了:

gcc -shared -fPIC \
    -o ./lib/libbzip2.so \
blocksort.c bzip2.c bzlib.c compress.c crctable.c decompress.c huffman.c randtable.c \
    >& compile.log

没有报错,.so文件创建成功。

为了构建我的应用程序和 link 到 bzip2 库,我使用了:

g++ -std=c++11 \
    -I ../bzip2-106 \
    main.cpp \
    -L../bzip2-106/lib \
    -o main \
    -lbzip2 \
    >& compile.log

这会导致以下错误:

../bzip2-106/lib/libbzip2.so: undefined reference to `_fdopen'
../bzip2-106/lib/libbzip2.so: undefined reference to `_isatty'
../bzip2-106/lib/libbzip2.so: undefined reference to `_fileno'
collect2: error: ld returned 1 exit status

据我所知,fdopen、isatty 和fileno 是标准库中的函数。但如果是这样的话,编译器不应该自动 link 到适当的标准库吗?如果没有,我需要 link 反对哪些图书馆?下划线的意义是什么?将 bzip2 编译为 C 库与它有什么关系吗?

没有报告错误,因为您要求none。符号上的前导下划线可能是直接问题。 bzip2 带有一个 Makefile-libbz2_so,通常将其用作起点(它会打开编译器警告,并在共享对象中设置依赖项)。

Linux 上的前导下划线是一种异常现象——很久以前(ELF 之前),这些很常见。但标准化已经消除了这一点。无论我是使用您引用的命令还是使用推荐的 makefile 进行编译,共享库中的外部符号都没有前导下划线。相反,没有选项的 "nm" 显示(例如,使用 Ubuntu 14.04)

U fchmod@@GLIBC_2.2.5                                          
U fchown@@GLIBC_2.2.5                                          
U fclose@@GLIBC_2.2.5                                          
U fdopen@@GLIBC_2.2.5                                          
U ferror@@GLIBC_2.2.5                                          
U fflush@@GLIBC_2.2.5                                          
U fgetc@@GLIBC_2.2.5   

至于与 g++ 的链接(未显示 main.cpp),我们假设它包含 bzlib.h(它确实具有预期的 extern "C" 包装 C 原型) .

所以...我们缺少一些信息。