문제

나는 Makefile을 만들고 다른 makefile을 호출하는 Makefile이 있습니다. 이 makefile은 실제로 변하지 않는 작업을 수행하는 더 많은 Makefiles를 호출하기 때문입니다. 따라서 프로젝트가 구축되고 최신 날짜라고 계속 생각하고 있습니다.

dnetdev11 ~ # make
make: `release' is up to date.

Makefile을 대상을 재건하도록하려면 어떻게해야합니까?

clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean


build = svn up ~/xxx                                                       \
        $(clean)                                                                \
        ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace        \
        $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1)                    \


release:
        $(build )

debug:
        $(build DEBUG=1)

clean:
        $(clean)

install:
        cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
        cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib

참고 : 무고한 사람을 보호하기 위해 이름이 제거되었습니다

편집 : 최종 고정 버전 :

clean = $(MAKE) -f xxx_compile.workspace.mak clean;


build = svn up;                                         \
        $(clean)                                        \
        ./cbp2mak/cbp2mak -C . xxx_compile.workspace;   \
        $(MAKE) -f xxx_compile.workspace.mak    $(1);   \


.PHONY: release debug clean install

release:
        $(call build,)

debug:
        $(call build,DEBUG=1)

clean:
        $(clean)

install:
        cp ./source/xxx_utillity/release/xxx_util /usr/bin
        cp ./dlls/Release/xxxcore.so /usr/lib
도움이 되었습니까?

해결책

하나 이상의 목표를 선언 할 수 있습니다. 위조품.

가짜 목표는 실제로 파일의 이름이 아닌 목표입니다. 오히려 명시 적 요청을 할 때 레시피를 실행하는 이름 일뿐입니다. 가짜 목표를 사용해야하는 두 가지 이유가 있습니다. 같은 이름의 파일과 충돌을 피하고 성능을 향상시키는 데.

...

가짜 목표는 실제 대상 파일의 전제 조건이되어서는 안됩니다. 그렇다면, 해당 파일을 업데이트 할 때마다 레시피가 실행됩니다. 가짜 대상이 실제 목표의 전제 조건이 아닌 한, 가짜 대상 레시피는 가짜 목표가 지정된 목표 인 경우에만 실행됩니다.

다른 팁

그만큼 -B 긴 형태가있는 사람으로 전환하십시오 --always-make, 말해 make 타임 스탬프를 무시하고 지정된 대상을 만들기 위해. 이것은 Make 사용의 목적을 물리 칠 수 있지만 필요한 것이 될 수 있습니다.

태양 매뉴얼에 문서화 된 한 가지 트릭 make (존재하지 않는) 대상 '.force'를 사용하는 것입니다. 다음을 포함하는 파일 인 force.mk를 만들어 다음을 수행 할 수 있습니다.

.FORCE:
$(FORCE_DEPS): .FORCE

그런 다음 기존 MakeFile이 호출된다고 가정합니다 makefile, 당신은 실행할 수 있습니다 :

make FORCE_DEPS=release -f force.mk -f makefile release

부터 .FORCE 존재하지 않으며, 그에 의존하는 모든 것은 구식이되어 재건 될 것입니다.

이 모든 것은 모든 버전과 함께 작동합니다 make; Linux에서는 GNU 제조업체가 있으므로 논의 된대로 .Phoony Target을 사용할 수 있습니다.

또한 이유를 고려할 가치가 있습니다 make 릴리스가 최신으로 간주됩니다. 이것은 당신이 가지고 있기 때문일 수 있습니다 touch release 실행 된 명령 중에서 명령; '릴리스'라는 파일이나 디렉토리가 존재하고 종속성이 없으므로 최신 상태입니다. 그러면 실제 이유가 있습니다 ...

다른 사람이 .Phone을 제안했습니다. .Phony는 입력과 출력 간의 날짜 비교가 유효하지 않은 규칙에 사용해야합니다. 양식의 대상이 없기 때문에 output: input 당신은 그들 모두에 .phony를 사용해야합니다!

즉, 다양한 파일 이름에 대해 Makefile 상단의 일부 변수를 정의하고 입력 및 출력 섹션이 모두있는 실제 제작 규칙을 정의하여 Make의 이점을 사용할 수 있습니다. 즉, 실제로 컴파일하는 것만 Copmile에 필요한 것들!

편집 : 추가 된 예. 테스트되지 않았지만 이것이 당신이하는 방법입니다

.PHONY: clean    
clean:
    $(clean)

올바르게 기억하면 'Make'는 타임 스탬프 (파일 수정 시간)를 사용하여 대상이 최신인지 여부를 결정합니다. 재건을 강요하는 일반적인 방법은 '터치'명령을 사용하여 해당 타임 스탬프를 업데이트하는 것입니다. MakeFile에서 '터치'를 호출하여 대상 중 하나 (아마도 하위 메이크 파일 중 하나)의 타임 스탬프를 업데이트하여 해당 명령을 실행하도록 강요 할 수 있습니다.

이 간단한 기술은 강제력이 필요하지 않을 때 Makefile이 정상적으로 작동하도록합니다. 호출 된 새 대상을 만듭니다 당신의 끝에 Makefile. 그만큼 대상은 기본 대상이 의존하는 파일을 터치합니다. 아래의 예에서는 추가했습니다 MyProgram.cpp를 터치합니다. 또한 재귀적인 전화를 추가했습니다 만들다. 이렇게하면 입력 할 때마다 기본 대상이 만들어집니다. 힘을 만드십시오.

yourProgram: yourProgram.cpp
       g++ -o yourProgram yourProgram.cpp 

force:
       touch yourProgram.cpp
       make

나는 이것을 시도했고 그것은 나를 위해 일했다

이 라인을 추가하여 Makefile을 추가하십시오

clean:
    rm *.o output

new: clean
    $(MAKE)     #use variable $(MAKE) instead of make to get recursive make calls

저장하고 이제 전화하십시오

make new 

그리고 그것은 모든 것을 다시 한 번 다시 컴파일 할 것입니다

무슨 일이에요?

1) '새로운'전화는 깨끗합니다. '.o'의 확장자가있는 모든 객체 파일을 제거하는 'Clean'do 'rm'.

2) '새로운'부름 'Make'. '.o'파일이 없다는 것을 '. 그런 다음 링커는 모든 .o 파일 int one 실행 가능 출력을 연결합니다.

행운을 빕니다

Miller 's에 따라 재귀는 해로운 것으로 간주됩니다 전화를 피해야합니다 $(MAKE)! 당신이 보여주는 경우, 이것은 실제로 makefile이 아니라 랩퍼 스크립트가 아니기 때문에 쉘로 작성되었을 수도 있기 때문에 무해합니다. 그러나 당신은 더 깊은 재귀 수준에서 그렇게 계속한다고 말하면, 아마도 그 시선을 사로 잡는 에세이에 표시된 문제를 발견했을 것입니다.

물론 GNU와 함께 피하는 것이 번거 롭습니다. 그리고 그들이이 문제를 알고 있지만, 그것은 문서화 된 일을하는 방법입니다.

오토, makepp 이 문제에 대한 해결책으로 만들어졌습니다. 디렉토리 당 MakeFiles를 쓸 수 있지만 모두 프로젝트의 전체 관점으로 함께 모입니다.

그러나 레거시 메이크 파일은 재귀 적으로 쓰여졌습니다. 따라서 해결 방법이 있습니다 $(MAKE) 하위 퀘스트를 기본 MakePP 프로세스로 다시 채널로 채널로 채널로 표시하는 것 외에는 아무것도하지 않습니다. 서브 메이크 사이에 중복되거나 더 나쁜 모순적인 것들이있는 경우에만 요청해야합니다. --traditional-recursive-make (물론 MakePP 의이 장점을 깨뜨리는 것은 무엇입니까). 나는 당신의 다른 makefiles를 알지 못하지만, 그들이 깨끗하게 작성된 경우, makepp와 함께 필요한 재건은 다른 사람들이 제안한 해킹이 필요하지 않고 자동으로 발생해야합니다.

이미 성공적으로 컴파일 한 출력을 보존 할 필요가 없다면

nmake /A 

모두 재건됩니다

실제로 목표가 무엇인지에 따라 다릅니다. 그것이 가짜 대상 인 경우 (즉, 대상은 파일과 관련이 없습니다) .Phony로 선언해야합니다.

그러나 대상이 가짜 대상이 아니지만 어떤 이유로 든 재 구축하려는 경우 (예를 들어 __time__ 전처리 매크로를 사용할 때) 여기에서 답변에 설명 된 힘 구성표를 사용해야합니다.

이미 언급되었지만 사용에 추가 할 수 있다고 생각했습니다. touch

만약 너라면 touch 컴파일 할 모든 소스 파일, touch 명령은 파일의 타임 스탬프를 시스템 시간으로 변경합니다. touch 명령이 실행되었습니다.

소스 파일 Timstamp는 무엇입니다 make 파일이 변경되었으며 다시 컴파일해야합니다.

예를 들어 : 프로젝트가 C ++ 프로젝트 인 경우 touch *.cpp, 실행 make 다시 한 번, 전체 프로젝트를 다시 컴파일해야합니다.

make clean 이미 컴파일 된 모든 객체 파일을 삭제합니다.

Linux 시스템 (Centos 6.2)에서는 규칙이 실제로 대상과 일치하는 파일을 생성 할 때 대상을 선언하는 것과 힘에 가짜 의존성을 만드는 것 사이에 큰 차이가 있습니다. 파일을 매번 재생 해야하는 경우 파일에 가짜 의존력과 가짜 의존성에 대한 .Phony가 모두 필요했습니다.

잘못된:

date > $@

오른쪽:

FORCE
    date > $@
FORCE:
    .PHONY: FORCE
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top