我遇到了一个奇怪的“未定义引用”编译错误,我似乎找不到解决方案。 我正在尝试使用 Yocto 项目生成的 ARM 编译器 (arm-poky-linux-gnueabi-gcc) 为我的 Gumstix Overo 配置/编译 PAM 1.1.6,但在编译过程中不断收到以下错误:
.libs/pam_rhosts.o: In function `pam_sm_authenticate':
modules/pam_rhosts/pam_rhosts.c:117: undefined reference to `ruserok'
collect2: error: ld returned 1 exit status
因此,我做了一些调查,发现在配置过程中,编译并执行了以下测试代码来确定 ruserok、ruserok_af 和 iruserok 的可用性。
/* end confdefs.h. */
/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
For example, HP-UX 11i <limits.h> declares gettimeofday. */
#define $2 innocuous_$2
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $2 (); below.
Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
<limits.h> exists even on freestanding compilers. */
#ifdef __STDC__
# include <limits.h>
#else
# include <assert.h>
#endif
#undef $2
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char $2 ();
/* The GNU C library defines this for functions which it implements
to always fail with ENOSYS. Some functions are actually named
something starting with __ and the normal name is an alias. */
#if defined __stub_$2 || defined __stub___$2
choke me
#endif
int
main ()
{
return $2 ();
;
return 0;
}
因此,我复制、粘贴(用 ruserok 替换所有 $2)并使用生成的 GCC 编译器编译了此代码
./arm-poky-linux-gnueabi-gcc -o test.o test.c
查看 ruserok、ruserok_af 和 iuserok 函数是否存在/不存在,我收到以下编译错误:
/tmp/ccU8YszI.o: In function `main':
test.c:(.text+0x8): undefined reference to `ruserok'
collect2: error: ld returned 1 exit status
这与上面的“未定义引用‘ruserok’”错误相同。作为健全性检查,由于我之前通过 Ubuntu 软件中心安装了 Ubuntu/Linaro ARM GCC 编译器,因此我使用 arm-linux-gnueabi-gcc 编译器编译了相同的代码,但代码编译得很好,没有任何错误。 这是我参考的命令:
arm-linux-gnueabi-gcc -o test.o test.c
编译器(特别是
gcc
)不仅仅是代码生成器。 他们非常熟悉 libc 或标准 C
库以及 libgcc 编译器帮助程序库。 一般命令行隐式使用 -lc
(与 libc 链接)。 Ubuntu 中的 arm-linux-gnueabi-gcc
是带有 eglibc 的 crosstool-ng 版本。
我不知道 Poky gcc 是关于什么的。 您可以提供指向编译器来源的链接。 从Poky配置链接来看,编译器似乎是一个多库发行版或其他东西,并且您可能需要执行其他步骤来配置cross-build。
问题的答案,
为什么一个编译器会产生“对 ruserok 的未定义引用”错误,而另一个则不会?
因为一个库中有
ruserok
,而另一个没有(或未配置为可以看到它)。