我有一个具有以下结构的项目
Top Level Project Dir
->Other Source Code Folders
->Experiment Binaries
->Experiment 1
-srcs.cpp
-main.cpp
-Makefile
->Experiment 2
-srcs.cpp
-main.cpp
-Makefile
该项目由多个实验组成,这些实验被编译成自己的二进制文件。这些实验由顶层目录中的源以及位于实验文件夹中的一些特定源组成。实验名称是唯一的,并且映射到文件夹名称。目前,为了制作特定的实验二进制文件,我将CD放入expeirment目录并运行“ Make”。我使用的这种结构变得难以管理,因为我进行了越来越多的实验,因为所有Makefile基本上都是相同的,如果最终更改了共享通用代码中的某些依赖项,那么我需要更新所有Makefile。我想将makefile统一为位于ExperimentBinaries文件夹级别的单个文件。运行“制作”将使所有实验将对象放置在相应的文件夹中。然后运行“ Make Experiment1”将进行该特定实验。我不确定如何以这种方式将Makefile放入我们的多个二进制文件。
您可以保留自己的实验Makefile,并在根目录Experiment Binaries
上创建一个,使用C
标志调用每个子Makefile。
make -C Experiment1
make -C Experiment2
这将使用给定路径运行make命令。
或者,如果要删除子Makefile,则可以在根目录使用多个规则创建一个。每个规则将编译给定实验文件夹中的每个文件(您可以使用wildcard
),然后创建所有二进制文件。
实际上:-如果可以将子目录名称假定为不包含空格,则这样做会容易得多。-可靠解决方案的关键是对通配符目标而不是目录使用file。
# Get list of identically structured subdirectories
SUBDIRS:=$(ls)
# Directories have timestamps that subvert the behavior of make.
# So define a new "PHONY" name using a -make suffix.
MAKE_TARGETS=$(addsuffix -make,$(SUBDIRS))
# Top level default target.
all: $(MAKE_TARGETS)
# Each subdirectory target, assume an output "foo/a.out" for timestamp.
$(MAKE_TARGETS): %-make: %/a.out;
.PHONY: $(MAKE_TARGETS)
# Your actual rules, could also use wildcards.
$(addsuffix /a.out,$(SUBDIRS)): %/a.out
#rule for building a.out from cpp files in $* subdirectory
# Other target suffixes can also be defined, like a "clean" target.
CLEAN_TARGETS=$(addsuffix -clean,$(SUBDIRS))
clean: $(CLEAN_TARGETS);
$(CLEAN_TARGETS): %-clean
rm -rf $*/a.out $*/*.o # customize, as needed
.PHONY: $(CLEAN_TARGETS)
help:
echo "The following subdirectories build experiments: $(SUBDIR)"
echo ""
echo "The default target invokes corresponding make targets in each dir"
echo " 'make' #will build the targets in each subdir"
echo "Or for a given folder, use the -make suffix for each folder. For example:"
echo " 'make foo-make' #will build the target for the 'foo' subdirectory"
echo "Likewise: there is a clean target and clean suffix for each subdirectory"
echo " 'make clean' #for all subdirectories"
echo " 'make foo-clean' #for just the 'foo' subdirectory"