2015-01-05 2 views
0

Я столкнулся с довольно странной ошибкой, связанной с использованием функции scons Glob в SConscript. Мой сценарий реальной сборки более сложный, но я сузил его до нижеследующего минимального примера.scons error using Glob in SConscript

В базовом SConstruct:

SConscript('SConscript', 
      variant_dir='build') 

Затем в SConscript:

Glob('*.cc') 

Это выходит, с сообщением об ошибке TypeError : Tried to lookup Dir 'build' as a File. Это была протестирована как с V2.1.0 и V2.3.0 ,

Я нашел несколько обходных решений, ни одна из которых не является полностью удовлетворительной.

  • Если я переведу SConscript в подкаталог, то scons работает без ошибок. Однако для этого потребуется, чтобы все дерево src было перемещено в подкаталог, что кажется беспорядочным.
  • Если я создаю каталог build перед запуском scons, scons запускается без ошибок. Однако для этого требуется дополнительный шаг, а пустые каталоги не играют хорошо с git.
  • Я могу добавить строку Execute(Mkdir('build')) до вызова SConscript. Однако это не работает при выполнении сухого хода с scons -n.
  • Я могу вызвать SConscript с duplicate=False, что предотвращает ошибку. Однако, насколько я понимаю документацию, это может привести к ошибкам в сборке, в зависимости от местоположения включенных файлов.

Я шатаюсь и не понимаю основную причину проблемы. Есть ли чистое решение этой проблемы?

Редакция: Было предложено добавить дополнительные сведения о моих намерениях, а не только код, вызывающий сообщение об ошибке. Я пытаюсь создать файл сборки для кросс-компиляции как исполняемых файлов linux, так и исполняемых файлов Windows одновременно.

Во-первых, настройка среды компиляции в SConstruct.

import os 

win32 = Environment() 
win64 = Environment() 
linux = Environment() 

#Define the working directory 
win32['SYS'] = 'win32' 
win64['SYS'] = 'win64' 
linux['SYS'] = 'linux' 

#Define the compilers 
win32.Replace(CXX='i686-w64-mingw32-g++') 
win64.Replace(CXX='x86_64-w64-mingw32-g++') 

#Define the appropriate file formats 
win32.Replace(SHLIBPREFIX='') 
win32.Replace(SHLIBSUFFIX='.dll') 
win32.Replace(PROGSUFFIX='.exe') 
win32.Append(LINKFLAGS='-static') 
win64.Replace(SHLIBPREFIX='') 
win64.Replace(SHLIBSUFFIX='.dll') 
win64.Replace(PROGSUFFIX='.exe') 
win64.Append(LINKFLAGS='-static') 

for env in [win32,win64,linux]: 
    build_dir = os.path.join('build',env['SYS']) 
    exe = SConscript('SConscript', 
        variant_dir=build_dir, 
        exports=['env']) 

Затем, имея фактические правила сборки в SConscript.

Import('env') 

env.Append(CPPPATH=['include']) 

for main in Glob('*.cc'): 
    env.Program([main, Glob('src/*.cc')]) 

Это показывает сообщение об ошибке, показанное выше, когда вызывается с scons -n.

+0

Вы не показываете полное содержимое своего SConstruct и SConscript, так что это не полный пример. Не видя чистого MWE, трудно дать чистое решение. ;) – dirkbaechle

+0

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

+0

Есть ли файл 'build.cc' где-то в ваших исходных папках или на верхнем уровне? – dirkbaechle

ответ

2

Ваша проблема заключается в том, что вы используете variant_dir, чтобы «связать» свою папку с установкой с «.». как ваш исходный каталог. В сочетании с опцией «duplicate = 1» по умолчанию это означает, что SCons пытается реплицировать все источники в «build» ... но последнее также является частью исходной папки. Это открывает двери для всех видов осложнений и круговых зависимостей.

Чистое решение состоит в том, чтобы поместить все источники в свой собственный подкаталог, например. «ЦСИ», так что вы можете ссылаться на содержащуюся в SConscript

SConscript('src/SConscript', variant_dir='build') 

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

Дополнительный совет: Вы можете (и должны) сэкономить время запуска с помощью

win32 = Environment() 
win64 = win32.Clone() 
linux = win32.Clone() 

вместо

win32 = Environment() 
win64 = Environment() 
linux = Environment() 

. В последнем случае вы вынуждаете SCons искать компиляторы/инструменты в вашей системе три раза подряд ... просто сделайте это один раз, затем clone() в разных средах и украсьте их с настройками, специфичными для вашей сборки.

Смежные вопросы