일부 디렉토리에는 메이크 파일이 포함되어 있고 일부 메이크 파일에는 clean
타겟이 있습니다. 상위 디렉토리에 간단한 스크립트가 있습니다.
#!/bin/bash
for f in *; do
if [[ -d $f && -f $f/makefile ]]; then
echo "Making clean in $f..."
make -f $f/makefile clean
fi
done
이것은 (정의 된) "깨끗한"대상이없는 메이크 파일이있는 디렉토리에 도달 할 때 이상한 일을합니다. 예를 들어, 두 개의 디렉토리 one
및 two
,
하나 / 메이크 파일
clean:
-rm *.x
두 / 메이크 파일
clean:
두 번째 경우 "clean"은 지시문없이 존재하므로 "make clean"을 실행 two
하면 다음과 같은 결과를 얻을 수 있습니다.
make: Nothing to be done for `clean'.
"clean"이없는 경우와 비교 :
make: *** No rule to make target `clean'. Stop.
그러나 설명하려는 문제의 경우 대상이 있지만 정의되지 않았거나 존재하지 않는 경우 결과는 동일합니다. clean.sh
상위 디렉토리에서 실행 ;
Making clean in one...
rm *.x
rm: cannot remove `*.x': No such file or directory
make: [clean] Error 1 (ignored)
그래서 one
청소가 필요하지 않았습니다. 별거 아니에요, 예상대로입니다. 하지만:
Making clean in two...
cat clean.sh >clean
chmod a+x clean
왜 cat clean.sh>clean
등? 참고 : 위에 표시된대로 정확히 최소한의 예제를 만들었습니다. 주변에 다른 파일이나 디렉토리가 없습니다 (clean.sh, 디렉토리 1과 2, 아주 최소한의 메이크 파일). 그러나 clean.sh가 실행 된 후 make
복사 clean.sh > clean
하여 실행 가능하게 만들었습니다. 그런 다음 clean.sh를 다시 실행하면 :
Making clean in one...
make: `clean' is up to date.
Making clean in two...
make: `clean' is up to date.
Press any key to continue...
지금은 지정된 메이크 파일을 전혀 사용하지 않기 때문에 더 이상한 것입니다. "최신"미스터리 타겟을 사용하고 있습니다.
아마도 관련된 현상을 발견했습니다. clean.sh에서 테스트 절 중 하나를 다음과 같이 제거하면 :
# if [[ -d $f && -f $f/makefile ]]; then
if [[ -d $f ]]; then
그리고 three
makefile없이 디렉토리 를 생성합니다 . 출력에는 다음이 포함됩니다.
Making clean in three...
make: three/makefile: No such file or directory
make: *** No rule to make target `three/makefile'. Stop.
내가 이해하는 그러한 파일이나 디렉토리가 없는데 왜 make
그 이름을 가진 대상을 찾습니까? 맨 페이지는 매우 간단합니다.
-f 파일, --file = file, --makefile = FILE
Use file as a makefile.
그 행동은 버그가 아닙니다. 기능입니다. 정확한 기능 및 가능한 사용자 오류.
문제의 기능은 Make의 암시 적 규칙 중 하나입니다. 귀하의 경우 "빌드" *.sh
파일에 대한 암시 적 규칙 입니다. 사용자 오류, 오류는 하위 디렉토리에서 makefile을 호출하기 전에 작업 디렉토리를 변경하지 않습니다.
TL; DR :이 문제를 해결하려면 다음 중 하나 이상을 수행 할 수 있습니다.
쉘 스크립트를 수정하여 작업 디렉토리를 변경하십시오.
#!/bin/bash
for f in *; do
if [[ -d $f && -f $f/makefile ]]; then
echo "Making clean in $f..."
(cd $f; make clean)
fi
done
빈 규칙을 명시 적으로 만듭니다.
clean: ;
clean
표적을 가짜로 만듭니다 .
.PHONY: clean
상해:
Make에는 암시 적 규칙이 많이 있습니다. 이를 통해 makefile을 작성하지 않고도 간단한 프로젝트에서 make를 호출 할 수 있습니다.
데모를 위해 이것을 시도하십시오.
clean.sh
.make clean
산출:
$ make clean
cat clean.sh >clean
chmod a+x clean
BAM! 그것이 묵시적 규칙의 힘입니다. 자세한 내용 은 암시 적 규칙에 대한 make 매뉴얼 을 참조하십시오.
나머지 미해결 질문에 답하려고 노력할 것입니다.
첫 번째 메이크 파일에 대해 암시 적 규칙을 호출하지 않는 이유는 무엇입니까? 암시 적 규칙을 명시 적 규칙으로 덮어 썼기 clean
때문입니다.
clean
두 번째 메이크 파일 의 규칙이 암시 적 규칙을 덮어 쓰지 않는 이유는 무엇 입니까? 레시피가 없었기 때문입니다. 레시피가없는 규칙은 암시 적 규칙을 덮어 쓰지 않고 전제 조건 만 추가합니다. 자세한 내용 은 여러 규칙에 대한 make 매뉴얼 을 참조하십시오. 명시 적으로 비어있는 레시피가있는 규칙에 대한 make 매뉴얼 도 참조하십시오 .
서브 디렉토리에서 메이크 파일을 호출하기 전에 작업 디렉토리를 변경하지 않는 것이 왜 오류입니까? make는 작업 디렉토리를 변경하지 않기 때문입니다. Make는 상속 된 작업 디렉토리에서 작동합니다. 기술적으로 이것은 반드시 오류는 아니지만 대부분의 경우 오류입니다. 하위 디렉터리의 메이크 파일이 하위 디렉터리에서 작동하도록 하시겠습니까? 아니면 부모 디렉터리에서 작동하도록 하시겠습니까?
clean
두 번째 호출에서 make 가 첫 번째 makefile 의 명시 적 규칙을 무시하는 이유는 무엇 clean.sh
입니까? 이제 대상 파일이 clean
이미 존재하기 때문입니다. 규칙 clean
에 전제 조건이 없기 때문에 대상을 다시 빌드 할 필요가 없습니다. 이 문제를 정확히 설명하는 가짜 타겟에 대한 make 매뉴얼을 참조하십시오 .
three/makefile
세 번째 호출에서 대상 을 검색하는 이유는 무엇 입니까? make는 항상 다른 작업을 수행하기 전에 makefile을 다시 만들려고하기 때문입니다. makefile을 사용하여 명시 적으로 요청 -f
했지만 존재하지 않는 경우 특히 그렇습니다 . 자세한 정보는 makefile 재 작성에 대한 make 매뉴얼 을 참조하십시오.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다