Shell 具有动态目标列表的Makefile

Shell 具有动态目标列表的Makefile,shell,makefile,Shell,Makefile,我将检查一些工具在比较其相对性能的测试数据和脚本上是否都具有正确(并且相同)的行为。我的想法是,如果我的学生可以把他们的源代码放在一个特定的目录中,然后所有的脚本都会被应用到这个目录中——我可以通过把它们放在我的目录副本中来组合他们的所有解决方案 我已经对它进行了设置,如果您将一个名称以\u src结尾的目录放在一个特定的目录中,并且这个目录中有一个Makefile,那么源代码将包含在构建中。不过,我实现它的方式基本上只是Makefile中的一个shell脚本 mappers=$(wildcar

我将检查一些工具在比较其相对性能的测试数据和脚本上是否都具有正确(并且相同)的行为。我的想法是,如果我的学生可以把他们的源代码放在一个特定的目录中,然后所有的脚本都会被应用到这个目录中——我可以通过把它们放在我的目录副本中来组合他们的所有解决方案

我已经对它进行了设置,如果您将一个名称以
\u src
结尾的目录放在一个特定的目录中,并且这个目录中有一个Makefile,那么源代码将包含在构建中。不过,我实现它的方式基本上只是Makefile中的一个shell脚本

mappers=$(wildcard *_src)

all:
    echo $(mappers)
    for m in $(mappers); do                               \
        mapper_name=`basename $$m _src`                  ;\
        echo $$mapper_name                               ;\
        (cd $$m && make)                                 ;\
        if [ ! -e $$mapper_name ]; then                   \
            cp $$m/$$mapper_name $$mapper_name           ;\
        fi                                               ;\
        if [ $$m/$$mapper_name -nt $$mapper_name ]; then  \
            cp $$m/$$mapper_name $$mapper_name           ;\
        fi                                               ;\
    done                                                 ;\
    for m in $(mappers); do                               \
        mapper_name=`basename $$m _src`                  ;\
        if [ ! -x $$mapper_name ]; then                   \
          echo "Hey! where did $${mapper_name} go?"      ;\
            exit 1                                       ;\
        fi                                               ;\
    done
我确信一定有一种更聪明的方法可以在Makefile中包含子目录,并且可以自动检测到它们,但我对
Make
的了解远远超出了简单的设置


我正在考虑制作一个脚本来更新我的Makefile,类似于
makedependens
的工作方式,但我不确定这是否是最好的解决方案。

类似的东西可能会工作——对于每个_src目录,它创建一个_build目录,复制文件,然后从_build目录生成。完成后,它会触摸_build/.build文件以标记完成:

src_Makefiles=$(wildcard *_src/Makefile)     # Makefiles in source
src_dirs=$(src_Makefiles:/Makefile=)         # source directories
build_dirs=$(src_dirs:_src=_build)           # build directories
built_files=$(build_dirs:=/.built)           # build done files

#default target, which builds everything:    
all: $(built_files)

#for debugging only -- lets you know if you've made a mistake:
$(info built_files=$(built_files))

# the following creates a _build directory for every _src directory.

$(build_dirs) : %_build : %_src
        @echo updating $@
        @rm -rf $@     # remove any artifacts from previous builds...
        @mkdir -p $@   # make the directory
        @cp -r $@ $^   # copy the entire contents of _src to build.


# The following is the rule to build each directory.
# Each built file depends on the _src directory (which
# has a timestamp of the latest modified file -- so it
# will rebuild only if the student has modified something
# since the last build)
$(built_files): %_build/.built : %_build
        @echo building $(dir $@)
        @echo "run make -C $(dir $@)"
        touch $@

clean:
        rm -rf *_build

您也可能会发现这个问题(以及整个社区!)很有趣: