2017-04-03 51 views
4

鉴于我有一个简单的Makefile中像这样一个项目:如何分离不同配置的Makefile构建输出?

all: foobar 
foobar: foo.o bar.o 

,我可以建立针对不同的架构:

$ CC=clang make     # or 
$ CC=x86_64-w64-mingw32-gcc make # or 
$ CC=arm-linux-gnueabihf-gcc make 

这工作,但我希望能够保持多路输出同时配置,例如在构建服务器上。

什么是一个很好的,干净的方式去做这件事?我已经考虑了以下几点:

  • 使用自动工具或其他构建工具,但我想看看有什么可以不
  • 创建建立与生成文件目录,在他们VPATH设置,包括根Makefile文件
  • 写在构建每个体系结构后移动输出的脚本
  • 修改Makefile以构建多个配置。我不喜欢这个解决方案,因为你最终会遇到一种复杂的元文件,它与你的特定的编译环境紧密耦合。
  • 向Makefile添加一个变量来设置输出目录。这可以工作,但这意味着我不能使用隐式的Makefile规则。模式的规则将变得混乱太
+0

,你的意思是对象,或者只是最终的可执行文件?通常的做法是将$(OBJDIR)设置为对象的输出目录,并且可以根据构建配置有条件地设置它。隐式规则很容易重写,尽管你必须首先创建一个规则来创建$(OBJDIR)。 – blackghost

+0

我认为你应该对每个架构使用不同的目标(包含目录)。说'arm/foo','x86_64/foo'和'main/foo'。我建议尽可能简单:) – uzsolt

+0

我认为我会使用@John提到的'$(OBJDIR)'解决方案。我真的希望能做到像'make -f ../Makefile VPATH = ...'这样的东西,但我想它不是。 @uzsoft我不认为Makefile应该具备这些不同环境的知识,而应该是适应性的。因此我的'meta-Makefile'的评论。 –

回答

1

我会用类似的东西去:

# User configuration 
BINARY := hello 
SOURCES := main.c 

# Create the output paths 
out  ?= out 
outdir := $(out)/$(CC) 
outbin := $(outdir)/$(BINARY) 
objects := $(outdir)/$(SOURCES:.c=.o) 

# Default target 
all: $(outbin) 

# Binary target 
$(outbin): $(objects) 
    $(CC) -o [email protected] $^ 

# Objects target 
$(objects): $(outdir)/%.o: %.c 
    mkdir -p $(@D) 
    $(CC) -o [email protected] -c $< 

# The cleanning targets 
clean: 
    $(RM) -r $(outdir) 

mrproper: 
    $(RM) -r $(out) 

# Declare phony targets 
.PHONY: all clean mrproper 

注意,目标是利用static pattern的对象能够得到在当前目录和对象的源文件输出目录中的文件。


它也容易作为基本Makefile使用方法:当你说你要保存的输出

$ make 
mkdir -p out/cc 
cc -o out/cc/main.o -c main.c 
cc -o out/cc/hello out/cc/main.o 

$ make 
make: Nothing to be done for 'all'. 

$ tree 
. 
├── main.c 
├── Makefile 
└── out 
    └── cc 
     ├── hello 
     └── main.o 

2 directories, 4 files 

$ CC=gcc make 
mkdir -p out/gcc 
gcc -o out/gcc/main.o -c main.c 
gcc -o out/gcc/hello out/gcc/main.o 

$ tree 
. 
├── main.c 
├── Makefile 
└── out 
    ├── cc 
    │   ├── hello 
    │   └── main.o 
    └── gcc 
     ├── hello 
     └── main.o 

3 directories, 6 files 
+0

感谢您的详细解答。我认为这是我将要进入的方向。如果在此期间没有其他新颖的想法出现,我会在稍后将此标记为答案。 –

+0

虽然有一个后续问题:是否可以在经典后缀语法中执行'obj /%。o:%.c'规则? –

+0

@SijmenMulder是的,我相信你可以。我更喜欢这种符号,因为它只对你指定的目标有效。 – jml

相关问题