Я вижу случайный сбой сборки из-за автоматически сгенерированных файлов (automake). Как мне создать зависимости между автоматически сгенерированными файлами? - PullRequest
0 голосов
/ 01 мая 2020

Я пытался отладить makefile.am, который иногда вызывает ошибку сборки в make. В этом файле источники генерируются автоматически. c файлами, а заголовки автоматически генерируются .h файлами.

..._SOURCES = @buildDirectory@/x.c
              @buildDirectory@/y.c
              @buildDirectory@/z.c

..._HEADERS = @buildDirectory@/x.h
              @buildDirectory@/y.h
              @buildDirectory@/z.h

Ошибка выглядит следующим образом

<failedproto>.proto: "symbol1" is not defined.
<failedproto>.proto: "symbol2" is not defined.
<failedproto>.proto: "symbol3" is not defined.
...
<failedproto>.proto: warning: Import <failedproto>.proto but not used.
make: *** [<failedproto>.c] Error 1
make: *** Waiting for unfinished jobs....

Все эти символы отображаются в соответствующем .h. Это заставляет меня думать, что. c генерируется перед .h, и это просто прямая гонка. Я добавил как ..._ SOURCES, так и _HEADERS в BUILT_SOURCES, но все еще вижу сбой. Поэтому мой следующий инстинкт - создать зависимость для. c от .h. Как мне это сделать, так как они оба генерируются автоматически? Также приветствуются любые альтернативные решения.

Надеюсь, мое форматирование не сбивает с толку.

Отредактируйте более подробно:

Эти файлы автоматически создаются прототипом. c - c компилятор: https://github.com/protobuf-c/protobuf-c Прото c - c принимает эти файлы .proto и генерирует .pb- c. c и .pb- c .h файлы, заставляя меня думать, что эти два не зависят в конце концов. Также запускается некоторый внутренний код, который генерирует другие файлы .proto, я буду называть их nameX.proto и nameY.proto, которые, в свою очередь, генерируют nameX.pb- c .c / nameX.pb- c .h и nameY.pb- c .c / nameY.pb- c .h. Более точный пример Makefile.am выглядит следующим образом:

..._SOURCES = @buildDirectory@/name.pb-c.c
              @buildDirectory@/nameX.pb-c.c
              @buildDirectory@/nameY.pb-c.c

..._HEADERS = @buildDirectory@/name.pb-c.h
              @buildDirectory@/nameX.pb-c.h
              @buildDirectory@/nameY.pb-c.h

Я пытался отслеживать эти зависимости, и я постараюсь описать, к каким выводам я пришел. nameX.pb- c. c включает соответствующий заголовок nameX.pb- c .h. Этот заголовок включает nameY.pb- c .h, заставляя меня думать, что nameX.proto компилируется в nameX.pb- c .c / nameX.pb- c .h до того, как nameY.proto может быть скомпилировано , Поскольку между nameX.pb- c .h и nameY.pb- c .h существует отношение включения, сборка завершается неудачно, поскольку nameX.pb- c .h требуется nameY.pb- c .h , Это приводит меня к двум правилам, которые я с самого начала подозревал. Эти правила обобщены так:

$(OUT_DIRECTORY)/%nameX.proto:$(SRC_DIRECTORY)/name.proto $(SRC_DIRECTORY)/nameY.proto
        command $(OUT_DIRECTORY) $(FLAGS) $<

$(OUT_DIRECTORY)/%nameX.proto:$(SRC_DIRECTORY)/name.proto 
        command $(OUT_DIRECTORY) $(FLAGS) $<

Может ли это быть проблемой? Что мешает запустить второе правило, если оно действительно нуждается в первом правиле?

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

1 Ответ

1 голос
/ 01 мая 2020

Очень необычно использовать @...@ замен в вашем make-файле, как это. Обычно вы назначаете замену один раз для переменной make, а затем используете вместо нее переменную (помимо того, что она «приятнее для чтения», это позволяет кому-то переопределить это значение в командной строке make, если он этого хочет):

BUILDDIR = @buildDirectory@

..._SOURCES = $(BUILDDIR)/x.c
          $(BUILDDIR)/y.c
          $(BUILDDIR)/z.c

..._HEADERS = $(BUILDDIR)/x.h
          $(BUILDDIR)/y.h
          $(BUILDDIR)/z.h

Кроме того, мне кажется вероятным, что есть стандартные переменные automake, которые могут уже покрывать это значение; если так, то лучше использовать стандартные, чем изобретать новые ... но, очевидно, нет способа узнать, что, не зная больше о вашей среде.

В любом случае, для вашего вопроса нам нужно знать больше об этой автогенерации операция. Как выглядят ваши правила для автогенерации сейчас? Неужели генерация файла. c не может быть выполнена до тех пор, пока не будет создан файл .h? Это необычно.

Если вы перечислите выходной файл, входные файлы и необходимую команду, тогда довольно просто написать правильное правило.

...