7

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

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

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

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


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

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


我需要一个适用于 BSDmake和 GNU的解决方案make

4

2 回答 2

12

!=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 make。

一种可能性是使用ifGNU make 函数

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

另一种是仅依赖于 shell 条件:

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

也可以使用GNU make 条件:

ifeq ($(shell uname -s),Linux)
    platform := Linux
else
    platform := BSD or other
endif
于 2018-10-21T06:18:27.110 回答
2

使用此解决方案之前请注意

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

扩展MadScientist的评论

我引用:

!=GNU make 版本 4.0 中添加了注释。它不适用于旧版本。

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

通过外壳的另一种方法

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 中工作,所以我还不能确认这一点。


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

于 2018-10-23T08:42:23.773 回答