鉴于我有一个简单的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以构建多个配置.我不喜欢这个解决方案,因为你最终得到了一种复杂且紧密耦合到你的特定构建环境的meta-Makefile
>将一个变量添加到Makefile以设置输出目录.这可能有效,但这意味着我不能使用隐式Makefile规则.模式规则也会变得混乱
最佳答案 我会选择这样的东西:
# 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