如何为不同的配置分离Makefile构建输出?

时间:2017-04-03 09:10:53

标签: c++ c makefile continuous-integration gnu-make

鉴于我有一个简单的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

这有效,但我希望能够同时维护多个配置的输出,例如在构建服务器上。

这会是一个好的,干净的方式吗?我考虑过以下几点:

  • 使用autotools或其他构建工具,但我想看看没有
  • 的可能性
  • 使用Makefile创建构建目录,其中包含设置VPATH并包含根Makefile
  • 编写一个在构建每个架构后移动输出的脚本
  • 修改Makefile以构建多个配置。我不喜欢这个解决方案,因为你最终得到了一种复杂且与你的特定构建环境紧密耦合的元Makefile
  • 将一个变量添加到Makefile以设置输出目录。这可能有效,但这意味着我无法使用隐式Makefile规则。模式规则也会变得混乱

1 个答案:

答案 0 :(得分:2)

我会选择类似的东西:

# 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 $@ $^

# Objects target
$(objects): $(outdir)/%.o: %.c
    mkdir -p $(@D)
    $(CC) -o $@ -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