답변:
UNIX에서는 다음을 사용하십시오.
mkdir -p $(OBJDIR)
mkdir에 대한 -p 옵션은 디렉토리가 존재하는 경우 오류 메시지를 방지합니다.
-p
Windows에서 작동하지 않습니다. 아마도 질문이 묻는 것입니다. 이것이 어떻게 받아 들여 졌는지 확실하지 않습니다.
make -p
Unix 또는 Linux입니까?
보면 공식 메이크업 문서 , 여기에 그것을 할 수있는 좋은 방법입니다 :
OBJDIR := objdir
OBJS := $(addprefix $(OBJDIR)/,foo.o bar.o baz.o)
$(OBJDIR)/%.o : %.c
$(COMPILE.c) $(OUTPUT_OPTION) $<
all: $(OBJS)
$(OBJS): | $(OBJDIR)
$(OBJDIR):
mkdir -p $(OBJDIR)
여기에서 | 파이프 연산자, 주문 전용 전제 조건을 정의합니다. 현재 대상을 빌드하려면 대상 $(OBJDIR)
이 더 최근 대신 존재해야 함을 의미합니다 .
내가 mkdir -p
. -p
플래그가 문서의 예를 비교 하였다. 다른 대안에 대해서는 다른 답변을 참조하십시오.
$(OBJDIR)
대상이 있어야 할 존재 " . 파일 존재 여부 (및 타임 스탬프)를 확인하여 대상을 빌드해야하는지 결정합니다. 따라서 여기서 $(OBJDIR)
가 없으면 빌드하므로 현재 대상을 빌드하기 위해 존재 하며 $(OBJS)
내부에 생성됩니다.
test 명령을 사용할 수 있습니다.
test -d $(OBJDIR) || mkdir $(OBJDIR)
make -j
디렉터리가 존재하는지 테스트 할 때와 생성 될 때 사이의 경쟁 조건으로 인해 병렬로 빌드 할 때 ( ) 중단 될 수 있음을 지적하고 싶습니다 . 한 작업은 자신이 없는지 테스트 할 수 있지만 생성하기 전에 다른 작업이 디렉토리를 생성합니다. 그런 다음 첫 번째 시도가 디렉토리가 이미 존재하기 때문에 실패합니다. 이 경우 가장 좋은 해결책은 @TeKa의 답변에 언급 된 전제 조건 만 주문하는 것입니다 (수용된 답변이어야 함).
다음은 컴파일러 출력 디렉토리를 만들기 위해 GNU make와 함께 사용하는 트릭입니다. 먼저이 규칙을 정의하십시오.
%/.d:
mkdir -p $(@D)
touch $@
그런 다음 해당 디렉토리의 .d 파일에 종속 된 디렉토리로 이동하는 모든 파일을 만듭니다.
obj/%.o: %.c obj/.d
$(CC) $(CFLAGS) -c -o $@ $<
$ ^ 대신 $ <를 사용하십시오.
마지막으로 .d 파일이 자동으로 제거되지 않도록합니다.
.PRECIOUS: %/.d
.d 파일을 건너 뛰고 디렉토리에 직접 의존하는 것은 파일이 해당 디렉토리에 기록 될 때마다 디렉토리 수정 시간이 업데이트되어 make를 호출 할 때마다 강제로 다시 작성되므로 작동하지 않습니다.
디렉토리가 이미 존재하는 것이 문제가되지 않는 경우 해당 명령에 대한 stderr을 리디렉션하여 오류 메시지를 제거 할 수 있습니다.
-mkdir $(OBJDIR) 2>/dev/null
Windows에서
if not exist "$(OBJDIR)" mkdir $(OBJDIR)
유닉스에서 | 리눅스
if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
/bin/sh: 1: Syntax error: end of file unexpected (expecting "then")
Lars의 대답보다 조금 더 간단합니다.
something_needs_directory_xxx : xxx/..
및 일반 규칙 :
%/.. : ;@mkdir -p $(@D)
정리하거나 .PRECIOUS를 만들 터치 파일이 없습니다. :-)
좀 더 일반적인 gmake 트릭을보고 싶거나 최소한의 스캐 폴딩을 사용 하는 비재 귀적 make에 관심이 있다면 해당 블로그에서 두 가지 더 저렴한 gmake 트릭 과 다른 make 관련 게시물을 확인하는 것이 좋습니다.