为不同目录中的不同系统配置make以生成对象



目前我正在使用这个makefile:

CFLAGS=-g -Wall
SRCS=foo.c bar.c main.c
OBJS=$(subst .c,.o,$(SRCS))
linux: CC=gcc
linux: OUTPUT=a.out
windows: CC=x86_64-w64-mingw32-gcc
windows: OUTPUT=a.exe
%.o: %.c
$(CC) $(CFLAGS) -c $< 
linux: $(OBJS)
$(CC) $(OBJS) -o $(OUTPUT)
windows: $(OBJS)
$(CC) $(OBJS) -o $(OUTPUT)
clean:
${RM} a.out a.exe *.o

我可以用它来构建带有make windowsmake linux的程序。但是,由于所有的对象文件都是在同一个目录中创建的,我无法在不必make clean目录的情况下构建windows版本和linux版本。

所以我想在一个子目录中构建windows对象,在另一个子目录下构建linux对象。我已经尝试修改如下所示的makefile,但我无法使其工作。

$ make linux
gcc obj/linux/foo.o obj/linux/bar.o obj/linux/main.o -o a.out
gcc: error: obj/linux/foo.o: No such file or directory
gcc: error: obj/linux/bar.o: No such file or directory
gcc: error: obj/linux/main.o: No such file or directory
gcc: fatal error: no input files
compilation terminated.
make: *** [Makefile:19: linux] Error 1
CFLAGS=-g -Wall
SRCS=foo.c bar.c main.c
OBJS=$(subst .c,.o,$(SRCS))
DIR=obj/subdir/
OBJSDIR:=$(addprefix $(DIR), $(OBJS))
linux: CC=gcc
linux: OUTPUT=a.out
linux: OBJECTS=$(subst subdir,linux,$(OBJSDIR))
windows: CC=x86_64-w64-mingw32-gcc
windows: OUTPUT=a.exe
windows: OBJECTS=$(subst subdir,windows,$(OBJSDIR))
%.o: %.c
$(CC) $(CFLAGS) -c $< 
linux: $(OBJECTS)
$(CC) $(OBJECTS) -o $(OUTPUT)
windows: $(OBJECTS)
$(CC) $(OBJECTS) -o $(OUTPUT)
clean:
${RM} a.out a.exe *.o

这里有很多东西不起作用。

首先,在您更改后,模式%.o : %.c不再匹配,因为词干现在是obj/subdir/foo,而没有obj/subdir/foo.c。而且,这个配方并没有告诉编译器将输出文件放在哪里,所以它将使用默认位置。因此,这种模式需要:

$(DIR)%.o : %.c
$(CC) $(CFLAGS) -c -o $@ $<

但这仍然不起作用,因为您错过了目标特定变量文档中的一个关键限制:它们在配方中生效。您正试图使用特定于目标的变量更改目标的先决条件;那行不通。

有很多方法可以处理这种情况,但最简单的方法是使用递归,如下所示:

...
DIR = obj/$(SUBDIR)/
...
linux:
$(MAKE) a.out CC=gcc OUTPUT=a.out SUBDIR=linux
windows:
$(MAKE) a.exe CC=x86_64-w64-mingw32-gcc OUTPUT=a.exe SUBDIR=windows
$(OUTPUT): $(OBJECTS)
$(CC) $^ -o $@

最新更新