Вывод 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, но я думал, что поделюсь им, если у кого-то будет такая же неприятная проблема.