"만들기"에 대한 인수 전달
나는 Makefiles를 사용합니다.
나는라는 대상이 run
빌드 대상을 실행합니다. 단순화하면 다음과 같습니다.
prog: ....
...
run: prog
./prog
다시 앉아 나는 이것이 독창적이라는 것을 알고 있지만 기립 박수는 필요하지 않습니다.
이제 내 질문은-인수를 전달할 방법이 있습니까? 그래서
make run asdf --> ./prog asdf
make run the dog kicked the cat --> ./prog the dog kicked the cat
감사!
원하는 것을 정확하게 수행하는 방법을 모르지만 해결 방법은 다음과 같습니다.
run: ./prog
./prog ${ARGS}
그때:
make ARGS="asdf" run
이 질문은 거의 3 살이지만 어쨌든 ...
GNU make를 사용한다면 쉽게 할 수 있습니다. 유일한 문제는 make
명령 행에서 비 옵션 인수를 대상으로 해석 한다는 것입니다. 해결책은 그것들을 아무것도하지 않는 목표로 바꾸는 것이므로 make
불평하지 않을 것입니다.
# If the first argument is "run"...
ifeq (run,$(firstword $(MAKECMDGOALS)))
# use the rest as arguments for "run"
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# ...and turn them into do-nothing targets
$(eval $(RUN_ARGS):;@:)
endif
prog: # ...
# ...
.PHONY: run
run : prog
@echo prog $(RUN_ARGS)
이것을 실행하면 다음이 제공됩니다.
$ make run foo bar baz
prog foo bar baz
표준 적으로 다음과 같은 매크로를 정의하여 인수를 전달할 수 있습니다.
make run arg1=asdf
다음과 같이 사용하십시오
run: ./prog $(arg1)
etc
Microsoft NMake 를 만들기 위한 참고 자료
아래와 같이 변수를 Makefile에 전달할 수 있습니다.
run:
@echo ./prog $$FOO
용법:
$ make run FOO="the dog kicked the cat"
./prog the dog kicked the cat
또는:
$ FOO="the dog kicked the cat" make run
./prog the dog kicked the cat
또는 베타에서 제공하는 솔루션을 사용하십시오 .
run:
@echo ./prog $(filter-out $@,$(MAKECMDGOALS))
%:
@:
용법:
$ make run the dog kicked the cat
./prog the dog kicked the cat
TL; DR은이 작업을 시도하지 않습니다
$ make run arg
대신 스크립트를 작성하십시오.
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
그리고 이것을하십시오 :
$ ./buildandrunprog.sh arg
명시된 질문에 대한 답변 :
레시피에서 변수를 사용할 수 있습니다
run: prog
./prog $(var)
그런 다음 변수 할당을 인수로 전달하여
$ make run var=arg
이 실행 ./prog arg
됩니다.
함정에주의하십시오. 이 방법과 다른 방법의 함정에 대해 자세히 설명하겠습니다.
질문 뒤에 의도 된 의도에 대한 답변 :
가정 : prog
일부 인수 로 실행 하고 싶지만 필요한 경우 실행하기 전에 다시 작성해야합니다.
대답 : 필요한 경우 다시 작성하고 args로 prog를 실행하는 스크립트를 작성하십시오.
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
이 스크립트는 의도를 매우 명확하게합니다. 그것은 make를 사용하여 좋은 일을합니다 : 건물. 쉘 스크립트를 사용하여 일괄 처리를 위해 유용한 작업을 수행합니다.
또한 호출 구문은 실제로 동일합니다.
$ ./buildandrunprog.sh foo "bar baz"
다음과 비교하십시오 :
$ ./prog foo "bar baz"
또한 makefile의 모든 경고없이 쉘 스크립트의 전체 유연성과 표현력으로 필요한 다른 작업을 수행 할 수 있습니다.
배경:
make는 대상을 실행하고 해당 대상에 인수를 전달하도록 설계되지 않았습니다. 명령 행의 모든 인수는 목표 (일명 대상), 옵션 또는 변수 지정으로 해석됩니다.
따라서 이것을 실행하면 :
$ make run foo bar --wat var=arg
메이크업 해석됩니다 run
, foo
및 bar
갱신에 대한 목표 (목표)로 자신의 조리법에 따라. --wat
make 옵션으로. 그리고 var=arg
변수 할당으로.
자세한 내용은 https://www.gnu.org/software/make/manual/html_node/Goals.html#Goals를 참조하십시오.
용어는 https://www.gnu.org/software/make/manual/html_node/Rule-Introduction.html#Rule-Introduction을 참조하십시오.
변수 할당 방법에 대한 이유와 내가 그것을 추천하는 이유
$ make run var=arg
레시피의 변수
run: prog
./prog $(var)
이것은 레시피에 인수를 전달하는 가장 "올 바르고"직접적인 방법입니다. 그러나 인수로 프로그램을 실행하는 데 사용할 수는 있지만 그런 식으로 사용되도록 설계되지는 않았습니다. 참조 https://www.gnu.org/software/make/manual/html_node/Overriding.html#Overriding를
내 의견으로는 이것은 하나의 큰 단점이 있습니다 : 당신이하고 싶은 것은 prog
argument 으로 실행 하는 것 arg
입니다. 그러나 쓰는 대신 :
$ ./prog arg
글 쓰고 있구나:
$ make run var=arg
공백을 포함하는 여러 인수 또는 인수를 전달하려고하면 훨씬 어색합니다.
$ make run var="foo bar\ baz"
./prog foo bar\ baz
argcount: 2
arg: foo
arg: bar baz
다음과 비교하십시오 :
$ ./prog foo "bar baz"
argcount: 2
arg: foo
arg: bar baz
기록을 위해 이것은 prog
다음과 같습니다.
#! /bin/sh
echo "argcount: $#"
for arg in "$@"; do
echo "arg: $arg"
done
$(var)
makefile에 따옴표 를 넣을 때 :
run: prog
./prog "$(var)"
그런 다음 prog
항상 하나의 인수를 얻습니다.
$ make run var="foo bar\ baz"
./prog "foo bar\ baz"
argcount: 1
arg: foo bar\ baz
이 모든 것이 내가이 경로를 추천하는 이유입니다.
완성도를 높이기 위해 "실행할 인수를 전달하는"다른 방법이 있습니다.
방법 1 :
run: prog
./prog $(filter-out $@, $(MAKECMDGOALS))
%:
@true
매우 간단한 설명 : 목표 목록에서 현재 목표를 걸러냅니다. %
다른 목표를 조용히 무시하지 않는 모든 대상 ( )을 잡으십시오 .
방법 2 :
ifeq (run, $(firstword $(MAKECMDGOALS)))
runargs := $(wordlist 2, $(words $(MAKECMDGOALS)), $(MAKECMDGOALS))
$(eval $(runargs):;@true)
endif
run:
./prog $(runargs)
슈퍼 간단한 설명 : 대상이 run
첫 번째 목표를 제거하고을 사용하여 나머지 목표에 대해 아무것도하지 마십시오 eval
.
더 자세한 설명은 make 매뉴얼을 참고 하십시오 : https://www.gnu.org/software/make/manual/html_node/index.html
방법 1의 문제점 :
대시로 시작하는 인수는 make로 해석되며 목표로 전달되지 않습니다.
$ make run --foo --bar
해결 방법
$ make run -- --foo --bar
인수가
run
대상과 같으면 제거됩니다.$ make run foo bar run
./prog foo bar
대신에 실행 됩니다./prog foo bar run
방법 2로 가능한 해결 방법
인수가 정당한 대상이면 실행됩니다.
$ make run foo bar clean
./prog foo bar clean
대상의 레시피도 실행됩니다clean
(존재한다고 가정).방법 2로 가능한 해결 방법
공백으로 인수를 전달하는 것은 어색합니다
$ make run foo "bar\ baz"
해결 방법 없음
합법적 인 대상을 잘못 입력하면 모든 대상을 잡기 때문에 자동으로 무시됩니다.
$ make celan
그냥 자동으로 무시
celan
합니다.해결 방법은 모든 것을 장황하게 만드는 것입니다. 무슨 일이 일어나는지 알 수 있습니다. 그러나 이는 합법적 인 출력에 많은 노이즈를 발생시킵니다.
방법 2의 문제 :
인수가 기존 대상과 이름이 같은 경우 make는 덮어 쓰고 있다는 경고를 인쇄합니다.
내가 아는 해결 방법이 없습니다.
공백으로 인수를 전달하는 것은 여전히 어색합니다.
해결 방법 없음
공백
eval
을 만들려는 인수는 대상을 수행하지 않습니다.해결 방법 : 위와 같이 아무것도하지 않는 전역 캐치 모든 대상을 작성하십시오. 위와 같은 문제로 잘못 입력 된 합법적 인 목표를 다시 자동으로 무시합니다.
eval
런타임에 makefile을 수정하는 데 사용 됩니다. 가독성과 디버깅 가능성, 그리고 놀랍도록 최소한 의 원리 로 볼 때 얼마나 더 나빠질 수 있습니까 ?해결 방법 :이 작업을 수행하지 마십시오 !! 1 대신 make를 실행 한 다음 실행하는 쉘 스크립트를 작성하십시오
prog
.
나는 gnu make 만 사용하여 테스트했습니다. 다른 제조사들은 다른 행동을 할 수 있습니다.
TL; DR은이 작업을 시도하지 않습니다
$ make run arg
대신 스크립트를 작성하십시오.
#! /bin/sh
# rebuild prog if necessary
make prog
# run prog with some arguments
./prog "$@"
그리고 이것을하십시오 :
$ ./buildandrunprog.sh arg
다음은 이러한 사용 사례 중 일부에 도움이되는 다른 솔루션입니다.
test-%:
$(PYTHON) run-tests.py $@
즉, 접두사 ( test-
이 경우)를 선택한 다음 대상 이름을 프로그램 / 러너로 직접 전달하십시오. 대상 이름을 기본 프로그램에 유용한 것으로 풀 수있는 러너 스크립트가있는 경우 이것이 대부분 유용하다고 생각합니다.
아니요. GNU make의 맨 페이지에서 구문을 보면
[-f makefile] [옵션] ... [대상] ...
여러 대상을 지정할 수 있으므로 '아니오'(지정한 정확한 방식으로는 아니오)입니다.
명령 행에서 각 n 번째 인수를 명시 적으로 추출 할 수 있습니다. 이를 위해 변수 MAKECMDGOALS를 사용할 수 있으며, 'make'에 제공된 명령 행 인수 목록을 보유하며 이는 대상 목록으로 해석됩니다. n 번째 인수를 추출하려면 "word"함수와 함께 해당 변수를 사용할 수 있습니다. 예를 들어 두 번째 인수를 원하는 경우 다음과 같이 변수에 변수를 저장할 수 있습니다.
second_argument := $(word 2, $(MAKECMDGOALS) )
곧이 , run: ./prog
오른쪽 부분이 대상이되어야 정도로, 조금 이상한 보이는 run: prog
더 나은 보인다.
나는 간단하게 제안 할 것이다 :
.PHONY: run
run:
prog $(arg1)
그리고 나는 인수가 전달 될 수 있다고 덧붙이고 싶습니다.
- 인수로 :
make arg1="asdf" run
- 또는 환경으로 정의하십시오.
arg1="asdf" make run
여기 내 예가 있습니다. Dev-Cpp와 함께 제공되는 mingw32-make.exe를 사용하여 Windows 7에서 작성하고 있습니다. c : \ Windows \ System32 \ make.bat가 있으므로 명령은 여전히 "make"입니다.
clean:
$(RM) $(OBJ) $(BIN)
@echo off
if "${backup}" NEQ "" ( mkdir ${backup} 2> nul && copy * ${backup} )
정기적 인 청소 사용법 :
make clean
mydir /에서 백업 정리 및 백업 사용법 :
make clean backup=mydir
이것을 너무 자랑스럽게 생각하지는 않지만 환경 변수를 전달하고 싶지 않아 미리 준비된 명령을 실행하는 방법을 뒤집 었습니다.
run:
@echo command-you-want
실행하려는 명령이 인쇄되므로 서브 쉘에서 평가하십시오.
$(make run) args to my command
내가 사용하는 또 다른 트릭 은 건식 실행 -n
을 지시 하는 플래그 make
입니다. 예를 들어
$ make install -n
# Outputs the string: helm install stable/airflow --name airflow -f values.yaml
$ eval $(make install -n) --dry-run --debug
# Runs: helm install stable/airflow --name airflow -f values.yaml --dry-run --debug
참고 URL : https://stackoverflow.com/questions/2214575/passing-arguments-to-make-run
'Programing' 카테고리의 다른 글
왜 참조 벡터를 만들 수 없습니까? (0) | 2020.03.06 |
---|---|
Python에서 stdout을 파이핑 할 때 올바른 인코딩 설정 (0) | 2020.03.06 |
탭 대신 공백을 사용하도록 메모장 ++을 구성하려면 어떻게해야합니까? (0) | 2020.03.06 |
Android 프로젝트에서 외부 JAR을 어떻게 사용합니까? (0) | 2020.03.06 |
decodeURIComponent와 decodeURI의 차이점은 무엇입니까? (0) | 2020.03.06 |