我的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中实现它的正确约定是什么?
答案 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
并删除mac
和nova
的规则,现在只需要一个build
规则。
您可以检查Nova计算机上uname
命令的输出是什么,并在makefile中相应地进行调整,但我非常确定它是Linux
。
答案 1 :(得分:0)
问题是build
目标是nova
和mac
的常见先决条件。因此,目标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-nova
和build-mac
)单独。
该规则的作用是为递归调用make
指定的目标(即:展开TARGET
的结果)。但是,您需要在makefile中导出SDLINC
和SDLLIB
变量,以便运行make
的新进程获得它们:
export SDLINC
export SDLLIB