Хеш внутри вызова оболочки Makefile вызывает неожиданное поведение - PullRequest
8 голосов
/ 29 января 2012

Следующая команда печатает абсолютный путь к определенному заголовку C ++, в соответствии с тем, где g ++ считает, что он есть.

echo \#include\<ham/hamsterdb.h\> | g++ -M -x c++-header - | grep hamsterdb.hpp | sed -e 's/-:  //' -e 's/ \\//'

В моей системе это выдает: /usr/local/include/ham/hamsterdb.hpp

Я столкнулся с проблемой при попытке запустить это внутри Makefile для установки переменной:

FILE=$(shell echo \#include\<ham/hamsterdb.h\> | g++ -M -x c++-header - | grep hamsterdb.hpp | sed -e 's/-:  //' -e 's/ \\//')

.PHONY spec

spec:
    @echo $(FILE)

Это выводит новую строку.Я думаю, что это хэш ('#'), который работает с make;если я переписываю строку FILE=... следующим образом:

FILE=$(shell echo \#include\<ham/hamsterdb.h\>)

, то на выходе все равно ничего не будет.

Ответы [ 2 ]

11 голосов
/ 29 января 2012

Вы должны дважды покинуть хеш, чтобы использовать его внутри функций: один раз для Make и еще раз для оболочки.

То есть

FILE = $(shell echo \\\#include\ \<ham/hamsterdb.h\>)

Обратите внимание на три обратных слеша вместо двух, как и следовало ожидать. Третий обратный слеш необходим, потому что в противном случае первый выйдет за пределы второго, а хеш все равно не будет экранирован.

UPD.

Другим возможным решением является исключение хеша для Make и использование одинарных кавычек Bash для предотвращения интерпретации хеша как комментария оболочки. Это также устраняет необходимость выхода из пробелов < и >:

FILE = $(shell echo '\#include <ham/hamsterdb.h>')
1 голос
/ 29 января 2012

Вам нужно еще немного процитировать:

FILE=$(shell echo \\\#include\<ham/hamsterdb.h\> ...
                  ^^^

Цитировать один раз для самого make, второй раз для оболочки (оболочка должна «видеть» \#).

...