탭 문자없이 유효한 Makefile을 만들 수 있습니까?


114
target: dependencies
    command1
    command2

내 시스템 (Mac OS X)에서 makeMakefile의 각 command줄 내용 앞에 탭 문자가 있어야 하거나 구문 오류가 발생합니다.

내 편집기가 항상 모든 공간으로 설정되어 있기 때문에 Makefile을 만들거나 편집 할 때 불편합니다.

탭 문자없이 유효한 Makefile을 만들 수 있습니까?


4
또한 공백이있는 탭을 에뮬레이트하도록 편집기를 구성했습니다. 하지만 에디터는 드물지만 Makefile 에서처럼 탭이 꼭 있어야하는 드문 경우에 Ctrl-Tab을 입력 할 수도 있습니다. 당신의 편집자도 마찬가지 일 것입니다.
toolic

답변:


118

이것은의 구문 이상 / 요구 사항이며 makeMac OS X와는 관련이 없습니다. 불행히도을 사용하려는 경우 할 수있는 작업이 없습니다 make.

편집 : GNU Make는 이제 사용자 정의 레시피 접두사를 지원합니다. 이 답변을 참조하십시오 .

의이 측면을 싫어하는 첫 번째 사람이 아닙니다 make. Unix Haters의 핸드북 을 인용하려면 :

Dennis의 Makefile의 문제점은 그가 주석 행을 추가 할 때 2 행의 시작 부분에있는 탭 문자 앞에 실수로 공백을 삽입했다는 것입니다. 탭 문자는 Makefile의 구문에서 매우 중요한 부분입니다. 모든 명령 줄 (이 예에서 cc로 시작하는 줄)은 탭으로 시작해야합니다. 그가 변경 한 후 2 행은 변경되지 않았으므로 오류가 발생했습니다.

"그래서 뭐?" "그게 뭐가 잘못 됐나요?"

그 자체로는 문제가 없습니다. Unix에서 다른 프로그래밍 도구가 작동하는 방식을 고려할 때 구문의 일부로 탭을 사용하는 것은 The Green Berets의 펀지 스틱 트랩 중 하나와 같습니다. Kansas의 불쌍한 아이가 John Wayne 앞에 걸어 가고 있습니다. t 트립 와이어를 참조하십시오. 결국 캔자스 옥수수 밭에서는 조심해야 할 전선이 없습니다. 왬!


5
탭의 문제는 make를 사용하는 모든 사람들이 가장 먼저 배우는 것 중 하나입니다. 나는 그것이 진짜 문제라는 것을 결코 발견하지 못했습니다.

2
@Neil, 나도 : 나는 UHH에 동의한다고 말한 적이 없으며, 어떤 사람들은 그것을 좋아하지 않는다고 말하고 있습니다. :-)
Alok Singhal

2
cmake를 사용하는 데 좋은 플러그처럼 보입니다. make 구문의 유일한 실망스러운 이상은 아닙니다.
orodbhen

3
방금 gnu.org/software/make/manual/html_node/Special-Variables.html을 찾았 습니다 (참조 .RECIPEPREFIX). 아래 답변 중 하나도 이에 대해 언급하며 내 대신 "올바른"것으로 표시해야합니다. stackoverflow.com/a/21920142
Alok Singhal

3
큰 문제는 아니지만 성가시다. 매번. 그것은 확실히 성 가시고 \ omicron 선형 시간에 성가시다.
파르 시안 샷

60

이 질문이 처음에 제기 된 이후 Tab로 접두사 문자 이외의 것을 사용할 수있는 GNU Make 버전이 출시되었습니다 . 메일 링리스트 공지에서 :

새로운 특수 변수 : .RECIPEPREFIX를 사용하면 레시피 소개 문자를 기본값 (TAB)에서 다른 것으로 재설정 할 수 있습니다. 이 변수 값의 첫 번째 문자는 새로운 레시피 소개 문자입니다. 변수가 빈 문자열로 설정되면 TAB이 다시 사용됩니다. 마음대로 설정하고 재설정 할 수 있습니다. 레시피는 처음 구문 분석되었을 때 활성 값을 사용합니다. 이 기능을 감지하려면 $ (. RECIPEPREFIX) 값을 확인하십시오.

이 기능은 2010 년 7 월에 출시 된 GNU Make 3.82에 추가되었습니다 (이 질문의 원래 요청 날짜로부터 6 개월 후). 3 년이 지나고 그 이후로 바뀌었기 때문에 다른 Make 플레이버가 GNU Make를 따랐을 가능성이 높습니다.


