make wildcard subdirectory targets

后端 未结 3 897
南笙
南笙 2021-02-02 11:57

I have a \"lib\" directory in my applications main directory, which contains an arbitrary number of subdirectories, each having its own Makefile.

I would like to have a

3条回答
  •  时光取名叫无心
    2021-02-02 12:22

    There is also a way of listing sub-directories with gmake commands only, without using any shell commands:

    test:
      @echo $(filter %/, $(wildcard lib/*/))
    

    This will list all sub-directories with trailing '/'. To remove it you can use the substitute pattern:

    subdirs = $(filter %/, $(wildcard lib/*/))
    test:
      @echo $(subdirs:%/=%)
    

    Then to actually create rules executing makefiles in each sub-directory you can use a small trick - a phony target in a non-existent directory. I think in this case an example will tell more than any explanation:

    FULL_DIRS =$(filter %/, $(wildcard lib/*/))
    LIB_DIRS  =$(FULL_DIRS:%/=%)
    DIRS_CMD  =$(foreach subdir, $(LIB_DIRS), make-rule/$(subdir))
    
    make-rule/%:
      cd $* && $(MAKE)
    
    all: DIRS_CMD
    

    Basically, target 'all' lists all sub-directories as prerequisites. For example, if LIB_DIRS contained lib/folder1 lib/folder2 then the expansion would look like this:

    all: make-rule/lib/folder1 make-rule/lib/folder2
    

    Then 'make', in order to execute rule 'all', tries to match each prerequisite with an existing target. In this case the target is 'make-rule/%:', which uses '$*' to extract the string after 'make-rule/' and uses it as argument in the recipe. For example, the first prerequisite would be matched and expanded like this:

    make-rule/lib/folder1:
      cd lib/folder1 && $(MAKE)
    

提交回复
热议问题