[makefile] makefile에 ‘cd’명령을 작성하는 방법

예를 들어, makefile에 다음과 같은 것이 있습니다.

all:
     cd some_directory

그러나 입력 할 때 명령 make과 같이 ‘cd some_directory’만 보았습니다 echo.



답변

실제로 명령을 실행하고 디렉토리를로 변경 some_directory하지만 하위 프로세스 쉘에서 수행되며 작업중 인 쉘이나 쉘에 영향을 미치지 않습니다.

에서 더 많은 작업을 수행 some_directory하려면 세미콜론을 추가하고 다른 명령도 추가해야합니다. 규칙의 끝으로 make로 해석되는 줄 바꿈을 사용할 수 없으므로 명확성을 위해 사용하는 줄 바꿈은 백 슬래시로 이스케이프해야합니다.

예를 들면 다음과 같습니다.

all:
        cd some_dir; echo "I'm in some_dir"; \
          gcc -Wall -o myTest myTest.c

백 슬래시와 개행을 추가하더라도 모든 명령간에 세미콜론이 필요합니다. 이것은 전체 문자열이 쉘에 의해 단일 행으로 구문 분석되기 때문입니다. 주석에서 언급했듯이 ‘&&’를 사용하여 명령을 결합해야합니다. 즉, 이전 명령이 성공한 경우에만 실행됩니다.

all:
        cd some_dir && echo "I'm in some_dir" && \
          gcc -Wall -o myTest myTest.c

cd어떤 이유로 든 실패 하면 잘못된 것을 파괴 할 수 있으므로 정리와 같은 파괴적인 작업을 수행 할 때 특히 중요합니다 .

그러나 일반적인 사용법은 하위 디렉토리에서 make를 호출하는 것입니다. 이에 대한 명령 행 옵션이 있으므로 cd직접 전화 할 필요가 없으므로 규칙은 다음과 같습니다.

all:
        $(MAKE) -C some_dir all

타겟 “all” 로 변경되어 in을 some_dir실행합니다 Makefile. 모범 사례 로서 직접 $(MAKE)호출 하는 대신 make올바른 make 인스턴스를 호출하는 데주의를 기울여야하며 (예를 들어 빌드 환경에 특수한 make 버전을 사용하는 경우) 실행시 약간 다른 동작을 제공해야합니다. 와 같은 특정 스위치 사용 -t.

레코드의 경우 출력이없는 경우에도 make가 명시 적으로 억제하지 않는 한 항상 실행하는 명령을 에코합니다.


답변

에서 시작 GNU 메이크 3.82 (7 월 2010), 당신은 사용할 수있는 .ONESHELL쉘 (굵게 강조 광산)의 단일 인스턴스의 모든 레시피 라인을 실행하는 데 특별한 목표를 :

  • 새로운 특수 대상 : .ONESHELL에 지시가 만들어 호출 쉘의 단일 인스턴스를 하고 그것을 제공하는 전체 조리법 에 관계없이 포함 얼마나 많은 라인. […]
.ONESHELL: # Only applies to all target
all:
    cd ~/some_dir
    pwd # Prints ~/some_dir if cd succeeded


답변

디렉토리를 다루고 만드는 귀여운 트릭이 있습니다. 여러 줄 문자열 또는 “cd;”를 사용하는 대신 각 명령에서 간단한 chdir 함수를 다음과 같이 정의하십시오.

CHDIR_SHELL := $(SHELL)
define chdir
   $(eval _D=$(firstword $(1) $(@D)))
   $(info $(MAKE): cd $(_D)) $(eval SHELL = cd $(_D); $(CHDIR_SHELL))
endef

그런 다음 규칙에 따라 호출하면됩니다.

all:
          $(call chdir,some_dir)
          echo "I'm now always in some_dir"
          gcc -Wall -o myTest myTest.c

다음을 수행 할 수도 있습니다.

some_dir/myTest:
          $(call chdir)
          echo "I'm now always in some_dir"
          gcc -Wall -o myTest myTest.c


답변

일단 도착하면 무엇을 하시겠습니까? 각 명령은 서브 쉘에서 실행되므로 서브 쉘은 디렉토리를 변경하지만 최종 결과는 다음 명령이 여전히 현재 디렉토리에 있다는 것입니다.

GNU make를 사용하면 다음과 같은 작업을 수행 할 수 있습니다.

BIN=/bin
foo:
    $(shell cd $(BIN); ls)


답변

dir을 변경하려면

foo:
    $(MAKE) -C mydir

multi:
    $(MAKE) -C / -C my-custom-dir   ## Equivalent to /my-custom-dir


답변

이처럼 :

target:
    $(shell cd ....); \
    # ... commands execution in this directory
    # ... no need to go back (using "cd -" or so)
    # ... next target will be automatically in prev dir

행운을 빕니다!


답변