51

탭없이 유효한 메이크 파일을 만드는 복잡한 방법이 있습니다.

makefile을 읽을 수 있도록 변경하는 경우 :

target: dependencies; command1; command2

작동한다면. 한 줄 이상에서 원하는 경우 다음을 수행 할 수 있습니다.

target: dependencies; \
command1; \
command2

지저분하지만 작동합니다.


지원하는 Make 버전으로 업그레이드 .RECIPEPREFIX하는 것이 가장 좋은 방법 일 것입니다. 하지만 그렇게하고 싶지 않았기 때문에 결국이 솔루션을 기반으로 한 솔루션을 사용하게되었습니다. 1 행 : target:\ , 2 행 : [네 공백 들여 쓰기] 다음에;command
LS

33

프로필에 vimrc가있는 경우 다음 줄을 추가하여 vim이 공백으로 변경되지 않도록 할 수 있습니다.

autocmd FileType make setlocal noexpandtab

나도 이것으로 어려움을 겪고 있었고 이것은 나를 위해 고쳤습니다. 좋은 소식을 전하세요!


19

공백을 사용하고 싶다면이 작업을 수행합니다.

.RECIPEPREFIX +=


어떤 버전의 make가이를 지원합니까? 이것은 GNU Make 4.1에서 작동하지 않습니다.
Cerin

2
GNU Make 4.1 x86_64-pc-linux-gnu 용으로 빌드 됨 죄송 합니다만 작동합니다
neok

아마,이 변수의 요구가 메이크업 파일 (점 쉽게 발견하지 접두사) 자체 내에서 선언 할 것을 언급 할 필요가
urusai_na

버전 4.2 이상에서는 작동합니다. 문서.RECIPEPREFIX"변수가 비어있는 경우 ( 기본적으로 ) 해당 문자가 표준 탭 문자"라는 설명에 나와 있습니다. 이는 변수가 기본적으로 정의되어 있음을 의미합니다. 를 사용하여 확인합니다 ifeq ($(origin .RECIPEPREFIX), undefined). 때문에 +=APPEND 하나의 공간 과 좌에 RHS는, var +=세트 var하나의 공간 (플러스 빈 문자열)에이만큼 var이미 정의 될 수있다. ( var정의되지 않은 경우 +=와 동일합니다 =.)
ynn

1
이 답변은 더 이상 작동하지 않습니다. 최신 솔루션에 대한 내 대답 을 참조하십시오 .
ynn

11

vim의 삽입 모드에서는 Ctrl-v <TAB>공백을 삽입하도록 탭 키를 설정 한 경우에도 리터럴 탭을 삽입하는 데 사용할 수 있습니다 . 물론 이것은 귀하의 질문에 대한 답변은 아니지만 리터럴 탭이 필요하지 않도록 사용 가능한 방법의 대안이 될 수 있습니다.


10

EditorConfig 를 사용하는 경우 .editorconfig파일에 다음 행을 추가 하여 IDE에서 공백 대신 탭을 사용하도록 강제 할 수 있습니다 Makefile.

[Makefile]
indent_style = tab

4

GNU Make 4.2까지

Steven Penny의 답변이 작동합니다.

.RECIPEPREFIX +=

이것이 작동하는 이유는 내 의견에 설명되어 있습니다.


GNU Make 4.3 이후 (2020 년 1 월 19 일 출시)

+=운영자의 행동은 이전 버전과 호환되지 않는 방식 변경 . 왼쪽 피연산자에 빈 값이 있으면 더 이상 공백이 추가 되지 않습니다 .

대신 사용할 수 있습니다.

.RECIPEPREFIX := $(.RECIPEPREFIX)<space>

, 여기서는 <space>단일 공간입니다. $(.RECIPEPREFIX)빈 값으로 확장 되지만 GNU Make가 무시하지 않도록해야 <space>합니다. 이 코드는 버전 4.3 이전의 GNU Make에서도 작동합니다.


1

우분투에서 : vi Makefile은 공간을 탭 (또는 원하는 다른 것)으로 대체합니다.

:%s/<space chars>/^I/g

예를 들어 8 개의 공백을 탭으로 바꿉니다.

:%s/        /^I/g

주의 : ^ I는 ^I 문자가 아닌 탭 키로 삽입 합니다. : D


-6

이식성이 없습니다. 특정 종류의 make에는 절대적으로 탭 문자가 필요합니다. 공백보다 탭을 선호하는 또 다른 이유 :-)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.