基本上我有两个版本的GMP库:
gmp
和gmp-devel
前者位于“通常位置”(如POSIX),此处为:/usr/include
和/usr/lib64/
。第二个路径为/usr/local/include
和/usr/local/lib
。考虑到后者尚未安装(即仅由make
编译)。
这是一些“虚拟”程序:
#include <stdio.h>
#include <gmp.h>
int main(void)
{
mpz_t a, b, c;
printf("%d.%d.%d\n", __GNU_MP_VERSION, __GNU_MP_VERSION_MINOR, __GNU_MP_VERSION_PATCHLEVEL);
#if __GNU_MP_VERSION >= 6
mpz_inits(a, b, c, NULL);
mpz_clears(a, b, c, NULL);
#endif
return 0;
}
对于库存版本显然它编译没有任何问题:
$ gcc -std=gnu99 -Wall dummy.c -lgmp
但是,如果我安装第二版GMP(即/usr/local
目录中的make install
目录),那么:
GNU预处理器cpp
首先找到/usr/local/include
路径(请参阅cpp
手册中的2.3 Search Path)。换句话说,我不需要添加-I/usr/local/include
。此外,“强制”使用“通常位置”标题并不容易,因为-I/usr/include
选项被忽略(一种解决方案是添加-nostdinc
选项并定义明确的标题列表,没有/usr/local/include
路径)。
GNU链接器ld
表现完全相反,它在编译期间不会搜索/usr/local/lib
(或更精确地说是链接),因此我得到:
$ gcc -std=gnu99 -Wall dummy.c -lgmp
/tmp/ccCCfPMX.o: In function `main':
dummy.c:(.text+0x41): undefined reference to `__gmpz_inits'
dummy.c:(.text+0x5d): undefined reference to `__gmpz_clears'
collect2: ld returned 1 exit status
我理解,我必须添加-L/usr/local/lib
,所以现在ld
正在使用正确的路径。要运行此程序(因为它是使用GMP编译为共享库),我需要:
LD_LIBRARY_PATH
(或者将其放入.bashrc
,.zshrc
等。)-Wl,-rpath=/usr/local/lib
/etc/ld.so.conf.d/
,运行# ldconfig
以更新其索引。我的问题是,这就是为什么预处理器和链接器/加载器之间存在这种不一致的原因?我错过了一些明显的东西吗?