mkdir을 사용할 때 makefile에서 "디렉토리가 이미 존재함 오류"를 방지하는 방법

StackOverflow https://stackoverflow.com/questions/99132

  •  01-07-2019
  •  | 
  •  

문제

메이크파일에 디렉토리를 생성해야 하는데 쉽게 무시할 수 있음에도 불구하고 "디렉토리가 이미 존재함 오류"가 계속해서 발생하지 않도록 하고 싶습니다.

나는 주로 mingw/msys를 사용하지만 다른 쉘/시스템에서도 작동하는 것을 원합니다.

이것을 시도했지만 작동하지 않았습니다. 어떤 아이디어가 있습니까?

ifeq (,$(findstring $(OBJDIR),$(wildcard $(OBJDIR) )))
-mkdir $(OBJDIR)
endif
도움이 되었습니까?

해결책

UNIX에서는 다음을 사용하십시오.

mkdir -p $(OBJDIR)

mkdir에 -p 옵션을 사용하면 디렉토리가 존재하는 경우 오류 메시지가 표시되지 않습니다.

다른 팁

보고 공식 make 문서, 여기에 좋은 방법이 있습니다:

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 문서의 예와 비교하여 플래그가 추가되었습니다.다른 대안은 다른 답변을 참조하세요.

테스트 명령을 사용할 수 있습니다.

test -d $(OBJDIR) || mkdir $(OBJDIR)

다음은 컴파일러 출력 디렉터리를 생성하기 위해 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

메이크파일 내부:

target:
    if test -d dir; then echo "hello world!"; else mkdir dir; fi

Windows의 경우

if not exist "$(OBJDIR)" mkdir $(OBJDIR)

유닉스에서 | 리눅스

if [ ! -d "$(OBJDIR)" ]; then mkdir $(OBJDIR); fi
ifeq "$(wildcard $(MY_DIRNAME) )" ""
  -mkdir $(MY_DIRNAME)
endif
$(OBJDIR):
    mkdir $@

이는 여러 디렉토리에서도 작동합니다.

OBJDIRS := $(sort $(dir $(OBJECTS)))

$(OBJDIRS):
    mkdir $@

첨가 $(OBJDIR) 첫 번째 목표가 잘 작동하기 때문입니다.

mingw32/msys/cygwin/linux에서 작동합니다.

ifeq "$(wildcard .dep)" ""
-include $(shell mkdir .dep) $(wildcard .dep/*)
endif

반환 코드를 명시적으로 무시하고 오류 스트림을 덤프하면 오류가 발생하면 make는 오류를 무시합니다.

mkdir 2>/dev/null || true

이로 인해 병렬 제작에서 경쟁 위험이 발생해서는 안 되지만 확실하게 테스트하지는 않았습니다.

Lars의 답변보다 조금 더 간단합니다.

something_needs_directory_xxx : xxx/..

일반 규칙:

%/.. : ;@mkdir -p $(@D)

정리하거나 .PRECIOUS를 만들 터치 파일이 없습니다 :-)

또 다른 일반적인 gmake 트릭을 보고 싶거나 최소한의 스캐폴딩을 사용하는 비재귀 make에 관심이 있다면 확인해 보세요. 두 가지 더 저렴한 gmake 트릭 그리고 해당 블로그의 다른 make 관련 게시물도 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top