Makefile (запускать внешние скрипты с макросами makefile) - PullRequest
1 голос
/ 07 ноября 2011

У меня есть несколько целей .PHONY, таких как 'clean', 'backup' и 'help'
правило для некоторых из этих целей очень велико.
Например:

   .PHONY: backup
    backup:
        @$(GREEN)
        @mkdir -p backup/include #make an backup include folder if it doesn't already exist
        @mkdir -p backup/src     #make a backup src folder if it doesn't already exist
        @mkdir -p backup/docs    #make a backup docs folder if it doesn't already exist

        @total=0; headerCount=0; sourceCount=0; documentCount=0; \
        for file in $(HEADER_PATH)*; do \
            if ls $$file[~] >/dev/null 2>&1; then \
                mv -fu $$file[~] backup/$$file; \
                let "headerCount+=1"; \
                echo $(DATE)[Backed Up] $$file~ >> $(LOG); \
            fi; \
        done; \
        for file in $(SOURCE_PATH)*; do \
            if ls $$file[~] >/dev/null 2>&1; then \
                mv -fu $$file[~] backup/$$file; \
                let "sourceCount+=1"; \
                echo $(DATE)[Backed Up] $$file~ >> $(LOG); \
            fi; \
        done; \
        for file in $(DOC_PATH)*; do \
            if ls $$file[~] >/dev/null 2>&1; then \
                mv -fu $$file[~] backup/$$file; \
                let "documentCount+=1"; \
                echo $(DATE)[Backed Up] $$file~ >> $(LOG); \
            fi; \
        done; \
        let "total= headerCount + sourceCount + documentCount"; \
        echo -n $(OUTPUT_PROMPT)" "; \
        if test $$total -eq 0; then \
            echo Nothing To Back up; \
        else \
            if test $$headerCount -eq $$total; then \
                echo -n $$total" "; \
                echo -n "Header"; \
                if test $$total -ge 2; then \
                    echo -n "s"; \
                fi; \
                echo " Backed Up"; \
            elif test $$sourceCount -eq $$total; then \
                echo -n $$total" "; \
                echo -n "Source"; \
                if test $$total -ge 2; then \
                    echo -n "s"; \
                fi; \
                echo " Backed Up"; \
            elif test $$documentCount -eq $$total; then \
                echo -n $$total" "; \
                echo -n "Document"; \
                if test $$total -ge 2; then \
                    echo -n "s"; \
                fi; \
                echo " Backed Up"; \
            else \
                $(UNDERLINE); echo $$total " Files Backed Up"; $(UNUNDERLINE); \
                if test $$headerCount -eq 1; then \
                    echo $(OUTPUT_PROMPT)" "$$headerCount header; \
                elif test $$headerCount -ge 2; then \
                    echo $(OUTPUT_PROMPT)" "$$headerCount headers; \
                fi; \
                if test $$sourceCount -eq 1; then \
                    echo $(OUTPUT_PROMPT)" "$$sourceCount source; \
                elif test $$sourceCount -ge 2; then \
                    echo $(OUTPUT_PROMPT)" "$$sourceCount sources; \
                fi; \
                if test $$documentCount -eq 1; then \
                    echo $(OUTPUT_PROMPT)" "$$documentCount document; \
                elif test $$documentCount -ge 2; then \
                    echo $(OUTPUT_PROMPT)" "$$documentCount documents; \
                fi; \
            fi; \
        fi;
        @$(DEFAULT_TEXT)

то, что делает код, не важно, но я хотел бы проиллюстрировать, что в нем есть макросы, в которых «make» должен расширяться, и что он также выполняет код оболочки (bash), и что некоторые указания на то, что сделал скрипт, отображается в терминале.
Я хочу поместить этот скрипт вне make в другой каталог и превратить этот код в нечто вроде этого:

.PHONY: backup
backup:
    @run scripts/backup.scr
    #or something similar to that

Как я могу поместить правило моей цели (то есть makefile / bash code) в отдельный файл и сделать так, чтобы make практически вставил его так, чтобы оно работало так, как было у меня изначально?

Я думал, что смогу использовать команду include внутри make.
Похоже, он используется для включения других make-файлов, хотя ..
может быть, мне просто нужно вставить всю цель / правило в другой make-файл, а затем включить этот make-файл в мой основной?
Это будет лучшим способом?

Ответы [ 2 ]

1 голос
/ 08 ноября 2011

В вашем случае у вас довольно мало выходных переменных. Возможно, стоит разделить генерацию и выполнение, например:

clean : clean-script
    sh clean-script
    rm -f clean-script

clean-script : clean-script.in
     sed -e 's:[@]HEADER_PATH[@]:$(HEADER_PATH):g' $<.in > $@

И напишите clean-script.in как чистый скрипт sh с несколькими заменами. Если вы используете GNU make, вы, конечно, можете создать список выходных переменных, например:

clean-script : clean-script.in
     sed $(foreach var,$(SUBSTVARS),-e 's:[@]$(var)[@]:$($(var)):g') $<.in > $@
1 голос
/ 08 ноября 2011

Я не знаю, может ли это помочь вам, но вы можете запустить make внутри некоторого Makefile, как правило, с помощью команды (внутри правила), например,

       $(MAKE) subtarget

См. Раздел Рекурсивное использование Make в документации GNU make.

Мне не нравится использовать make для сложных проектов (но, к сожалению, я должен). Если вы можете выбрать какой-либо другой инструмент, вы можете рассмотреть omake и многие другие (cmake, scons, bake, ...)

...