2016-02-19 15 views
5

Czy ktoś wie, jak użyć przekierowania dokumentu tutaj na przepis?Przepis Makefile z przekierowaniem dokumentu tutaj

test: 
    sh <<EOF 
    echo I Need This 
    echo To Work 
    ls 
    EOF 

nie mogę znaleźć żadnego rozwiązania próbuje zwykły sposób ukośnika (co w zasadzie kończy się poleceniem w jednej linii).

Uzasadnienie:

Mam zestaw receptur wielokreskowych że chcą poprzez innego polecenia (na przykład, SH, dokowanym).

onelinerecipe := echo l1 
define twolinerecipe := 
echo l1 
echo l2 
endef 
define threelinerecipe := 
echo l1 
echo l2 
echo l3 
endef 

# sh as proxy command and proof of concept 
proxy := sh 

test1: 
    $(proxy) <<EOF 
    $(onelinerecipe) 
    EOF 

test2: 
    $(proxy) <<EOF 
    $(twolinerecipe) 
    EOF 

test3: 
    $(proxy) <<EOF 
    $(threelinerecipe) 
    EOF 

Rozwiązanie, które chciałbym uniknąć: przekształć makra multilinii w pojedyncze linie.

define threelinerecipe := 
echo l1; 
echo l2; 
echo l3 
endef 

test3: 
    $(proxy) <<< "$(strip $(threelinerecipe))" 

To działa (ja używam gmake 4.0 i bash jako powłoki make), ale wymaga to zmiany moich przepisów i mam dużo. Pasek usuwa nowe linie, z makra, a następnie wszystko jest napisane w jednym wierszu.

mój koniec celem jest: proxy := docker run ...

+0

Co powiesz na sh -c ''wpisz tutaj swoje polecenia''? – fanton

+0

Możliwy duplikat [Heredoc w pliku Makefile?] (Http://stackoverflow.com/questions/5873025/heredoc-in-a-makefile) – e0k

+0

@ e0k Dodałem kontekst –

Odpowiedz

5

Korzystanie z wiersza .ONESHELL: gdzieś w Makefile wyśle ​​wszystkie linie przepis na jednym wywołaniu powłoki, należy odnaleźć oryginalny Makefile działa zgodnie z oczekiwaniami.

+1

Ważne brakujące uwagi: jego efekt jest globalny, a nie lokalny w stosunku do pojedynczej reguły i przepisu. Jeśli pojawi się w pliku Makefile, wówczas ** wszystkie ** linie receptur ** dla każdego ** celu zostaną dostarczone do pojedynczego wywołania powłoki. Nie powoduje problemów w moim przypadku. Ale zwróć też uwagę, że '.SHELLFLAGS = -ec' jest wymagane, aby zachować domyślne zachowanie make pozostawiając przy błędzie. –

+1

Używam tego rozwiązania od kilku dni i jedyna wada, którą do tej pory miałem, to powtarzające się problemy. Ponieważ z '.ONESHELL:', wiodące '@' są teraz poprawne dla całego przepisu. Dzięki temu selektywne echo (echo jedno polecenie, a nie inne) nie jest już możliwe. Aby rozwiązać ten problem, możesz zmienić tylko przepis, łamiąc regułę, której szukałem: proxy w sposób przezroczysty. W każdym razie jest to jedyne rozwiązanie pozwalające na tutaj-doc, więc go sprawdzam. –

3

Gdy aby widzi blok wielu linii w recepturze (to blok linii zakończonym \ wszystkie oprócz ostatniego) przechodzi że blok un zmodyfikowaliśmy do powłoki. Zasadniczo działa to w bash, oprócz tego tutaj są dokumenty.

Sposobem na to, aby pozbawić wszelkich końcowe \ s, przechodzą następnie uzyskaną ciąg bash „s eval. Robisz to w tworząc, grając z ${.SHELLFLAGS} i ${SHELL}. Możesz użyć obu tych elementów w postaci przeznaczonej dla celu, jeśli chcesz tylko, aby została pobrana dla kilku celów.

.PHONY: heredoc 

heredoc: .SHELLFLAGS = -c eval 
heredoc: SHELL = bash -c 'eval "$${@//\\\\/}"' 

heredoc: 
    @echo First 
    @cat <<-there \ 
     here line1 \ 
     here anotherline \ 
    there 
    @echo Last 

dając

$ make 
First 
here line1 
here anotherline 
Last 

Ostrożnie z tym cytowanie, Eugene. Uwaga na kod: Usuwam wszystkie ukośniki odwrotne, nie tylko te na końcach linii. YMMV.

+0

W szczególności, dziękuję za "Kiedy make widzi blok wieloliniowy w recepturze (tj. Blok wszystkich linii kończących się \, oprócz ostatniego), przekazuje ten blok niezmodyfikowany do powłoki." bit: Próbowałem użyć dokumentu tutaj, gdzie jest on rozwiązywany przez samą technikę. – kostix