모든 소스 파일을 수집하여 기본 파일에 대해 컴파일하는 사용자 지정 Makefile을 작성하려고 합니다. 먼저 나는 그들의 이름을 수집합니다.
# other sources to compile against (without extensions, separated by spaces)
DEPENDENT_FILES = greet farewell
.o
그런 다음 각 단어에 추가하고 싶습니다 . 셸에서는 여러 가지 방법으로 이 작업을 수행할 수 있습니다.
echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g' # but I know, it's UNIX dependant
# or ...
echo '$DEPENDENT_FILES' | sed 's/[^ ]*/&\.o/g'
greet.o farewell.o
둘 다 터미널에서 결과를 생성하지만 make
프로세스에서는 실패합니다(결과적으로 빈 문자열이 생성됨). 나는 그것들을 다음과 같이 쓴다.
DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g')
# or ...
DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/[^ ]*/&\.o/g')
# but they result in
$(info DEPENDENCIES is $(DEPENDENCIES)) # "DEPENDENCIES is "
여기서 내가 뭘 잘못하고 있는지 모르겠습니다. Makefile의 에코나 파이프와 관련이 있는 것으로 의심되지만 알아낼 수는 없습니다.
나는 다른 접근법을 제안하는 것보다 sed 및 echo 솔루션 작업과 관련된 답변을 선호한다는 점에 유의하십시오. Makefile의 에코 및 파이프 관련 문제가 발생한 것은 이번이 처음이 아니며 여전히 내 접근 방식에 어떤 문제가 있는지 모르겠습니다. 문제입니다.
답변1
그런 다음 각 단어 뒤에 .o를 추가하고 싶습니다.
쉘을 통한 왕복은 필요하지 않습니다. Make는 도움을 줄 만큼 강력합니다.파일 이름에 대한 일반적인 작업
이와 같이. 귀하의 경우에는 설명이 필요 없는 이름을 가진 함수가 필요합니다
addsuffix
.
DEPENDENCIES = $(addsuffix .o, $(DEPENDENT_FILES))
그러면 a.o b.o c.o
입력 목록이 표시 됩니다 a b c
. 더 완전한 예:
units = a b c
inc = $(addsuffix .h,$(units))
obj = $(addsuffix .o,$(units))
myprog: $(obj)
gcc -o $@ $(obj)
header-bundle.h: $(inc)
cat $< >$@
좀 더 복잡한 교체가 필요한 경우 다양한 교체 방법이 있습니다.일반적인 문자열 작업 그러나 충분하다면 파일 작업이 더 편리하고 겸손한 사람들이 이해하기 더 쉽다고 생각합니다.
답변2
이들 구문은 유사점이 많지만 매우 다르기 때문에 매우 주의해서 사용해야 한다는 점을 인식해야 make
합니다 shell
. 게다가 make는 경고에 매우 인색합니다.
코드 make
에 두 가지 문제가 있습니다 .
## bad code
DEPENDENCIES := $(echo '$DEPENDENT_FILES' | sed 's/\>/\.o/g')
- make가 그 의미를 이해하는 방식이기 때문에
GNU make
이름이 붙은 내장 함수 는 없습니다 .echo l
- 외부 유틸리티를 실행해야 할 때 해야 할 일은 gnu make 내장
$(shell ...)
함수를 호출하는 것입니다. - 이제 make 코드를 작성하는 방식에 숨겨진 잠재적인 문제가 있는데 바로 변수입니다
$DEPENDENT_FILES
. make는 이것을 make 변수 $D로 구문 분석하고 그 뒤에 문자열 리터럴 EPENDENT!가 옵니다. 이는 make vars가 괄호나 중괄호로 묶이지 않은 경우 문자가 하나만 있고 나머지는 리터럴 문자열로 처리되기 때문입니다. - eval이 실행 중이 아닌 이상 쉘 vars vegin 앞에는 $$가 붙습니다.