표적마크다운 파일로 슬라이드쇼를 작성한 다음 표시용으로 컴파일하고 웹 서버에 업로드하는 등의 작업을 수행합니다. makefile에 마크다운을 작성한 후 단계를 구성하고 싶습니다.
PROJNAME = `pwd | grep -oP '(\w|-)+' | tail -n 2 | head -n 1 | tr '[:upper:]' '[:lower:]'`
presentation: slides.pandoc
pandoc --self-contained --data-dir=$(HOME)/.pandoc --template=slides/revealjs_niels_tmpl.html -V revealjs-url:$(HOME)/.pandoc/revealjs -V theme:solarized slides.pandoc -f markdown -t revealjs -o $(PROJNAME).html
onlinepresent: $(PROJNAME).html
cp $(PROJNAME).html $(HOME)/Share/index.html
설명하다 PROJNAME
프로젝트 폴더 이름을 찾아 소문자로 변환하세요. 이것을 사용하고 제목에 표시된 메시지를 생성하는 예제 폴더에서 결과는 입니다 ws-anno-ii
. presentation
규칙은 슬라이드쇼를 html로 컴파일하는 데 사용됩니다 pandoc
. 매크로는 PROJNAME
출력 파일의 이름을 정의하는 데 사용됩니다. 마운트된 외부 파일 시스템( )에 파일이 있는 경우 프로젝트 이름( )이 포함된 파일을 중지 onlinepresent
위치 에 복사해야 합니다 make
. 존재하지 않는 경우에는 물론 규칙을 먼저 적용해야 합니다. 하지만 명령을 입력하면 아무 일도 일어나지 않고 메시지가 나타납니다.ws-anno-ii.html
Share
presentation
make
프로세스 make
가 중지되고 Makefile:6: *** multiple target patterns. Stop.
라인을 참조합니다.onlinepresent: $(PROJNAME).html
왜 이런 일이 발생하는지 설명해 줄 수 있는 사람이 있나요?
답변1
make 변수의 값은 PROJNAME
다음과 같습니다.
`pwd | grep -oP '(\w|-)+' | tail -n 2 | head -n 1 | tr '[:upper:]' '[:lower:]'`
백틱 문자는 make에서 특별하지 않습니다. 쉘 명령에서 이 변수를 사용하면 쉘은 역따옴표를 보고 이를 명령 대체로 해석합니다. 그러나 make가 해석하는 변수를 사용하면 백틱은 특별한 작업을 수행하지 않습니다. onlinepresent: $(PROJNAME).html
변수가 확장되면 행은 다음과 같습니다.
onlinepresent: `pwd | grep -oP '(\w|-)+' | tail -n 2 | head -n 1 | tr '[:upper:]' '[:lower:]'`.html
onlinepresent
구문 분석을 , 콜론, `pwd
, \
, grep
, -oP
, , , , , , '(\w|-)+'
, , , , , 콜론, , 콜론, , , 콜론, , 콜론, 으로 둡니다 . 가장 오른쪽 콜론 왼쪽에 여러 단어가 있으므로 "다중 대상 패턴"입니다.|
tail
-n
2
|
head
-n
1
|
tr
'[
upper
]'
'[
lower
]'`.html
make가 읽을 수 있는 위치에서 쉘 명령의 출력을 사용하려면 다음을 호출해야 합니다.shell
기능. 이는 GNU make 기능이며 다른 make 구현에는 영향을 미치지 않습니다.
PROJNAME = $(shell pwd | grep -oP '(\w|-)+' | tail -n 2 | head -n 1 | tr '[:upper:]' '[:lower:]'`)
이렇게 하면 PROJNAME
변수가 소문자로 변환된 작업 디렉터리의 마지막에서 두 번째 구성 요소로 설정됩니다.
현재 디렉터리를 사용하는 것은 취약하다는 점에 유의하십시오. 즉, 다른 디렉터리에서 대상으로 호출하면 makefile이 작동하지 않는다는 의미입니다. PROJNAME
대상까지의 경로에서 계산하는 것이 더 강력합니다. 소문자 부분이 아닌 경우 make 함수를 사용하여 완전히 수행할 수 있습니다(문제가 있는 경우). (코드 분할의 목적은 실제로 경로 이름 구성 요소를 추출하는 것이라고 가정합니다.)
$(notdir $(patsubst %/,%,$(dir $(patsubst %/,%,$(dir $(abspath $@))))))
그러나 GNU make에는 대소문자 변환 도구가 없습니다. 어쨌든 쉘을 호출하는 경우 더 간단하게 만들 수 있습니다.
PROJNAME = $(shell set -x; echo '$(abspath $@)' | awk -F/ '{$$0=tolower($$0); print $$(NF-2)}')
onlinepresent: $(PROJNAME).html
cp $< $$HOME/Share/index.html
$$
makefile에서의 사용에 유의하십시오. 이는 $
쉘 명령의 내용이 됩니다. 이는 변수가 정의될 때가 아니라 사용할 때마다 평가되기 때문에 작동합니다 PROJNAME
(make의 변수 정의는 사용된 경우 각 사용마다 확장되고 =
사용된 경우 읽기 할당 시 확장됩니다 :=
).
답변2
달리고 make onlinepresent
, make
목표를 향해 걷고 onlinepresent
, 무엇이 필요한지 확인하는 $(PROJNAME).html
것은 일종의잘못된...make의 관점에서 보면 직접 제공되는 대상이 없기 때문입니다 $(PROJNAME).html
.
나는 또한 귀하의 할당 PROJNAME
이가능성결과.
사용해 보세요
presentation: slides.pandoc
#your pandoc rule
onlinepresent: presentation
#your mv command
이는 make
목표를 달성하기 위해서는 onlinepresent
목표가 필요하다는 것을 보여줍니다. presentation
그런 다음 대상 표현은 make에게 이것이 필요하다는 것을 알려주므로 새 규칙이거나 수정된 slides.pandoc
규칙인 경우 해당 규칙을 실행합니다.slides.pandoc
또는
다음과 같이 presentation
대상 이름을 바꿀 수도 있습니다.$(PROJNAME).html
$(PROJNAME).html: slides.pandoc
#your pandoc rule
onlinepresent: $(PROJNAME).html
#your mv command