몇 개의 파일이 포함 된 디렉토리가 있으며 일부 파일에는 이름에 공백이 있습니다.
Test workspace/
Another directory/
file1.ext
file2.ext
demo 2012-03-23.odp
$(wildcard)
이 디렉토리에서 GNU의 명령을 사용한 다음를 사용하여 결과를 반복하여 $(foreach)
모든 것을 인쇄합니다. 코드는 다음과 같습니다.
FOO := $(wildcard *)
$(info FOO = $(FOO))
$(foreach PLACE,$(FOO),$(info PLACE = $(PLACE)))
인쇄 된 내용은 다음과 같습니다.
Test workspace
Another directory
file1.ext
file2.ext
demo 2012-03-23.odp
실제로 얻을 수있는 것은 다음과 같습니다.
Test
workspace
Another
directory
file1.ext
file2.ext
demo
2012-03-23.odp
후자는 분명히 나에게 쓸모가 없습니다. 문서 에 대한 $(wildcard)
이 완전히 “이름의 공백으로 구분 된 목록”을 반환하지만 플랫 아웃 상태는 큰 문제가이 인상을 인정하는 데 실패합니다. 도 아니다 않는 문서 를 들어 $(foreach)
.
이 문제를 해결할 수 있습니까? 그렇다면 어떻게? 공백을 제거하기 위해 모든 파일과 디렉토리의 이름을 바꾸는 것은 옵션이 아닙니다.
답변
버그 # 712 는 make가 공백이있는 이름을 처리하지 않는다고 제안합니다. 어디에도, 결코.
( 오타 또는 형식 지정 아티팩트 인 것처럼 보임) 공백을 이스케이프하여 부분적으로 구현 되었다는 블로그 게시물을 찾았 지만 :\
\\
- 을 제외한 어떤 기능에서도 작동하지 않습니다
$(wildcard)
. - 특별한 변수를 포함하는 변수에서 이름의 목록을 확장 할 때 그것은 작동하지 않습니다
$?
,$^
그리고$+
뿐만 아니라 사용자 정의 변수를. 즉$(wildcard)
, 올바른 파일과 일치 하는 동안 결과를 해석 할 수는 없습니다.
따라서 명시 적이거나 매우 간단한 패턴 규칙을 사용하면 작동하도록 할 수 있지만 그 이상은 운이 없습니다. 공간을 지원하는 다른 빌드 시스템을 찾아야합니다. jam / bjam 이 작동 하는지 , scons , waf , ant , nant 및 msbuild가 모두 작동 하는지 확실 하지 않습니다 .
답변
GNU Make는 공백으로 구분 된 파일 이름으로 매우 열악합니다.
공백은 모든 곳에서 단어 목록의 구분 기호로 사용됩니다.
이 블로그 게시물 은 상황을 잘 요약하지만 경고 : \가 아닌 \\를 잘못 사용합니다.
target: some\ file some\ other\ file
some\ file some\ other\ file:
echo done
변수를 사용할 수도 있으므로 이것도 작동합니다.
VAR := some\ file some\ other\ file
target: $(VAR)
$(VAR):
echo done
wildcard
기능 만이 탈출을 인식하므로 많은 고통 없이는 멋진 일을 할 수 없습니다.
그러나 쉘이 구분 기호로도 공백을 사용한다는 것을 잊지 마십시오 .
나는 변경을 원하는 경우 echo done
에 touch $@
, 나는 나의 쉘을 탈출 슬래시를 추가해야 할 것이다.
VAR := some\ file
target: $(VAR)
$(VAR):
touch $(subst \,\\,$@)
또는 따옴표를 사용하십시오.
VAR := some\ file some\ other\ file
target: $(VAR)
$(VAR):
touch '$@'
결국 GNU make와 쉘 모두에서 많은 고통을 피하려면 파일 이름에 공백을 넣지 마십시오. 그렇게한다면 Make의 제한된 기능으로 충분할 것입니다.
답변
이 방법을 사용하면 파일 $?
목록 인 및 사용자 변수와 같은 나열된 파일 이름을 사용할 수도 있습니다.
Make에서 공백을 처리하는 가장 좋은 방법은 다른 문자를 공백으로 대체하는 것입니다.
s+ = $(subst \ ,+,$1)
+s = $(subst +,\ ,$1)
$(call s+,foo bar): $(call s+,bar baz) $(call s+,bar\ baz2)
# Will also shows list of dependencies with spaces.
@echo Making $(call +s,$@) from $(call +s,$?)
$(call s+,bar\ baz):
@echo Making $(call +s,$@)
$(call s+,bar\ baz2):
@echo Making $(call +s,$@)
출력
Making bar baz
Making bar baz2
Making foo bar from bar baz bar baz2
그런 다음 모든 GNU Make 함수를 사용하여 파일 이름 목록을 안전하게 조작 할 수 있습니다. 규칙에서 이러한 이름을 사용하기 전에 +를 제거해야합니다.
SRCS := a\ b.c c\ d.c e\ f.c
SRCS := $(call s+,$(SRCS))
# Can manipulate list with substituted spaces
OBJS := $(SRCS:.c=.o)
# Rule that has object files as dependencies.
exampleRule:$(call +s,$(OBJS))
# You can now use the list of OBJS (spaces are converted back).
@echo Object files: $(call +s,$(OBJS))
a\ b.o:
# a b.o rule commands go here...
@echo in rule: a b.o
c\ d.o:
e\ f.o:
출력
in rule: a b.o
Object files: a b.o c d.o e f.o
이 정보는 모두 다른 사람이 게시 한 블로그 에서 가져온 것입니다.
대부분의 사람들은 경로에 공백을 사용하지 않거나 Windows 8.3 경로를 사용하는 것을 권장하는 것처럼 보이지만 공백을 사용해야하는 경우 공백을 이스케이프하고 대체가 작동합니다.
답변
쉘에 조금 더 의존하고 싶다면 공백이있는 이름을 저장할 수있는 목록이 제공됩니다.
$(shell find | sed 's: :\\ :g')
답변
원래의 질문은 “이름 바꾸기는 선택 사항이 아닙니다”라고 말했지만 많은 주석가들은 이름 바꾸기가 Make가 공백을 처리 할 수있는 유일한 방법이라고 지적했습니다. 중간 방법을 제안합니다. Make를 사용하여 파일 이름을 임시로 바꾼 다음 다시 이름을 바꿉니다. 이것은 암시 적 규칙과 다른 장점으로 Make의 모든 기능을 제공하지만 파일 이름 지정 체계를 엉망으로 만들지는 않습니다.
# Make cannot handle spaces in filenames, so temporarily rename them
nospaces:
rename -v 's/ /%20/g' *\ *
# After Make is done, rename files back to having spaces
yesspaces:
rename -v 's/%20/ /g' *%20*
당신은 손으로이 목표를 부를 수 make nospaces
및 make yesspaces
, 또는 당신이 그들에 따라 다른 목표를 가질 수있다. 예를 들어, 파일을 서버와 다시 동기화하기 전에 파일 이름에 공백을 다시 넣어야하는 “푸시”대상이 필요할 수 있습니다.
# Put spaces back in filenames before uploading
push: yesspaces
git push
[(!) 참고 : 내가 사용하는 제안 대답 시도 +s
및 s+
하지만 내 메이크 열심히 읽고 디버깅하기 위해 만들었다. 묵시적 규칙에 대해 욕을 먹었을 때 포기했습니다 %.wav : %.ogg ; oggdec "$<"
..]