Sources from subdirectories in Makefile

后端 未结 7 1282
无人共我
无人共我 2020-11-29 19:06

I have a C++ library built using a Makefile. Until recently, all the sources were in a single directory, and the Makefile did something like this

SOURCES = $(w

相关标签:
7条回答
  • 2020-11-29 19:46

    Recursive wildcards can be done purely in Make, without calling the shell or the find command. Doing the search using only Make means that this solution works on Windows as well, not just *nix.

    # Make does not offer a recursive wildcard function, so here's one:
    rwildcard=$(wildcard $1$2) $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2))
    
    # How to recursively find all files with the same name in a given folder
    ALL_INDEX_HTMLS := $(call rwildcard,foo/,index.html)
    
    # How to recursively find all files that match a pattern
    ALL_HTMLS := $(call rwildcard,foo/,*.html)
    

    The trailing slash in the folder name is required. This rwildcard function does not support multiple wildcards the way that Make's built-in wildcard function does, but adding that support would be straightforward with a couple more uses of foreach.

    0 讨论(0)
  • 2020-11-29 19:49

    If you don't want to use recursive makefiles, this might give you some ideas:

    subdirs := $(wildcard */)
    sources := $(wildcard $(addsuffix *.cpp,$(subdirs)))
    objects := $(patsubst %.cpp,%.o,$(sources))
    
    $(objects) : %.o : %.cpp
    
    0 讨论(0)
  • 2020-11-29 19:51

    You can use several rules in wildcard:

    SOURCES := $(wildcard *.cpp */*.cpp)
    

    if you need more depth:

    SOURCES := $(wildcard *.cpp */*.cpp */*/*.cpp */*/*/*.cpp)
    

    Unfortunately, and unlike what we sometimes read, glob (**) is not supported by makefile and will be interpreted as normal wildcard (*).

    For example **/*.cpp match dir/file.cpp but neither file.cpp nor dir/sub/file.cpp.

    If you need infinite depth use shell:

    SOURCES := $(shell find . -name "*.cpp")
    
    0 讨论(0)
  • 2020-11-29 19:55

    If you can use find shell command, you may define a function to use it.

    recurfind = $(shell find $(1) -name '$(2)')
    SRCS := $(call recurfind,subdir1,*.c) $(call recurfind,subdir2,*.cc) $(call recurfind,subdir2,*.cu) \
            ...
    
    0 讨论(0)
  • 2020-11-29 19:57

    Common practice is to put a Makefile in each subdir with sources, then

    all: recursive
        $(MAKE) -C componentX
        # stuff for current dir
    

    or

    all: recursive
        cd componentX && $(MAKE)
        # stuff for current dir
    
    recursive: true
    

    It may be wise to put settings for each Makefile in a Makefile.inc in the root source directory. The recursive target forces make to go into the subdirectories. Make sure that it doesn't recompile anything in a target requiring recursive.

    0 讨论(0)
  • 2020-11-29 20:04

    This is a side note and do not answer to your question but there is a paper "Recursive Make Considered Harmful". It's worth reading.

    Here is the link. http://aegis.sourceforge.net/auug97.pdf

    0 讨论(0)
提交回复
热议问题