如何在进行检查期间定位二进制文​​件?

Posted

技术标签:

【中文标题】如何在进行检查期间定位二进制文​​件?【英文标题】:How to locate binaries during make check? 【发布时间】:2020-01-10 01:51:07 【问题描述】:

由于路径问题,我在运行 make check 时遇到问题。目前我的 shell 脚本(由 autoconf 配置)包含

prefix="@prefix@"
exec_prefix="@exec_prefix@"
PATH="@libexecdir@:$PATH"

它稍后会执行位于@libexecdir@ 中的二进制文件。这可以在make install 之后找到,但是当它不起作用时是在make check 期间。由于文件尚未安装,因此它们不在预期的位置。

解决这个问题的正确方法是什么?我一定不是第一个尝试解决这个问题的人......

【问题讨论】:

“我的 shell 脚本”是指包含您的一项测试的脚本,还是指您正在接受测试的项目的可安装组件?还是别的什么? 可安装组件。一个安装为bin_SCRIPTS = foo,另一个安装为libexec_SCRIPTS = bar,我需要从foo 调用bar 【参考方案1】:

我一定不是第一个尝试解决这个问题的人。

不,虽然我稍后会描述一些可能性,但没有一个真正的惯例来解决这个问题。有些项目根本没有解决这个问题——他们要么根本不提供自动化测试,要么他们设计自己的测试套件在安装后运行。

解决这个问题的正确方法是什么?

这取决于您的程序/脚本的详细信息。对于在哪里可以找到它们所依赖的外部软件非常不灵活的程序在安装之前可能很难测试。当然,如果安装前可测试性是项目目标,那么您必须在脚本中构建一些灵活性,以了解它如何定位要运行的二进制文件。

这种灵活性最常见的形式可能是

识别命令行选项,通过这些选项可以在运行时覆盖二进制文件的位置,和/或 识别用于相同目的的环境变量。

根据项目的不同,这种覆盖功能可能会服务于更多的用例,而不仅仅是测试。

不过,只要我们谈论的是环境变量,脚本不应该依赖可执行文件搜索路径来定位所需的二进制文件。 libexec 目录不应该在路径中——那里的二进制文件应该只显式运行。即使在脚本内部设置它也不是一个足够的解决方案,因为它可能会从那里传播到脚本运行的其他程序。此外,如果由于某种原因所需的二进制文件不在 libexec 目录中,那么您不希望意外运行恰好具有相同名称的不同二进制文件。

【讨论】:

Even setting it internally in the script is not a sufficient solution because it may propagate from there to other programs the script runs. - 嗯,你说得对,我没有想到【参考方案2】:

要回答我自己的问题,正确的做法是 RTFM(通常是这样):

引自(强调我的):https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/autoconf.html#Installation-Directory-Variables

这些变量中的大多数都具有依赖于前缀或 exec_prefix 的值。故意使目录输出变量保持未扩展:通常将“@datarootdir@”替换为“$prefix/share”,而不是“/usr/local/share”,并且将“@datadir@”替换为“ $datarootdir'。

此行为是 GNU 编码标准规定的,因此当用户运行时:

‘制作’

她仍然可以指定与指定配置不同的前缀,在这种情况下,如果需要,包应该硬编码对应于 make-specified 前缀的依赖项。

‘进行安装’

她可以指定不同的安装位置,在这种情况下,包必须仍然依赖于编译的位置(即,运行“make install”时永远不要重新编译)。这是一个非常重要的功能,因为许多人可能会决定安装组合在一起的软件包的所有文件,然后安装从最终位置到那里的链接。

为了支持这些功能,datarootdir 必须保持定义为“$prefix/share”,以便可以根据当前的前缀值扩展其值。

一个推论是你不应该使用这些变量,除了在 makefile 中。例如,与其尝试在 configure 中评估 datadir 并使用例如'AC_DEFINE_UNQUOTED([DATADIR], ["$datadir"], [Data directory.])' 在 makefile 中对其进行硬编码,您应该添加 -DDATADIR=' $(datadir)' 添加到 makefile 的 CPPFLAGS 定义中(如果您还使用 Automake,则为 AM_CPPFLAGS)。

同样,您不应依赖 AC_CONFIG_FILES 来替换您的 shell 脚本和其他文件中的 bindir 和朋友;相反,让 make 管理他们的替换。例如,Autoconf 提供了以“.in”结尾的 shell 脚本模板,并使用类似于以下的 makefile sn-p 来构建 autoheader 和 autom4te 等脚本:

 edit = sed \
         -e 's|@bindir[@]|$(bindir)|g' \
         -e 's|@pkgdatadir[@]|$(pkgdatadir)|g' \
         -e 's|@prefix[@]|$(prefix)|g'

 autoheader autom4te: Makefile
         rm -f $@ $@.tmp
         srcdir=''; \
           test -f ./$@.in || srcdir=$(srcdir)/; \
           $(edit) $$srcdir$@.in >$@.tmp

         chmod +x $@.tmp
         chmod a-w $@.tmp
         mv $@.tmp $@

 autoheader: $(srcdir)/autoheader.in
 autom4te: $(srcdir)/autom4te.in

【讨论】:

以上是关于如何在进行检查期间定位二进制文​​件?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 npm 在 64 位系统上构建 32 位二进制文​​件?

为啥 32 位内核可以运行 64 位二进制文​​件?

Objcopy 获取目标文件 64 位二进制文​​件

gcc:在 32 位平台上编译 64 位二进制文​​件

无法在 64 位 Debian 上运行 32 位二进制文​​件

Python:读取 12 位二进制文​​件