2010-03-17 4 views
0

평평하지 않은 디렉토리 구조에 수백 개의 파일이 있습니다. My Makefile은 각 소스 파일을 나열합니다. 프로젝트의 크기와 프로젝트에 여러 개발자가 있다는 사실을 감안할 때 새로운 파일을 넣거나 꺼내는 것을 잊어 버리면 성가심이 생길 수 있습니다. 필자는 makefile을 일반화하여 make가 모든 파일 이름을 지정하지 않고 모든 .cpp 및 .h 파일을 간단히 만들 수 있도록하고 싶습니다. 여러 파일 유형에 대한 몇 가지 일반적인 규칙이 있습니다.하나의 메이크 파일을 사용하여 계층 적 프로젝트를 만들 수 있습니까?

내 질문 : 많은 하위 폴더가있는 디렉토리에 많은 수의 파일이있는 경우 각 하위 폴더를 경로의 일부로 지정할 필요없이 make가 모든 것을 빌드하도록 어떻게 알 수 있습니까? 그리고 루트 디렉토리에 하나의 Makefile만으로이 작업을 수행 할 수 있도록 어떻게 만들 수 있습니까? 편집

: this 거의 내 질문에 대한 대답,하지만 당신은 모든 파일 이름을 지정해야합니다 :

+1

편집중인 파일의 백업, 임시 파일 등 임의의 파일을 빌드하는 빌드 프로세스를 원하지 않습니다. 작성해야하는 파일을 나열하려면 __want__를 사용해야합니다. 당신은 아직 그것을 깨닫지 못할 수도 있습니다. 그러나 당신은 정말로 건설 될 것을 열거하고 싶습니다. –

+0

백업 및 임시 파일에 .cpp 또는 .h 확장자가 없으십니까? .cpp ~ .cpp를 해석합니까? – saramah

답변

1

순수한 gmake 솔루션은 가능하지만 외부 명령을 사용하여 메이크 파일을 수정하거나 외부 파일 (makefile의 include)을 생성하는 것이 훨씬 간단합니다. 의 라인을 따라

뭔가 :

all: myprog 

find_sources: 
    zsh -c 'for x in **/*.cpp; echo "myprog: ${x/.cpp/.o}" >> deps.mk' 

include deps.mk 

make find_sources && make 

메모를 실행 정확한 zsh을 선 아마 일부는 메이크 파일, 예를 들어,에서 일을 탈출해야합니다 $ 대신 $$. bash + find로 바꿀 수도 있습니다.것

+0

흠, 그래서 난 그냥 내 목표 중 하나로서 작은 쉘 스크립트를 실행해야할까요? 나는 그 일을 생각하고 있었지만, 내가 놓친 뭔가를 만들었 으면 좋았을 텐데. – saramah

+0

꽤 깨끗하지는 않지만, 내구성이 거의없는 경로로 보인다. 감사! – saramah

+1

더 간결한 방법이 있습니다. "find_sources"대신 "deps.mk"를 대상으로 사용하십시오. 그러면 "make"를 실행할 수 있습니다. – Beta

0
나는 와일드 카드 기능의 조합을 사용하여 시작할 것

: \ http://www.gnu.org/software/make/manual/make.html#Wildcard-Function

VPATH을/VPATH http://www.gnu.org/software/make/manual/make.html#Selective-Search

및 파일 기능 http://www.gnu.org/software/make/manual/make.html#File-Name-Functions

제외 (예 : 백업, Jonathan Leffler 언급) 백업을 위해 vpath에없는 별도의 폴더를 사용하고 좋은 암시 적 규칙을 사용하십시오.

아직 수행 할 폴더는 정의해야하지만 각 파일이 아닌 폴더를 정의해야합니다.

0

나는 이것에 대해 두 사람의 마음을 가지고 있습니다. 한편으로, Make 시스템을 컴파일하고 링크 된 모든 것을 링크한다면 누군가가 소스 디렉토리에 충돌하는 쓰레기를 남겨 두었다가 서둘러 찾아 낼 수 있습니다. 반면에 충돌하지 않는 쓰레기가 번식하고 라이브 코드와 구분할 수있는 쉬운 방법이 없을 것입니다 ...

소스와 같이 상점에 특정한 것이 많다고 생각합니다. 소스 제어 시스템 및 겹치는 코드 기반을 가진 다른 프로젝트를 가질 계획인지 여부에 대해 설명합니다. 당신이 이라면 실제로은 주어진 디렉토리 아래의 모든 소스 파일을 컴파일하고 그들 모두를 연결하고 싶습니다. 간단한 재귀를 제안합니다 : 객체를 만들고 여기에 모든 소스 파일을 컴파일하고 전체 경로를 사용하여 결과 객체를 추가 한 다음, 최상위 소스 디렉토리의 목록으로 이동하려면 여기에있는 모든 디렉토리를 반복하십시오. 연결하려면 목록을 사용하십시오.

1

한 가지 방법은 (내가 쉘에서 독립적 인 Windows 또는 리눅스에있는 의미)이있다 독립적 인 플랫폼 : 또한 지정하는 것이 중요 공간도 세미콜론 여기에 중요하다는 것을

DIRS = relative/path1\ 
     relative/path2 

dd = absolute/path/to/subdirectories 
all: 
@$(foreach dir, $(DIRS), $(MAKE) -C $(dd)$(dir) build -f ../../Makefile ;) 
build: 
    ... build here 

노트입니다 절대 경로뿐만 아니라 마지막에 적절한 Makefile에 대한 경로를 지정하십시오 (이 경우 조부모 폴더에 하나의 Makefile 만 사용하고 있습니다)

PHONY 대상을 포함하는 더 나은 접근 방법이 있습니다. 진행 및 오류를 처리하고 다른 대상으로 진행하는 대신 한 폴더에 문제가있는 경우 빌드를 중지합니다.

.PHONY: subdirs $(DIRS) 

subdirs: $(DIRS) 

$(DIRS): 
    $(MAKE) -C [email protected] build -f ../../Makefile 
all : prepare subdirs 
... 
build : 
... build here 

여기에도 모든 하위 프로젝트에 적용 할 수있는 Makefile 만 사용하고 있습니다. 손자 폴더의 각 하위 프로젝트에 대해 대상 "빌드"가 루트에있는 하나의 Makefile을 사용하여 만들어집니다.