Вывод Force Scons (exe, obj, lib и dll) в конкретный каталог компоновки

Я пытаюсь получить scons для вывода файлов exe, obj, lib и dll в конкретный каталог сборки.

Моя файловая структура выглядит следующим образом:

/projectdir
  /build
    /bin
    /obj
  /source
    /subdirs
    /..
  SConstruct

В принципе, то, что я получаю сейчас, это мой исходный каталог, который загрязняется файлами obj. Я предпочел бы все это в одном месте.

Файл SConstruct выглядит следующим образом:

env.VariantDir('build', 'source', duplicate = 0)
env.Program('Hierarchy', source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])

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

Спасибо

Ответ 1

Самый простой способ, который я нашел, - использовать 2 файла, файл SConstruct и отдельный SConscript.

В SConstruct вы просто вызываете другой файл и указываете каталог для выхода сборки:

# content SConstruct
SConscript('main.scons', variant_dir='build', duplicate=0)

Затем в "main.scons" вы делаете мясо своей сборки. Вы можете забыть о каталогах вариантов в этом файле.

# content of main.scons
env = Environment()
env.Program('Hierarchy',
            source = ['source/sconstest.cpp', 'source/utils/IntUtil.cpp'])

Ответ 2

Не сложно заставить VariantDir работать с использованием только одного файла SConstruct (для небольшого проекта), но он очень запутан, так как конфигурация отличается для однофайлового и двухфайлового использования.

Только SConstruct:

env = Environment()
env.VariantDir('build', 'src', duplicate=0)
files = Glob('build\*.c')
env.Program("build\program", files)

Обратите внимание, что исходные файлы находятся в .\src, но .\build указывается как местоположение. Вывод должен быть также "префикс" с помощью .\build, иначе скомпилированная программа будет находиться в каталоге файла SConstruct.

Когда вы выполняете script, SCons будет скомпилировать файлы *.c из .\src и поместить полученные объекты в .\build.

Неудивительно, что они переименовали BuildDir в VariantDir, чтобы избежать путаницы (без особого успеха).

Ответ 3

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

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

Ответ 4

Я использовал двухфайловый метод, например richq answer, но хотя готовые продукты (libs, programs) попадали в каталог правильных вариантов, объектные файлы все равно попадали в исходный каталог.

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

Мой второй файл scons изначально выглядел так. Обратите внимание на globbing по абсолютному пути - когда я впервые написал это, я не понял, что пути будут автоматически относиться к файлу scons.

import os, inspect
env = Environment()
packageDir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
src = Glob(os.path.join(packageDir, "src/*/*.c*"), strings=True, source=True)
env.Program('Foo', source = src)

И это привело к тому, что *.obj заканчивается под src/и программой под моим вариантом dir. Когда я изменил его на следующее, объектные файлы также перешли к варианту dir:

env = Environment()
src = Glob("src/*/*.c*", strings=True, source=True) 
env.Program('Foo', source = src)

Использование абсолютных путей, вероятно, является ошибкой noob - я относительно новичок как для scons, так и для Python, но я думал, что поделюсь им, если у кого-то будет такая же неприятная проблема.