Как заставить генерацию зависимостей работать на C? (Также ... расшифруйте это заявление sed / make!) - PullRequest
0 голосов
/ 26 мая 2010

У меня есть система сборки сборки, которую я пытаюсь расшифровать, что кто-то написал. Я получаю сообщение об ошибке, когда я запускаю его в Redhat System, но не когда я запускаю его в моей системе Solaris. Версии gmake - это одна и та же основная ревизия (одна - на малой ревизии).

Это для сборки проекта на C, а система make имеет глобальный Makefile.global, который наследуется локальным Makefile каждого каталога

Makefile.global содержит все цели, начиная с

 all: $(LIB) $(BIN)

Глобальный файл также имеет следующую строку

 ifndef INCLUDE_GEN_DEPS
 sinclude $(GEN_DEPS)
 endif

где LIB создает библиотеки, а BIN создает двоичные файлы.

прыгая вниз по целям у меня

 $(LIB) : $(GEN_LIB) 

 $(GEN_LIB) : $(GEN_DEPS) $(GEN_OBJS)
      $(AR) $(ARFLAGS) $(GEN_LIB) $(GEN_OBJS)
 $(GEN_DEPS) :
      @set -e; rm -f $@; \
      $(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g' > $@.tmp ; \
      cat $@.tmp > $@ ; \
      cat $@.tmp | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> $@ ; \
      rm $@.tmp
  $(GEN_OBJS) :
       $(CC) $(CFLAGS) $(INCDIRS) -c $(*F).c -lmpi -o $@

Я думаю, что это все соответствующие цели, которые мне нужно включить, чтобы ответить на мой вопрос.

Определения этих переменных:

 CC = icc
 CDEP_FLAG = -M
 CFLAGS = various compiler flags ifdef type flags
 INCDIRS = include directory where all .h files are
 GEN_OBJDIR = /lib/objs
 HOME_SRC = .
 GEN_LIB = lib/$(LIB)
 GEN_DEPDIR=/lib/deps
 GEN_DEPS = $(addprefix $(GEN_DEPDIR)/,$(addsuffix .d,$(basename $(OBJS))))

Я думаю, что это все, что вам нужно. В основном понятно из названий.

Теперь, насколько я могу судить, это создание в / lib / deps файла .d, в котором есть зависимости объекта и источника. Другими словами, для библиотеки utilities.a я получу стек зависимостей utils.o и utils.c, все в файле utils.d

Существует некоторая синтаксическая ошибка, которая генерируется в этом файле, я думаю, потому что я получаю следующую ошибку:

 ../lib/deps/util.d:25: *** target pattern contains no '%'. Stop.
 gmake[2]: *** [all] Error 2
 gmake[1]: *** [all] Error 2
 gmake: *** [all] Error 2

Я не уверен, что моя ошибка связана с генерацией зависимостей или с какой-то дальнейшей нисходящей частью, например с целью генерации объекта?

Если вам нужна дополнительная информация, дайте мне знать, я добавлю в пост

1 Ответ

1 голос
/ 26 мая 2010

Сравните то, что записано в lib / deps / util.d на вашей рабочей (Solaris) машине с нерабочей (redhat), обращая особое внимание на строку 25. Это, вероятно, даст вам хороший совет относительно того, что происходит неправильно.

Если они идентичны, проблема заключается в том, что одноразовая минорная версия.

Если вы отличаетесь, возможно, проблема в некоторой разнице между запущенными инструментами или (более вероятно) различными версиями установленной icc.

редактировать

расшифровка make rule:

$(GEN_DEPS) :
        @set -e; rm -f $@; \
        $(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g' > $@.tmp ; \
        cat $@.tmp > $@ ; \
        cat $@.tmp | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> $@ ; \
        rm $@.tmp

Это правило делает файлы зависимостей в $(GEN_DEPS), которые соответствуют всем исходным файлам с .c, измененным на .d

@set -e; rm -f $@;

Заставить любые ошибки немедленно выйти из этого правила с ошибкой, а не продолжить, и удалить цель, которую мы собираемся восстановить

$(CC) $(CDEP_FLAG) $(CFLAGS) $(INCDIRS) `basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,'` | sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g' > $@.tmp ;

Запустите icc для файла .c, соответствующего файлу .d, который мы пытаемся сгенерировать с флагами, чтобы автоматически генерировать зависимости вместо компиляции. basename $@ | sed 's/\.d/\.c/' | sed 's,^,$(HOME_SRC)/,' предложение переводит имя .d обратно в имя .c.

Передать вывод (который является правилом зависимостей) в сценарий sed sed 's,\(.*\)\.o: ,$(GEN_OBJDIR)/\1.o $@ :,g', который добавит сам файл зависимостей как нечто, зависящее от всего, что icc нашел для файла .o (объект), от которого зависит , Запишите все это во временный файл.

cat $@.tmp > $@ ;

Скопировать временный файл в выходной файл зависимостей.

cat $@.tmp | cut -d: -f2 | grep '\.h' | sed 's,\.h,.h :,g' >> $@ ;

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

rm $@.tmp

Удалить временный файл.

...