【发布时间】:2009-09-03 21:58:54
【问题描述】:
作为我last one 的后续问题,是否有任何简单的方法来判断给定的 C 库是否安装在给定的机器上(不是以编程方式,只是一次性的事情)?我需要使用 libuuid,但我不确定它是否安装在相关机器上。我能想到的唯一两种方法是:
1) 尝试在那里编译代码(比我想做的还多)
2) 尝试“man libuuid”之类的方法,但如果由于某种原因未安装联机帮助页,这似乎并不总是可靠的。
还有其他更好的方法吗?
【问题讨论】:
作为我last one 的后续问题,是否有任何简单的方法来判断给定的 C 库是否安装在给定的机器上(不是以编程方式,只是一次性的事情)?我需要使用 libuuid,但我不确定它是否安装在相关机器上。我能想到的唯一两种方法是:
1) 尝试在那里编译代码(比我想做的还多)
2) 尝试“man libuuid”之类的方法,但如果由于某种原因未安装联机帮助页,这似乎并不总是可靠的。
还有其他更好的方法吗?
【问题讨论】:
您是否考虑过使用autoconf?它旨在检查构建环境是否设置正确。
【讨论】:
autoconf 的基本用例。 autoconf 将获取 configure.ac 文件并输出 configure shell 脚本。
autoconf 的示例,也许您的答案会得到改善?显然你不能在一个 StackOverflow 答案中解释 autoconf,但你至少可以让他开始。
最简单的方法是使用-l 选项调用ld。这将有效地测试库的存在,自动搜索标准库位置:
$ ld -luuid
ld: warning: cannot find entry symbol _start; not setting start address
$ echo $?
0
$ ld -luuidblah
ld: cannot find -luuidblah
$ echo $?
1
# so...
$ ld -luuid 2>/dev/null && echo "libuuid exists" || echo "libuuid not found"
编辑
正如dreamlax 所指出的,这并不适用于所有的unix 变体。我不知道它是否适用于所有 unix(我已经测试过 linux 和 OpenBSD),但你可以试试这个:
$ echo "int main(){}" | gcc -o /dev/null -x c - -luuid 2>/dev/null
$ echo $?
0
$ echo "int main(){}" | gcc -o /dev/null -x c - -luuidblah 2>/dev/null
$ echo $?
1
【讨论】:
ld 在这两种情况下都返回 1。
ld 的错误,但这仍然是一个问题。
这是我使用 autoconf 所做的,我在这里将其作为一个可靠的例子展示给接下来可能出现的其他人:
我创建了文件configure.ac,其中包含以下内容:
AC_INIT(package, 1.1, email)
AC_CHECK_LIB(uuid, uuid_generate_random, [echo "libuuid exists"], [echo "libuuid missing"])
然后我按顺序运行以下命令(我创建的同一文件夹 configure.ac):
autoconf
./configure
在配置结束时,它会返回是否在uuid 库中找到uuid_generate_random。似乎工作得很好(尽管不幸的是,其中两个操作系统缺少库,但这是另一个问题)。
对于事后可能会发现这一点的任何人,这里的 AC_INIT 参数是一次性的,您可以大量复制它们。 AC_CHECK_LIB 的参数是:库名称、该库中函数的名称、成功时要做什么、失败时要做什么。
尽管 Mehrdad 的回答没有我希望的那么有帮助(即没有花时间浏览文档),但它似乎是正确的,我会接受它。 mhawke:我真的很喜欢你的回答,但我不太确定如何测试以确保它有效。它似乎在 SunOS 上,但在其他两个(AIX、HPUX)上总是说不,我似乎无法想出一个我可以保证它会找到的库。
感谢大家的帮助。
【讨论】:
如前所述,自动工具会检查库中的符号。它的方式有点简单。正如您在 1) 中提到的,autoconf 及其结果配置脚本基本上创建了一个虚拟 c 程序并尝试与相关库链接。如果它工作,图书馆工作,如果它失败,显然它不会工作。不过,Autoconf 会在库中查找特定的符号/函数名称。
【讨论】: