Как обойти «scons: warning: для цели были указаны две разные среды»

Предположим, у меня есть файл SConstruct , который выглядит следующим образом :

env = Environment()

env.Program("a", ["a.c", "util.c"])
env.Program("b", ["b.c", "util.c"])

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

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

Это похоже на вызывается компоновщиком программ , автоматически создающим новую среду для сборки исходных текстов , даже если отличается только переменная LIBS (а значит, только ссылка шаг должна иметь другую среду). Я могу обойти это, выполнив что-то вроде:

util = env.Object("util.c")
env.Program("a", ["a.c"] + util, LIBS="m")
env.Program("b", ["b.c"] + util, LIBS="c")

Здесь используется один построитель Object для построения util.c , а затем используется предварительно скомпилированный объектный файл в каждой Program , что позволяет избежать предупреждения. Однако в этом нет необходимости. Есть ли более элегантный способ обойти эту проблему? Или это действительно ошибка в SCons, которую следует исправить?

Контекст: у меня есть около 2000 исходных файлов C, скомпилированных примерно в 20 библиотек и 120 исполняемых файлов с множеством общих источников. Я создал файл SConstruct из предыдущей проприетарной системы сборки, используя написанный мной сценарий преобразования. SCons выдает около 450 предупреждающих сообщений «Две разные среды» для полной сборки с использованием моего текущего SConstruct .

26
задан Greg Hewgill 1 June 2011 в 00:23
поделиться

3 ответа

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

env.Program("a", ["a.c", env.Object("util.c")], LIBS="m")
env.Program("b", ["b.c", env.Object("util.c")], LIBS="c")

Это изолирует сборку util.c в одной среде. Хотя он указывается дважды, один раз для каждого Program, SCons не предупреждает об этом, потому что это один и тот же источник, созданный с тем же объектом env. Конечно, в этом случае SCons компилирует источник только один раз.

19
ответ дан 28 November 2019 в 07:50
поделиться

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

env.StaticLibrary ("a", ["a.c","util.c"], LIBS = "m")
env.Program ("b", ["b.c","util.c"], LIBS = ["c","a"])
1
ответ дан 28 November 2019 в 07:50
поделиться

Вы можете использовать функцию Split и пользовательский помощник для упрощения процесса сборки для больших проектов:

def create_objs(SRCS, path=""):
    return [env.Object(path+src+".cpp") for src in SRCS]

prg1 = Split("file_1 file_2 file_N")
prg2 = Split("file_2 file_5 file_8")

env.Program("a", create_objs(prg1), LIBS="x")
env.Program("b", create_objs(prg2), LIBS="y")

Объектные файлы создаются только один раз и могут использоваться в нескольких сборках. Надеюсь, это поможет ...

9
ответ дан 28 November 2019 в 07:50
поделиться
Другие вопросы по тегам:

Похожие вопросы: