【问题标题】:make: trigger without rebuilding dependencymake: 在不重建依赖的情况下触发
【发布时间】:2014-07-31 01:29:30
【问题描述】:

基本上我有通常的 Makefile 结构:

target: dependency1 dependency2 dependency3
      runtargetscript.sh

但是在这种情况下,目标只需要其中一个依赖项,并且某些依赖项可能无法构建。 (所以我不能只构建所有依赖项)

当依赖项之一更改/创建(即正常行为)时,是否可以告诉 make 触发“目标”但不尝试重建任何丢失的依赖项?

【问题讨论】:

    标签: makefile


    【解决方案1】:

    使用 GNU make,您可以使用 shell 转义来动态构建依赖项,只有在它们已经存在时才添加它们:

    if_exist = $(shell if [ -e $(1) ]; then echo $(1); fi)
    
    target: $(call if_exist,dependency1) $(call if_exist,dependency2) $(call if_exist,dependency3)
            runtargetscript.sh
    

    如果 target 不存在,或者如果它比任何在读取 makefile 时确实存在的依赖项更旧,这将运行脚本,但不会尝试构建它们他们当时不存在。

    请注意这里的重要警告 - 如果文件不存在,但其他一些不相关的规则运行创建它们的操作,它将不会重建目标,除非您再次重新运行 make target

    【讨论】:

      【解决方案2】:

      假设您的规则主体没有做任何特殊的事情,具体取决于哪些依赖项比目标更新,您可以使用 -W 标志来指示它将某些目标视为始终是新的(因此不需要构建) .

      因此,对于给定的示例,假设您可以(并且想要)构建 dependency2 但不能构建 dependency1dependency3,您将运行:

      make -W dependency1 -W dependency3 target
      

      编辑:正如 cmets 中所指出的,当 dependency2 不比 target 更新时,这将无法正常工作,因为仍将构建 target

      在这种情况下,我相信唯一的解决方案(鉴于下面的 cmets)是使用类似的东西:

      DEPENDENCY_BIN := $(or $(wildcard /path/to/mysql),$(wildcard /path/to/sqlite3),/path/that/does/not/exist)
      
      target: $(DEPENDENCY_BIN) dependency2
      

      【讨论】:

      • 不,这并不重要,因为 (1) 缺少依赖会导致失败,并且 (2) 在所有情况下都会触发目标,即使没有更改依赖项
      • @Robby75 1) 如果缺少依赖意味着目标无法构建,那么我根本不知道如何获得所需的东西。 2) 不,这只会在dependency2target 更新时触发。
      • 1) 安装需要 MySQL 二进制文件 OR Sqlite3 二进制文件,但不能同时使用两者——只要至少一个是可用
      • 2) 来自手册页:-W file, --what-if=file, --new-file=file, --assume-new=file 假装目标文件刚刚被修改.当与 -n 标志一起使用时,这将向您显示如果您要修改该文件会发生什么。没有-n,它几乎和在运行make之前对给定文件运行一个touch命令一样,除了修改时间只是在make的想象中改变。 --- END --- 这意味着总是会触发目标,因为 -W dependency1 将导致(假定)dependency1 比目标更新。
      • 嗯...没错。对于第二点,我没有正确地考虑这一点。我很抱歉。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 2015-02-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多