Makefile: sed를 올바르게 사용하여 변수를 편집하는 방법

Makefile: sed를 올바르게 사용하여 변수를 편집하는 방법

모든 소스 파일을 수집하여 기본 파일에 대해 컴파일하는 사용자 지정 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 앞에는 $$가 붙습니다.

관련 정보