Makefile:基于规则的不同变量值

时间:2018-01-29 20:24:18

标签: makefile

我的makefile中出现以下情况:

mvn package

感觉我做错了什么。基本上SDLINC_NOVA = -I/usr/local/lib/sdl_2.0.5/include/SDL2 -D_REENTRANT SDLLIB_NOVA = -L/usr/local/lib/sdl_2.0.5/lib -Wl,-rpath,/usr/local/lib/sdl_2.0.5/lib -Wl,--enable-new-dtags -lSDL2 -lSDL2main SDLINC_MAC = -I/usr/local/SDL/include -D_REENTRANT SDLLIB_MAC = -L/usr/local/SDL/lib -Wl,-rpath,/usr/local/SDL/lib -Wl,-install_name,--enable-new-dtags -lSDL2 -lSDL2main .... .PHONY: all nova mac clean all: nova nova: SDLINC = $(SDLINC_NOVA) nova: SDLLIB = $(SDLLIB_NOVA) nova: build mac: SDLINC = $(SDLINC_MAC) mac: SDLLIB = $(SDLLIB_MAC) mac: build build: $(TARGET) $(TARGET): $(OBJECTS) $(CC) $(OBJECTS) $(SDLLIB) -o $@ $(OBJECTS): $(OBJDIR)/%.o : $(SRCDIR)/%.c $(CC) $(CFLAGS) $(SDLINC) -c $< -o $@ SDLINC变量应根据所调用的规则包含不同的值,然后是SDLLIB规则应该被称为。

在makefile中实现它的正确约定是什么?

2 个答案:

答案 0 :(得分:1)

基本上,正确的方法是不要为Mac和Linux制定两个不同的规则。这是因为这两个系统都是基于Unix的系统并且很常见。

方法是自动检测您正在运行的系统,这可以使用uname shell命令完成:

 OS := $(shell uname)
 ifeq ($(OS), Darwin)
        OS := mac
 else ifeq ($(OS), Linux)
        OS := linux
 else
        $(info Warning: unknown OS, assuming linux)
        OS := linux
 endif

然后只需添加ifeq条件来分配变量:

ifeq ($(OS), linux)
    SDLINC = $(SDLINC_NOVA)
    SDLLIB = $(SDLLIB_NOVA)
else ifeq ($(OS), mac)
    SDLINC = $(SDLINC_MAC)
    SDLLIB = $(SDLLIB_MAC)
endif

并删除macnova的规则,现在只需要一个build规则。

您可以检查Nova计算机上uname命令的输出是什么,并在makefile中相应地进行调整,但我非常确定它是Linux

答案 1 :(得分:0)

问题是build目标是novamac常见先决条件。因此,目标build的规则仅匹配一次。也就是说,它匹配需要它的第一个目标,然后它仍然需要更新第二个目标。

您可以设置您的makefile,以便上述目标取决于不同的先决条件:

nova: SDLINC = $(SDLINC_NOVA)
nova: SDLLIB = $(SDLLIB_NOVA)
nova: build-nova

mac: SDLINC = $(SDLINC_MAC)
mac: SDLLIB = $(SDLLIB_MAC)
mac: build-mac

使用此新设置,mac取决于build-mac,而nova取决于build-nova

然后,通过添加以下规则:

build-nova build-mac:
    $(MAKE) --no-print-directory $(TARGET)

将为每个目标执行其配方(即:build-novabuild-mac单独

该规则的作用是为递归调用make指定的目标(即:展开TARGET的结果)。但是,您需要在makefile中导出SDLINCSDLLIB变量,以便运行make的新进程获得它们:

export SDLINC
export SDLLIB