Тест на существование цели - PullRequest
1 голос
/ 02 февраля 2012

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

# /SConstruct
<...>
subdirs = ['variant1', 'variant2', 'variant3']
for subdir in subdirs:
    SConscript(dirs=subdir, src_dir=subdir)

# /variant1/SConscript
localEnv = env.Clone() # Duplicates the global Environment so we may modify it without problems
localEnv.Command('../libs/generated.so', '', 'someexternalscript')
<...>

# /variant2/SConscript
localEnv = env.Clone() # Duplicates the global Environment so we may modify it without problems
localEnv.Command('../libs/generated.so', '', 'someexternalscript')
<...>

Это дает предупреждения:

scons: warning: Two different environments were specified for target ../libs/generated.so
                but they appear to have the same action: someexternalscript

Что, конечно, правильно, но я не знаю, как я могу проверить существование цели в варианте SConscripts . А поскольку другие могут позже вызывать SConscripts, я не могу полагаться на наличие глобальных переменных.

Ответы [ 4 ]

0 голосов
/ 23 августа 2016

Если это буквально код, я вижу два способа удалить предупреждение:

# /SConstruct
<...>
subdirs = ['variant1', 'variant2', 'variant3']
for subdir in subdirs:
    SConscript(dirs=subdir, src_dir=subdir)

# /variant1/SConscript
localEnv = env.Clone() # Duplicates the global Environment so we may modify it without problems
localEnv.Command('../libs/generated.so', '', 'someexternalscript')
<...>

# /variant2/SConscript
localEnv = env.Clone() # Duplicates the global Environment so we may modify it without problems
localEnv.Command('../libs/generated.so', '', 'someexternalscript')
<...>

Также обратите внимание, что на самом деле нет двух SConscripts (один в варианте 1 и один в варианте 2, это тот же SConscript.

Первый : вызов некоторого внешнего сценария перед клоном:

# /variant*/SConscript
env.Command('../libs/generated.so', '', 'someexternalscript')
localEnv = env.Clone() # Duplicates the global Environment so we may modify it without problems
<...>

Во-вторых : добавить условную логику и передать флаг с помощью вызова SConscript:

# /SConstruct
<...>
subdirs = ['variant1', 'variant2', 'variant3']
for subdir in subdirs:
    build_generated = (subdir == 'variant1')
    SConscript(dirs=subdir, src_dir=subdir, exports=['env','build_generated'])

# /variant*/SConscript
Import('build_generated','env')
localEnv = env.Clone() # Duplicates the global Environment so we may modify it without problems
if build_generated:
    localEnv.Command('../libs/generated.so', '', 'someexternalscript')
<...>

Наконец : если вы всегда хотите, чтобы этот скрипт вызывался, вы можете поместить вызов в сам SConstruct.

Кроме того, зачем указывать источник для цели как ''?

Эта цель никогда не изменится, по крайней мере, источником должен быть someexternalscript

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

Трудно понять, действительно ли вы считаете .. / libs / generate.so частью сборки или нет.

Если это библиотека, вы ожидаете, что она будет существовать вне сборки, но вы хотите убедиться в этом. Я предлагаю вам использовать Configure, чтобы убедиться, что библиотека существует, и в противном случае вы можете потерпеть неудачу или запустить someexternalscript, чтобы исправить ситуацию.

config = Configure(env)
if not config.CheckLib("generated.so") make_generated_so()

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

Если вы, с другой стороны, рассматриваете ../libs/generated.so как часть сборки, вы должны создать эту цель один раз и сделать зависимые цели зависимыми от этого файла .so, что вы можете сделать это, включив сгенерированный узел как часть целей в env.Program("someprogram",target) или просто выполните env.Depends(sometarget,"generated.so")

0 голосов
/ 23 августа 2016

В этой ситуации я не клонирую среду для этого конкретного процесса.И я не думаю, что вам нужно в вашем примере, так как эта команда ничего не меняет в env.Вы можете клонировать потом.Если эта цель в конечном итоге вызывается из разных сценариев SC с уже клонированными env, то для этой цели доступна одна среда.

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

Итак, SConscript1 создаст: ../libs/generated.so, а SConscript2 создаст тот же ../libs/generated.so - тот же целевой файл.

Вы не можете использовать 2 одинаковые цели (../libs/generated.so в SConscript1 и SConscript2). Вы должны указать другую цель для одной из команд в SConscripts. Например, для команды SConscript2 (../ libs / generate2.so.

но я не знаю, как я могу проверить существование цели в вариант SConscripts

Зачем вам нужно это проверять? Если scons обнаружит цель, нужно построить ее. Вы также можете установить дополнительную зависимость для запуска Command для генерации .so, если какой-либо из исходных файлов будет изменен.

genLibCmd = localEnv.Command('../libs/generated.so', '', 'someexternalscript')
Depends(genLibCmd, [ listOfSrcThatSomeExternalScriptUse ])

Для проверки существующей цели вы можете использовать класс scons Файл:

File('#libs/generated.so').exists()

Но, я уверен - у вас неправильные сценарии, если вы строите одну и ту же цель дважды.

...