Правильный способ обработки ссылок в Makefiles? - PullRequest
1 голос
/ 28 февраля 2012

В настоящее время я работаю над проектом, в котором есть около 20 исходных файлов c и около 8 двоичных целей.Мы находим содержание Makefile довольно сложным и подверженным ошибкам.Основная проблема заключается в записи того, какие двоичные файлы зависят от каких объектных файлов, потому что автоматическое разрешение зависимостей заголовка кажется довольно простым (но мы еще не реализовали его).

Это пример того, как наш make-файл настроен в данный момент.Две программы foo и bar.Foo должен использовать функции, экспортированные из timestamp.c, а bar должен использовать функции, экспортированные из pretty_print.c, который, в свою очередь, использует функции timestamp для генерации строк с метками времени.

foo bar:
     $(CC) -o $@ $^ $(CFLAGS) $(LIBS)

foo: foo.o timestamp.o
foo.o: timestamp.h   

bar: bar.o pretty_print.o timestamp.o
bar.o: pretty_print.h 

pretty_print.o: pretty_print.h timestamp.h

timestamp.o: timestamp.h

Есть ли лучший способ сделать это (кроме автоматической генерации строк foo.o и bar.o)?Я чувствую, что должен быть лучший способ, чем писать, что строка зависит от timestamp.o, когда она не включает timestamp.h.Это источник большинства ошибок на самом деле.Только когда компоновщик не может найти символ «create_timestamp», мы понимаем, что pretty_print опирается на функции из метки времени.Возможно, так оно и есть?

Ответы [ 3 ]

0 голосов
/ 28 февраля 2012

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

Так что на самом деле я бы написал это еще более простым способом:

FOO_OBJS = foo.o timestamp.o
foo: $(FOO_OBJS)
    $(CC) $(LDFLAGS) -o $@ $(FOO_OBJS) $(LIBS)

BAR_OBJS = bar.o pretty_print.o timestamp.o
bar: $(BAR_OBJS)
    $(CC) $(LDFLAGS) -o $@ $(BAR_OBJS) $(LIBS)

Если вы действительно хотите избежать беспокойства о том, какие двоичные цели нужны, какиеРазные объектные файлы, вы можете разделить объектные файлы на канонические, соответствующие каждой двоичной цели (foo.o, bar.o и т. д.) и разные другие, и поместить последние в библиотеку разных компоновщиков:

foo: foo.o libmisc.a
    $(CC) $(LDFLAGS) -o $@ foo.o libmisc.a $(LIBS)

bar: bar.o libmisc.a
    $(CC) $(LDFLAGS) -o $@ bar.o libmisc.a $(LIBS)

MISC_OBJS = pretty_print.o timestamp.o
libmisc.a: $(MISC_OBJS)
    -rm -f $@
    $(AR) rc $@ $(MISC_OBJS)
    -$(RANLIB) $@

Тогда при связывании каждой двоичной цели (foo, bar) будут извлекаться только те разные объектные файлы, которые ей нужны.

0 голосов
/ 28 февраля 2012

Я никогда не пробовал это сам, но для перечисления зависимостей ссылок вы могли бы использовать nm с некоторой простой постобработкой текста.

0 голосов
/ 28 февраля 2012

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

Смотрите "makedepend" или "mkdepend" - так люди обычно делают это на практике. Достаточно часто они поставляются с большинством версий Unix.

...