linux - 使用 Make 在 shell 条件下构建

标签 linux makefile

如果尚未安装,我想将要构建的软件包添加到构建列表中。

目标是在没有 pip 的情况下从本地源安装一些 Python 包。我无权访问 pip...

所以我写了一个看起来像这样的 Makefile:

all: natsort foo bar foobar ...

natsort: natsort-4.0.4.tar.gz
    tar xvzf $<
    cd $(patsubst %.tar.gz,%, $<) && python setup.py install
    rm -rf $(patsubst %.tar.gz,%, $<)
    python -c 'import natsort'
    echo -e "Installation of $< [done]\n" >> install.log 

这个实现的问题是每次我运行 Make 命令时,所有的包都会被重建和重新安装。我想检查模块是否已经安装。我的想法是做这样的事情:

ifdef $(shell python -c 'import natsort')
all: natsort
endif

我怎样才能重写它以使其工作?

最佳答案

你绝对可以做这样的事情。但是每次运行 make 都会“花费”一次 shell 调用和一次 python 调用,这是一个相对较高的成本。

基本上,有两种方法可以以更便宜的方式完成您想要的事情。

配方中的标记文件和短路逻辑。

标记文件方法基本上就是您所拥有的方法,只是您将 touch $@ 添加到配方的末尾。

natsort: natsort-4.0.4.tar.gz
    tar xvzf $<
    cd $(patsubst %.tar.gz,%, $<) && python setup.py install
    rm -rf $(patsubst %.tar.gz,%, $<)
    python -c 'import natsort'
    echo -e "Installation of $< [done]\n" >> install.log 
    touch $@

以这种方式第一次运行配方会创建 stamp 文件,直到 natsort-4.0.4.tar.gz 变得比 stamp 文件更新或 stamp 文件被删除,配方将永远不会运行再次。

请注意第二点。删除 stamp 文件,然后重新安装。

这就是短路逻辑解决方案解决的问题。

与原来的多条命令规则不同,您将它们全部打包在一个命令中(这是可选的,但可以节省重复检查的成本),并在执行任何工作之前检查要安装的模块。

natsort: natsort-4.0.4.tar.gz
    if ! python -c 'import natsort'; then \
        tar xvzf $< || exit 1; \
        cd $(patsubst %.tar.gz,%, $<) && python setup.py install || exit 1; \
        rm -rf $(patsubst %.tar.gz,%, $<); \
        python -c 'import natsort' || exit 1; \
        echo -e "Installation of $< [done]\n" >> install.log; \
    fi

注意需要添加|| exit 1 因为我们不再为我们处理它。另请注意,这现在总是运行规则(我们应该标记natsort.PHONY)但在最常见的情况下它会在之后停止if 测试。

综上所述,您可以结合使用这些方法来获得两全其美的效果。

natsort: natsort-4.0.4.tar.gz
    if ! python -c 'import natsort'; then \
        tar xvzf $< || exit 1; \
        cd $(patsubst %.tar.gz,%, $<) && python setup.py install || exit 1; \
        rm -rf $(patsubst %.tar.gz,%, $<); \
        python -c 'import natsort' || exit 1; \
        echo -e "Installation of $< [done]\n" >> install.log; \
    fi
    touch $@

您将获得这两种方法的好处。第一次运行 make 时,natsort 文件不存在,并且运行了配方。 natsort 未安装,因此 if 测试失败并开始安装。之后 natsort 文件被 touch 编辑。下次安装 make 时,natsortnatsort-4.0.4.tar.gz 更新,所以 make 认为它没有任何问题做。如果出于某种原因,您删除了 natsort 文件,那么下次 make 运行时,它会检查模块是否存在,跳过安装并touch再次输入 natsort 文件以恢复同步。

关于linux - 使用 Make 在 shell 条件下构建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33630829/

相关文章:

linux - OEToolchainConfig.cmake 未由 cmake 配方 Yocto 安装

c# - 应该调用 C# .BeginReceive() 多少次以接收发送的 3 个 block ,即通过 TCP 对 Linux C write() 的 3 次调用?

Linux读取文件权限

c++ - 堆栈变量或函数声明

makefile - 编译 Fortran 程序和编译器/库

linux - rpmbuild 和签名的可执行文件

c - 在另一个发行版中运行 C 可执行文件

c - PETSc 示例不起作用

在 Windows 上使用 Makefile 编译 C 文件

c++ - 如何使用makefile编译arduino核心库?