Предположим, что у меня есть файл SConstruct
, который выглядит следующим образом:
env = Environment()
env.Program("a", ["a.c", "util.c"])
env.Program("b", ["b.c", "util.c"])
Эта сборка работает корректно без предупреждений об ошибках SCons. Однако, если я изменяю это, чтобы указать разные библиотеки для каждой сборки Program
(фактические библиотеки не актуальны):
env.Program("a", ["a.c", "util.c"], LIBS="m")
env.Program("b", ["b.c", "util.c"], LIBS="c")
то я получаю предупреждение:
scons: warning: Two different environments were specified for target util.o, but they appear to have the same action: $CC -o $TARGET -c $CFLAGS $CCFLAGS $_CCCOMCOM $SOURCES
Это, по-видимому, вызвано создателем Program
, автоматически создающим новую среду для создания источников, хотя это только переменная LIBS
, которая отличается (и поэтому только шаг ссылки должен иметь другую среду). Я могу обойти это, сделав что-то вроде:
util = env.Object("util.c")
env.Program("a", ["a.c"] + util, LIBS="m")
env.Program("b", ["b.c"] + util, LIBS="c")
Для построения util.c
используется один конструктор Object
, а затем с использованием предварительно скомпилированного объектного файла в каждой сборки Program
, тем самым избегая предупреждения. Однако это не обязательно. Есть ли более элегантный способ обойти эту проблему? Или это на самом деле ошибка в SCons, которая должна быть исправлена?
Контекст: у меня есть почти 2000 исходных файлов C, скомпилированных в 20 библиотек и 120 исполняемых файлов с большим количеством общих источников. Я создал файл SConstruct
из предыдущей проприетарной системы сборки, используя преобразование script, которое я написал. Существует около 450 предупреждающих сообщений "Две разные среды", созданных SCons для полной сборки с использованием текущего SConstruct
.