Create directories using make file

前端 未结 9 2073
情深已故
情深已故 2020-11-28 21:27

I\'m a very new to makefiles and i want to create directories using makefile. My project directory is like this

+--Project  
   +--output  
   +--source  
           


        
9条回答
  •  伪装坚强ぢ
    2020-11-28 22:06

    OS independence is critical for me, so mkdir -p is not an option. I created this series of functions that use eval to create directory targets with the prerequisite on the parent directory. This has the benefit that make -j 2 will work without issue since the dependencies are correctly determined.

    # convenience function for getting parent directory, will eventually return ./
    #     $(call get_parent_dir,somewhere/on/earth/) -> somewhere/on/
    get_parent_dir=$(dir $(patsubst %/,%,$1))
    
    # function to create directory targets.
    # All directories have order-only-prerequisites on their parent directories
    # https://www.gnu.org/software/make/manual/html_node/Prerequisite-Types.html#Prerequisite-Types
    TARGET_DIRS:=
    define make_dirs_recursively
    TARGET_DIRS+=$1
    $1: | $(if $(subst ./,,$(call get_parent_dir,$1)),$(call get_parent_dir,$1))
        mkdir $1
    endef
    
    # function to recursively get all directories 
    #     $(call get_all_dirs,things/and/places/) -> things/ things/and/ things/and/places/
    #     $(call get_all_dirs,things/and/places) -> things/ things/and/
    get_all_dirs=$(if $(subst ./,,$(dir $1)),$(call get_all_dirs,$(call get_parent_dir,$1)) $1)
    
    # function to turn all targets into directories
    #     $(call get_all_target_dirs,obj/a.o obj/three/b.o) -> obj/ obj/three/
    get_all_target_dirs=$(sort $(foreach target,$1,$(call get_all_dirs,$(dir $(target)))))
    
    # create target dirs
    create_dirs=$(foreach dirname,$(call get_all_target_dirs,$1),$(eval $(call make_dirs_recursively,$(dirname))))
    
    TARGETS := w/h/a/t/e/v/e/r/things.dat w/h/a/t/things.dat
    
    all: $(TARGETS)
    
    # this must be placed after your .DEFAULT_GOAL, or you can manually state what it is
    # https://www.gnu.org/software/make/manual/html_node/Special-Variables.html
    $(call create_dirs,$(TARGETS))
    
    # $(TARGET_DIRS) needs to be an order-only-prerequisite
    w/h/a/t/e/v/e/r/things.dat: w/h/a/t/things.dat | $(TARGET_DIRS)
        echo whatever happens > $@
    
    w/h/a/t/things.dat: | $(TARGET_DIRS)
        echo whatever happens > $@
    

    For example, running the above will create:

    $ make
    mkdir w/
    mkdir w/h/
    mkdir w/h/a/
    mkdir w/h/a/t/
    mkdir w/h/a/t/e/
    mkdir w/h/a/t/e/v/
    mkdir w/h/a/t/e/v/e/
    mkdir w/h/a/t/e/v/e/r/
    echo whatever happens > w/h/a/t/things.dat
    echo whatever happens > w/h/a/t/e/v/e/r/things.dat
    

提交回复
热议问题