как реализовать csplit в make-файле? - PullRequest
0 голосов
/ 09 мая 2020

Как мне реализовать конкретно A и B в следующем make-файле. : Программисты этого проекта решили упаковать часть своего кода в «модуль» под названием chomp.adt, из которого могут быть сгенерированы связанные файлы cook ie .h и cook ie. cpp. Шаги, необходимые для создания этой программы:

A. Выполните команду

    csplit chomp.adt "/Split Here/"

и скопируйте полученный файл xx00 в файл ie .h.

B. Выполните команду

csplit chomp.adt "/Split Here/"

и скопируйте полученный файл xx01 в ie. cpp.

C. Скомпилируйте cook ie. cpp, чтобы получить cook ie .o.

D. Скомпилируйте mainProg. cpp для создания mainProg.o.

E. Свяжите файлы .o, чтобы создать исполняемую программу с именем playChomp

Как я могу написать make-файл, который будет выполнять ВСЕ эти шаги? Я понимаю, как реализовать C -E Я считаю, это в основном A и B, где я не понимаю, как сделать это правилом. Когда я попытался, я написал A и B как-

cookie.h: csplit chomp.adt
         cp xx00 cookie.h
cookie.cpp: csplit chomp.adt
         cp xx01 cookie.cpp

. Я получил сообщение об ошибке: «Нет правила для создания целевого csplit, необходимого для cook ie. cpp».

1 Ответ

3 голосов
/ 09 мая 2020

Простое правило make-файла имеет синтаксис:

<target> : <prerequisites>
        <recipe>

, где цель - это выходной файл, который должен быть построен, предварительные условия - это входные файлы, используемые для построения цели, а рецепт - это процесс при котором входные файлы превращаются в выходные файлы.

Команда csplit ... является частью рецепта . Его не следует указывать как предварительное условие.

Таким образом, ваше правило должно выглядеть примерно так:

cookie.h: chomp.adt
        csplit $< "/Split Here/"
        cp xx00 $@

cookie.cpp: chomp.adt
        csplit $< "/Split Here/"
        cp xx01 $@

Вы можете прочитать о $< и $@ здесь: https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html Их использовать не обязательно.

Однако приведенные выше правила не идеальны, потому что вы запускаете команду csplit дважды, когда в этом нет необходимости. И если вы попытаетесь запустить make с включенными параллельными сборками (make -jN), это может потерпеть неудачу, потому что оба будут работать одновременно и перезаписать выходные файлы.

Как вы можете сделать лучше, зависит от того, какая версия GNU сделать у вас есть. Если у вас GNU make 4.3, вы можете использовать:

cookie.h cookie.cpp &: chomp.adt
        csplit $< "/Split Here/"
        cp xx00 cookie.h
        cp xx01 cookie.cpp

Это сгруппированная цель, о которой вы можете прочитать здесь: https://www.gnu.org/software/make/manual/html_node/Multiple-Targets.html#index -grouped-target

Если у вас более старая версия, вы можете сыграть с трюком, потому что все цели и предварительные условия начинаются с одного и того же префикса (буква c); это будет выглядеть так:

%ookie.h %ookie.cpp : %homp.adt
        csplit $< "/Split Here/"
        cp xx00 cookie.h
        cp xx01 cookie.cpp

Это шаблонное правило, о котором вы можете прочитать здесь: https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.html

...