在同一makefile中配置不同版本
我想使用同一个make文件生成几个构建。我所说的几个版本是指在同一makefile中配置不同版本,makefile,Makefile,我想使用同一个make文件生成几个构建。我所说的几个版本是指windows发行版,windows调试,linux发行版,linux调试,等等。我的想法是根据我正在运行的构建设置变量,如下所示: windows-release: CC:=... CFLAGS:=... OUTDIR:=windows/release OBJDIR:=$(OUTDIR)/obj EXECUTABLE:=$(OUTDIR)/exe # Would call $(EXECU
windows发行版
,windows调试
,linux发行版
,linux调试
,等等。我的想法是根据我正在运行的构建设置变量,如下所示:
windows-release:
CC:=...
CFLAGS:=...
OUTDIR:=windows/release
OBJDIR:=$(OUTDIR)/obj
EXECUTABLE:=$(OUTDIR)/exe
# Would call $(EXECUTABLE) here, but it's not procedural
windows-release: CC:=...
windows-release: CFLAGS:=...
windows-release: OUTDIR:=windows/release
windows-release: OBJDIR:=$(OUTDIR)/obj
windows-release: EXECUTABLE:=$(OUTDIR)/exe
windows-debug: CC:=...
windows-debug: CFLAGS:=...
windows-debug: OUTDIR:=windows/debug
windows-debug: OBJDIR:=$(OUTDIR)/obj
windows-debug: EXECUTABLE:=$(OUTDIR)/exe
linux-release: CC:=...
linux-release: CFLAGS:=...
linux-release: OUTDIR:=linux/release
linux-release: OBJDIR:=$(OUTDIR)/obj
linux-release: EXECUTABLE:=$(OUTDIR)/bin
linux-debug: CC:=...
linux-debug: CFLAGS:=...
linux-debug: OUTDIR:=linux/debug
linux-debug: OBJDIR:=$(OUTDIR)/obj
linux-debug: EXECUTABLE:=$(OUTDIR)/bin
.SECONDEXPANSION:
windows-release windows-debug linux-release linux-debug: $$(EXECUTABLE)
然后有规则来进行实际构建:
# This will generate a static library
$(EXECUTABLE): $(OBJECTS)
$(AR) $(ARFLAGS) $(ARLIB) $(OBJECTS)
$(OBJDIR)/%.o: src/%.cpp
$(CC) $(CFLAGS) $< -o $@
#这将生成一个静态库
$(可执行文件):$(对象)
$(AR)$(ARFLAGS)$(ARLIB)$(对象)
$(OBJDIR)/%.o:src/%.cpp
$(CC)$(CFLAGS)$<-o$@
对于这个不完整的示例,我很抱歉,但是我还没有真正的makefile,我现在正在编写它
我可以使用makefile来完成这项工作吗?我更适合用脚本来代替吗?你完全可以这样做。您需要的三件事是(因此make不认为windows release等是真实的文件),(因此您可以根据运行的目标设置不同的变量),并且因为前提条件的计算发生在特定于目标的上下文之外,因此特定于目标的变量不起作用) 这两个组合会让你得到这样的结果:
windows-release:
CC:=...
CFLAGS:=...
OUTDIR:=windows/release
OBJDIR:=$(OUTDIR)/obj
EXECUTABLE:=$(OUTDIR)/exe
# Would call $(EXECUTABLE) here, but it's not procedural
windows-release: CC:=...
windows-release: CFLAGS:=...
windows-release: OUTDIR:=windows/release
windows-release: OBJDIR:=$(OUTDIR)/obj
windows-release: EXECUTABLE:=$(OUTDIR)/exe
windows-debug: CC:=...
windows-debug: CFLAGS:=...
windows-debug: OUTDIR:=windows/debug
windows-debug: OBJDIR:=$(OUTDIR)/obj
windows-debug: EXECUTABLE:=$(OUTDIR)/exe
linux-release: CC:=...
linux-release: CFLAGS:=...
linux-release: OUTDIR:=linux/release
linux-release: OBJDIR:=$(OUTDIR)/obj
linux-release: EXECUTABLE:=$(OUTDIR)/bin
linux-debug: CC:=...
linux-debug: CFLAGS:=...
linux-debug: OUTDIR:=linux/debug
linux-debug: OBJDIR:=$(OUTDIR)/obj
linux-debug: EXECUTABLE:=$(OUTDIR)/bin
.SECONDEXPANSION:
windows-release windows-debug linux-release linux-debug: $$(EXECUTABLE)
也就是说,你也可以用普通的全局变量和条件来代替:
ifeq (windows-release,$(filter windows-release,$(MAKECMDGOALS)))
CC:=...
CFLAGS:=...
OUTDIR:=windows/release
OBJDIR:=$(OUTDIR)/obj
EXECUTABLE:=$(OUTDIR)/exe
else ifeq (windows-debug,$(filter windows-debug,$(MAKECMDGOALS)))
CC:=...
CFLAGS:=...
OUTDIR:=windows/debug
OBJDIR:=$(OUTDIR)/obj
EXECUTABLE:=$(OUTDIR)/exe
else ifeq (linux-release,$(filter linux-release,$(MAKECMDGOALS)))
CC:=...
CFLAGS:=...
OUTDIR:=linux/release
OBJDIR:=$(OUTDIR)/obj
EXECUTABLE:=$(OUTDIR)/bin
else ifeq (linux-debug,$(filter linux-debug,$(MAKECMDGOALS)))
CC:=...
CFLAGS:=...
OUTDIR:=linux/debug
OBJDIR:=$(OUTDIR)/obj
EXECUTABLE:=$(OUTDIR)/bin
endif
windows-release windows-debug linux-release linux-debug: $(EXECUTABLE)
请注意,二次扩展是一种全局修改。所有列出的目标都已应用。这可能不重要(事实上,可能是你想要的),但需要注意。绝对!谢谢你的提醒。。不过有两个问题。根据文档:
gnumake还能够为makefile中定义的部分或所有目标启用先决条件(仅)的第二次扩展。
我觉得它毕竟不是全局的,这准确吗?它只发生一次吗?我的意思是,你的例子有四个变化,但是文档中谈到了第二次扩展。下一句解释了这句话,我已经指出:为了第二次扩展的发生,特殊目标。第二次扩展必须在使用此功能的第一个先决条件列表之前定义。
下一段第一句的部分内容进一步说明了这一点第二次扩展特殊目标后定义的目标的所有先决条件。
。您可以这样做,将它们全部扩展默认情况下,当且仅当它们不共享任何对象文件或可执行文件时生成。使用特定于目标的变量构建的任何内容都不能在这些目标之间共享。因为make只会构建任何目标一次。因此,任何共享的目标都将由第一个需要它们的对象构建,而不会在下一个目标(使用不同标志)需要时重新构建。