문제

MakeFile에서 다음과 비슷한 코드를 사용하고 있습니다.

empty:=
space:= $(empty) $(empty)
path_escape = $(subst $(space),\$(space),$(1))

TOP=$(call path_escape,$(abspath .))
TARGET=$(TOP)/foo

$(info TOP='$(TOP)')
$(info TARGET='$(TARGET)')

all: $(TARGET)

$(TARGET):
    touch '$(notdir $@)'

.PHONY: $(TARGET)

공간이없는 디렉토리에서 이것을 사용하면 space-test, 그것은 잘 작동합니다 :

$ make
TOP='/tmp/space-test'
TARGET='/tmp/space-test/foo'
touch 'foo'

그러나 공백이있는 디렉토리에서 사용하면 space test, 그 다음에 $(notdir) 잘못된 일을합니다.

TOP='/tmp/space\ test'
TARGET='/tmp/space\ test/foo'
touch 'space foo'

여기서 일어나는 일은 그 것입니다 $(notdir) 해석 /tmp/space test/foo ~처럼 경로와 "파일 부분"을 반환합니다 둘 다 (즉, space 그리고 foo). 이것의 이상한 부분은 그 것입니다 TARGET 제대로 탈출됩니다. 어떻게 든, 규칙 내부 또는 내부 $(notdir), 백 슬래시 탈출은 무시되고 있습니다.

여기서 내가 뭘 잘못하고 있니?

도움이 되었습니까?

해결책

그만큼 $(notdir) GNU의 기능은 공백으로 분리 된 인수 목록을 가져옵니다. 일부 기능은 탈출 공간을 지원합니다 \\, 하지만 $(notdir) 그들 중 하나가 아닙니다.

이것은 작동해야합니다 :

s? = $(subst $(empty) ,?,$1)
?s = $(subst ?, ,$1)
notdirx = $(call ?s,$(notdir $(call s?,$1)))

$(TARGET):
    touch '$(call notdirx,$@)'

이것은 "공간 안전"버전을 정의합니다 notdir ~라고 불리는 notdirx. 아주 간단합니다. s? 먼저 모든 공간을 물음표로 바꾸고 (파일 이름으로 표시 될 수 없기를 바랍니다). ?s 다시 변환합니다. 그 사이에서 우리는 원본을 안전하게 호출 할 수 있습니다 notdir 기능.

파일 이름의 GNU 제조업체 및 공백에 대한 훌륭한 요약은 GNU는 공백이있는 파일 이름을 충족시킵니다.

다른 팁

유닉스 쉘이 있다고 가정하면 다음을 수행 할 수 있습니다.

notdirx = $(shell basename '$1')
dirx = $(shell dirname '$1')

비슷한 전략이 다른 기능에 적용될 수 있습니다. 단일 인수로 취급하려는 공백에 감염된 텍스트가 포함 된 변수 주변의 견적 표시를 기억하십시오. 이것은 또한 다른 특수 캐릭터로부터 당신을 보호 할 것입니다 (견적 마크 제외!). 다음은 Wildcard Glob의 결과에서 모든 공간을 탈출하는 예입니다.

$(shell ls -1 '*.foo' | sed 's/ /\\\\ /g')

Windows는 이제 디렉토리 이름에 괄호를 넣고 있습니다. C:\Program Files (x86)\ 아직 분명하지 않습니다. make.

이것은 어둠 속에서 단지 샷입니다.

TOP='"/home/chris/src/tests/make/space test"'
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top