2016-12-25 4 views
0

В некотором контексте: Я пытаюсь создать общий Makefile с генерацией автоматической зависимости (используя GCC, как описано here, не рекурсивный, который может использоваться с любого уровня моих проектов. С этой целью файлы зависимостей, сгенерированные должен иметь следующий вид:.Как перенаправить вывод в определенный файл в команду sed?

$(DIR)file.o: $(DIR)file.c $(DIR)file.h 

$(DIR)file.h 

таким образом, независимо от уровня добавочного вызова, сделать может правильно расположить файлы

для того, чтобы сделать это, у меня есть следующее неявное правило:

DEPFLAGS = -MT [email protected] -MP -MMD -MF $(word 2,$^).tmp 
COMPILE = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o [email protected] $< 
POSTCOMPILE = sed -E 's|([0-9a-z_.:]*/)?([0-9a-z_.:]+)|$$(DIR)\2|g' $(word 2,$^).tmp > $(word 2,$^) 

%.o: %.c %.dep 
    $(COMPILE) 
    $(POSTCOMPILE) 
    $(RM) $(word 2,$^).tmp 
    touch [email protected] 

СЕПГ призывание заменить любую директорию часть перед именем файла по $(DIR)

Проблема в том, что, поскольку файл зависимостей генерируется после объектного файла, он вызывает файл сборки перелинковать каждый раз. И поэтому я должен добавить команду touch, чтобы быть уверенным, что объектный файл будет считаться актуальным. Что не очень элегантно. Итак, у меня есть вопрос: вместо использования временного файла есть способ напрямую перенаправить выход gcc (который направлен в файл .tmp) в команду sed?

Другими словами, существует ли способ сделать эквивалент перенаправления трубок, но для другого дескриптора потока/файла, чем для stdout?

+0

в GNU sed есть 's/pattern/replacement/w file', который будет писать подстановку в именованный файл. Вы можете использовать 's /.*/&/ w yourFile'. – potong

+0

Ответ на ваш вопрос - нет, нет никакого способа сделать это. В любом случае вам понадобится «touch», так как нет возможности быть на 100% уверенным, что команда sed завершит запись своего файла до того, как компилятор завершит запись объектного файла: они работают параллельно, поэтому вы не можете гарантия, которую вы закончите первым. – MadScientist

ответ

0

Если вы находитесь в полноценной среде Linux, вы действительно можете пропустить создание файла .tmp и напрямую подключить зависимые элементы к sed.

# This is needed, because the default shell does not support 
# process substitution 
SHELL = /bin/bash 

SED_COMMAND = sed -E 's|([0-9a-z_.:]*/)?([0-9a-z_.:]+)|$$(DIR)\2|g' > $(word 2,$^) 
DEPFLAGS = -MT [email protected] -MP -MMD -MF >($(SED_COMMAND)) 
COMPILE = $(CC) $(DEPFLAGS) $(CFLAGS) $(CPPFLAGS) -c -o [email protected] $< 

%.o: %.c %.dep 
     $(COMPILE) 
     touch [email protected] 

Однако, это все еще нуждается в команде touch в конце, по той причине, правильно упоминается в комментариях по @MadScientist выше:

нет никакого способа, чтобы быть 100% уверены, что СЕПГ команда завершит запись своего файла до того, как компилятор завершит запись объектного файла: они работают параллельно, поэтому вы не можете гарантировать, какой из них будет завершен первым.

+0

Thxs, именно это я и искал (несмотря на то, что мне все равно придется прикоснуться к файлу). Это специфично для Linux или для Bash? (Я работаю над Linux и MacOs, так как моя школа использует Mac). – VannTen

+0

Подстановка процесса - это специфичная для bash конструкция, доступная только в некоторых средах: среди них есть настольные Linux и MacOS. – Dario

 Смежные вопросы

  • Нет связанных вопросов^_^