Makefile을 사용하여 컴파일하고 있습니다.깨끗한암호. 내 Clean 파일은 다음 형식의 파일 이름을 *.icl
가지며 .icl
.
$(EXE): % : %.icl | copy
$(CLM) $(CLM_LIBS) $(CLM_INC) $(CLM_OPTS) $@ -o $@
이제 바이너리를 실행할 수 있는 규칙을 추가하고 싶습니다. 요즘은 자주 해요
make some_module && ./some_module
위의 규칙에 따라 모듈을 실행하는 make 대상을 원합니다. 하지만 모듈 이름 자체가 이미 별도의 컴파일 대상이므로 그대로 유지하고 싶습니다. 내가 원하는 것은 호출할 수 make run some_module
있고 위의 규칙에 따라 실행할 수 있는 두 단어가 있는 대상입니다 ./some_module
.
여러 단어가 포함된 타겟을 생성할 수 있나요?
나는 다음과 같은 규칙을 만들려고 했습니다(지금은 여전히 종속성이 없습니다).
run $(EXE):
./$@
실행하면 make run some_module
많은 레시피가 "덮어쓰기" 및 "무시"되어 궁극적으로 ./run
존재하지 않게 됩니다.
Makefile:24: warning: overriding recipe for target 'tut7_2_2'
Makefile:21: warning: ignoring old recipe for target 'tut7_2_2'
Makefile:24: warning: overriding recipe for target 'support_check'
Makefile:21: warning: ignoring old recipe for target 'support_check'
[...]
Makefile:24: warning: overriding recipe for target 'drawingframe'
Makefile:21: warning: ignoring old recipe for target 'drawingframe'
./run
/bin/bash: ./run: No such file or directory
Makefile:24: recipe for target 'run' failed
make: *** [run] Error 127
답변1
당신은 사용할 수 있습니다$(MAKECMD 대상)run
명령줄에 지정된 다른 대상 중에서 마지막으로 강제 실행합니다. 아래 예는 Clean을 모르기 때문에 C로 작성되었습니다.
EXE = a b c
%: %.c
$(CC) $(CFLAGS) -o $@ $< $(LDFLAGS)
all: $(EXE)
clean:
rm -f $(EXE)
run: $(filter-out run, $(MAKECMDGOALS))
@for i in $^; do ./$$i; done
.PHONY: all clean run
make run program
항상 불필요한 출력을 생성하므로 약간 어색해 보일 수 있습니다 program is up to date
.
$ cat a.c
#include <stdio.h>
int main(int argc, char **argv) { printf("This is %s\n", argv[0]); return 0; }
$ cp a.c b.c
$ cp a.c c.c
$ make run a b
cc -o a a.c
cc -o b b.c
This is ./a
This is ./b
make: 'a' is up to date.
make: 'b' is up to date.
make program run
그러한 출력이 없으면 영어처럼 더 자연스러울 수도 있습니다.
$ make c run
cc -o c c.c
This is ./c
답변2
당신은 할 수조사하다MAKECMDGOALS
다른 목표를 설정하는 동안 하나의 목표의 존재를 감지합니다. %: %.icl
실행이 target 의 존재를 감지 하도록 하거나 run
, run
target 이라고 불리는 실행 파일을 target 확인하도록 하십시오. 여러 실행 파일을 대상으로 전달하는 경우 첫 번째 방법을 사용하면 각 파일이 빌드 직후에 실행되고, 두 번째 방법을 사용하면 모든 실행이 마지막에 실행됩니다.
이 접근 방식의 단점은 다른 기능과 잘 확장되지 않는다는 것입니다. 예를 들어 여러 실행 파일이 있는 대상을 종속성으로 정의하면 run
대상이 있는 메서드가 작동하지 않습니다.
EXE = foo bar experimental
released: foo bar
run: $(filter $(EXE), $(MAKECMDGOALS))
set -e; for x in $^; do ./$x; done
여기서는 make released run
아무것도 실행되지 않습니다 .
이런 상황에서 내가 일반적으로 하는 일은 각 실행 파일에 대한 "실행" 대상을 정의하는 것입니다. 이를 통해 각 목표를 단일 단어로 표현할 수 있다는 점이 큰 장점입니다. 간단하고 다른 기능을 손상시키지 않습니다.
$(EXE): %.run: %
./$(@:.run=)
all.run: $(EXE:=.run)
make {foo,bar}.run
foo
그런 다음 빌드 하고 테스트하고 싶 bar
거나 make all.run
빌드하고 실행하려면 실행합니다.