명령 줄에서 Makefile에 인수를 전달하는 방법은 무엇입니까?


109

명령 줄에서 Makefile에 인수를 전달하는 방법은 무엇입니까?

할 수 있음을 이해합니다

$ make action VAR="value"
$ value

Makefile

VAR = "default"
action:
    @echo $(VAR)

다음 동작을 어떻게 얻습니까?

$ make action value
value

?

어때

$make action value1 value2
value1 value2


3
의 사용 가능한 복제 "화장 실행"에 인수를 전달
lesmana

답변:


212

당신은 아마 이것을하지 말아야합니다. Make가 작동하는 방식의 기본 패턴을 깨고 있습니다. 그러나 여기 있습니다 :

action:
        @echo action $(filter-out $@,$(MAKECMDGOALS))

%:      # thanks to chakrit
    @:    # thanks to William Pursell

편집 :
첫 번째 명령을 설명하려면

$(MAKECMDGOALS) 명령 줄에 적힌 "대상"목록입니다 (예 : "action value1 value2").

$@자동 변수 ,이 경우 "동작"의 규정의 대상의 이름.

filter-out목록에서 일부 요소를 제거하는 함수입니다. 따라서 $(filter-out bar, foo bar baz)반환합니다 foo baz(더 미묘 할 수 있지만 여기서는 미묘함이 필요하지 않습니다).

이들을 합하여 $(filter-out $@,$(MAKECMDGOALS))"action"이외의 명령 행에 지정된 대상 목록을 리턴합니다. 이는 "value1 value2"일 수 있습니다.


1
$(shell echo $(MAKECMDGOALS) | sed 's!^.* $@ !!')이전에 모든 목표를 생략하고 다음을 인수로 고려하십시오.make target1 target2 action value1 value2
Evgeniy Generalov

1
내 무지를 용서하십시오. 나는 인터넷 검색을 해봤 %:@:과 (그들은 호출하고 또는 무엇이든) 그 "지시어는"무엇에 대한 정보를 찾을 수 없습니다. 설명해 주시겠습니까?

15
@Jon : 설명서가 여기 있습니다 . 부분은 구성 %:@:A는 규칙 . 대상 이름 %모든 항목과 일치하는 규칙임을 의미합니다 . 즉, Make가 빌드하도록 지시 한 것을 빌드 할 다른 방법을 찾을 수없는 경우 해당 규칙을 실행합니다. 는 @:A는 제조법 ; :수단은 아무것도 할 수없고, @수단 조용히 해.
Beta

감사. 나는 그 매뉴얼을 읽고 있었고 처음에는 고려하지 않았습니다. %:실제로 % :는 와일드 카드 유형 대상 이름이었습니다. 나는 그 매뉴얼 페이지에서 아무것도 보지 못했다 @:. 그것은 "do-nothing"규칙이 단순히 ;대상 사양 뒤에 있을 것이라는 것을 암시한다. 그래서 % : ;"와일드 카드 do 로 작성하는 것이 더 정확하지 않을까? " -아무것도 "규칙?

1
filter-out작업이 명령 줄에 지정된 대상의 종속성이면 작동하지 않습니다. 왜냐하면 명령 줄에서 $@호출 된 원래 인수가 아닌 종속성의 이름으로 설정 되기 때문 입니다. 대신 MAKECMDGOALS쉘 배열에 할당 한 다음 첫 번째 요소를 제거합니다.@ args=($(MAKECMDGOALS)); args=("$${args[@]:1}")
Gingi

18

다음은 @Beta를 기반으로하는 일반적인 작업 솔루션입니다.

SHELL=/bin/bash내 Makefile 위에 GNU Make 4.1을 사용 하고 있으므로 YMMV!

이를 통해 추가 인수를 허용 할 수 있습니다 (오류를 던지는 대신 일치하지 않는 작업을 얻을 때 아무것도하지 않음).

%:
    @:

그리고 이것은 우리를 위해 args를 얻는 매크로입니다 :

args = `arg="$(filter-out $@,$(MAKECMDGOALS))" && echo $${arg:-${1}}`

다음은 이것을 부를 수있는 직업입니다.

test:
    @echo $(call args,defaultstring)

결과는 다음과 같습니다.

$ make test
defaultstring
$ make test hi
hi

노트! Maketools의 뉘앙스없이 만 make와 유사하게 작동하는 bash 패턴 인 "Taskfile"을 사용하는 것이 더 나을 수 있습니다. 참조 https://github.com/adriancooney/Taskfile를


작동했습니다 !! 다른 사람들이 그것을 시도하려면 반드시이 확인 tab하기 전에 @echo,하지 space.
Abdullah Al Maruf-Tuhin

11

훨씬 더 쉬운 앞치마. 작업을 고려하십시오.

provision:
        ansible-playbook -vvvv \
        -i .vagrant/provisioners/ansible/inventory/vagrant_ansible_inventory \
        --private-key=.vagrant/machines/default/virtualbox/private_key \
        --start-at-task="$(AT)" \
        -u vagrant playbook.yml

이제 호출하고 싶을 때 다음과 같이 실행합니다.

AT="build assets" make provision

또는 그냥 :

make provision이 경우 AT는 빈 문자열입니다.


-2

이러려고 하지마

$ make action value1 value2

대신 스크립트를 작성하십시오.

#! /bin/sh
# rebuild if necessary
make
# do action with arguments
action "$@"

다음을 수행하십시오.

$ ./buildthenaction.sh value1 value2

더 많은 설명을 위해 왜 이렇게 하는가와 makefile 해커의주의 사항은 매우 유사하지만 중복되지 않는 다른 질문에 대한 내 대답을 읽었습니다. "make run"에 인수 전달

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