2015-07-29 3 views
1

Я новичок в GNU make, и я читаю «Управление проектами с помощью GNU make - O'Reilly».Статическая библиотека встроенного правила в GNU make

В главе 2, в разделе «Библиотека зданий», в книге представлены два способа обновления архивной библиотеки (статические - .a).

Первый:

libname.a: preq1.o preq2.o 
        $(AR) $(ARFLGS) [email protected] $? 

Второй:

libname.a(preq1.o): preq1.o 
        $(AR) $(ARFLGS) [email protected] $< 

Как libName.a (preq1.o) увеличить производительность обновления статической библиотеки?

Также я предполагаю, что второй формат может быть накладным, если в библиотеке много членов (сотни или тысячи), это правильно?

Это следующее встроенное правило?

(%): % 
# commands to execute (built-in): 
    $(AR) $(ARFLAGS) [email protected] $< 

Заранее спасибо

+1

В первом примере весь архивный файл каждый раз воссоздается с нуля. Во втором примере архив сохраняется, и только один файл объекта preq1.o заменяется новой копией. В любом архиве, который вы, вероятно, найдете и с любой доступной сегодня системой, вряд ли вы сможете сказать разницу, если в вашем архиве не содержится сотни или более объектов. Когда была написана статья, все было намного медленнее, и эти повышения эффективности сделали большую разницу. – MadScientist

+0

@MadScientist: вы должны представить это как ответ – wizurd

+0

@MadScientist Сначала спасибо за ваш ответ, но у меня есть комментарий в первом примере, в архиве будут обновляться устаревшие файлы, потому что я передаю «$?» до "$ (AR)". Итак, я думаю, что оба обновляют только устаревших членов, но в книге говорится, что вторая лучшая? –

ответ

0

Я думаю, что может быть в состоянии предоставить вам несколько более полный ответ на основе моего - также ограниченно - знание GNU Make утилиты. Первая форма рецепта просто указывает, что «libname.a» зависит от следующего списка объектных файлов. Если какой-либо из этих файлов моложе последнего обновленного времени «libname.a», то «libname.a» будет, как говорит MadScientist, полностью воссоздаваться с нуля. В этом смысле «libname.a» ничем не отличается от любой другой цели. Во второй форме сама зависимость НЕ 'libname.a', а временные метки вставки подчиненных объектных файлов в архиве. Здесь «libname.a» вообще не протестирован. Временная метка вставки каждого объектного файла проверяется в архиве и любых файлах DEPENDENT, чья последняя измененная дата моложе соответствующего файла-члена объекта, затем вызывает восстановление объекта-объекта, архив, который должен быть обновлен с помощью файла восстановленного объекта. И тогда объект будет удален, что я лично считаю блестящим. Есть два оговорки; Во-первых, «libname.a» уже должен существовать (даже если это всего лишь пустой файл), прежде чем рецепт make будет работать UNLESS, если вы укажете флаг «-c», вызывающий make, чтобы принудительно создать начальное создание архива. Второй относится к безопасности потоков. Повторное создание элемента архива членом может привести к тому, что несколько рецептов будут выполняться параллельно. В этом случае существует высокая вероятность того, что целевой архив будет поврежден (из-за многолетней проблемы, связанной с несколькими файловыми дескрипторами в архиве), если только директива «noparallel» не указана в верхней части make-файла. Чтобы ответить на вопрос вашего вопроса, вторая форма более эффективна просто потому, что только устаревшие модули компонентов архива перестраиваются и повторно вставлены вместо всего архива, который перестраивается сверху вниз. Надеюсь, это поможет - В.В.

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