如何有条件地为Makefile(BSD + GNU)中的变量赋值?

时间:2018-10-21 04:21:59

标签: makefile conditional gnu-make bsdmake

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

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

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

除Linux外,我新支持* BSD,因此我需要检查在多个地方使用的平台。 Makefile中可以进行条件变量赋值吗?像这样:


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

这当然是行不通的,但是希望您能理解我的意思。


我需要一个可以与BSD make和GNU make一起使用的解决方案。

2 个答案:

答案 0 :(得分:4)

编辑新版本的问题(“ 与BSD make和GNU make一起使用”):

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

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上。

一种可能性是使用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

答案 1 :(得分:1)

使用此解决方案之前要小心

Renaud Pacalet的称赞:给您的make变量分配的是shell命令,而不是shell执行它们的结果。它将严重限制您可以使用它们的用途(基本上仅限于食谱)。您将无法将它们用作目标,前提条件,其他变量定义,make条件的条件。

扩展MadScientist的评论

我引用:

  

注意!=已在4.0版中添加到GNU make。在较旧的版本中将无法使用。

并简化了大量不必要的if,我们可以在可能的所有 版本的GNU和BSD make上获得可用的版本,如下所示。 / p>

通过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中工作,因此我无法确认这一点。


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