Makefile 习惯用法安装到第一个可用目录

Makefile 习惯用法安装到第一个可用目录

我有一个生成文件其中,除其他外,安装 Bash 补全脚本:

install [...] /etc/bash_completion.d/

这在 Ubuntu 中工作得很好,但在 Arch Bash 中补全被安装到/usr/share/bash-completion/completions.

会是什么惯用的 GNU 或 POSIXmake方式来处理这个?我希望一个好的解决方案具有以下功能:

  1. 如果install命令失败,则目标也必定失败。
  2. 按书写顺序遍历目录列表。在第一个已经存在的目录处(如果有):
    1. 如果文件不存在则安装,
    2. 如果文件存在且不是最新的(根据make语义),则覆盖该文件,
    3. 如果文件存在并且是最新的,则跳过该文件,并且
    4. 停止处理目录。
  3. 这是不是如果该文件未安装在任何地方,则会出现错误。
  4. 这是不是Makefile如果该文件已安装在一个目录中,并且后续运行将其安装到另一个目录中,则会出现错误(也不应尝试处理这种情况)。也就是说,给定一个目录列表/a /b,如果有人

    1. 创造/b,
    2. 将文件放入/b,
    3. 然后创建/a
    4. 运行make

    应该Makefile不是/b检测到所有的存在。

  5. 这是不是如果任何目录都不存在,则会出现错误。
  6. 关于尝试了哪些目录的反馈会很好,但不是强制性的。

答案1

显而易见的脚本式解决方案是这样做:

for dir in /etc/bash_completion.d /usr/share/bash-completion/completions; \
do \
    if [ -d "$$dir" ]; \
    then \
        install [...] "$$dir" || exit 1; \
        break; \
    fi; \
done

然而,这不太好:

  • 很多转义字符
  • 需要使用ugly|| exit 1来检查错误

并且它不会检查文件是否是最新的(第 2.2、2.3 点)。

答案2

一种简单的方法是依次尝试每个安装并继续进行,直到其中一个安装成功为止。

for d in /etc/bash_completion.d /usr/share/bash-completion/completions; do \
  { cmp -s $(COMPLETION_SCRIPT) $$d/$(COMPLETION_SCRIPT) || \
    install $(INSTALL_OPTIONS) $(COMPLETION_SCRIPT) $$d; } && exit; \
done; \
exit 1

相关内容