【问题标题】:How to conditionally assign value to a variable in a Makefile (BSD + GNU)?如何有条件地为 Makefile(BSD + GNU)中的变量赋值?
【发布时间】:2018-10-21 04:21:58
【问题描述】:

我有一个(从我的角度来看)相当复杂的 Makefile。

这主要是因为我想要那里的颜色和其他不必要的东西。

无论如何,我可以直接进入我的问题:

除了Linux我新支持*BSD,因此我需要在几个地方检查正在使用的平台。在 Makefile 中是否可以进行条件变量赋值?比如:


platform := [ $$(uname) = Linux ] && echo Linux || echo BSD or other

当然这不起作用,但希望你明白我的意思。


我需要一个同时适用于 BSD make 和 GNU make 的解决方案。

【问题讨论】:

    标签: makefile conditional gnu-make bsdmake


    【解决方案1】:

    != shell 赋值运算符显然在 BSD 和 GNU make 上都受支持:

    platform_id != uname -s
    
    platform != if [ $(platform_id) = Linux ] || \
        [ $(platform_id) = FreeBSD ] || \
        [ $(platform_id) = OpenBSD ] || \
        [ $(platform_id) = NetBSD ]; then \
            echo $(platform_id); \
        else \
            echo Unrecognized; \
        fi
    

    请注意,这些赋值实际上是由 shell 计算的:赋值给 make 变量的是这个计算的结果,而不是 shell 命令。

    需要 GNU make 的解决方案。它适用于 BSD 上的 GNU make,但不适用于 BSD make。

    一种可能性是使用if GNU make function

    platform := $(if $(patsubst Linux,,$(shell uname -s)),BSD or other,Linux)
    

    另一种是只依赖shell条件:

    platform := $(shell [ $$(uname) = Linux ] && echo Linux || echo BSD or other)
    

    GNU make conditionals也可以使用:

    ifeq ($(shell uname -s),Linux)
        platform := Linux
    else
        platform := BSD or other
    endif
    

    【讨论】:

    • 注意 != 在 4.0 版中被添加到 GNU make 中。它不适用于旧版本。
    【解决方案2】:

    使用此解决方案前请注意

    Renaud Pacalet 的赞美:您分配给make 变量的是shell 命令,而不是shell 执行它们的结果。这将严重限制您对它们的使用(基本上是食谱)。您将无法将它们用作目标、先决条件、其他变量定义、make 条件的条件。

    扩展 MadScientist 的评论

    我引用:

    注意!= 在 4.0 版中添加到 GNU make。它不适用于旧版本。

    并且还简化了一堆不必要的ifs,我们可以像下面的方法一样在可能所有版本的GNU和BSD make上获得一个工作版本。

    通过 shell 的另一种方法

    platform_id = $$( uname -s )
    
    platform = $$( \
        case $(platform_id) in \
            ( Linux | FreeBSD | OpenBSD | NetBSD ) echo $(platform_id) ;; \
            ( * ) echo Unrecognized ;; \
        esac )
    

    重要提示:

    • 你需要在这里使用标准的=惰性赋值。使用立即赋值运算符:=,它在 BSD make 中不起作用。

    • 您需要在case 语句中使用( ... )。否则,它将无法在 OpenBSD 上运行


    成功测试:

    我仍在努力使 NetBSD 8.0 在 VirtualBox 中工作,所以我还不能确认这一点。


    需要对这些系统的旧版本进行进一步测试,因此如果您有其中一个明显较旧,请进行测试,谢谢。

    【讨论】:

      猜你喜欢
      • 2017-06-12
      • 1970-01-01
      • 2010-10-01
      • 1970-01-01
      • 2014-04-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多