Scons: как указать зависимость файла для стороннего результата компиляции?

Мне кажется, что цели scons генерируются не в порядке объявления. Моя проблема в том, что мне нужно сначала сгенерировать некоторый код, я использую protoc для обработки файла my.proto в файлы .h и .cc, мне нужен такой псевдокод (как должен выглядеть рабочий код?)

import os
env=Environment(ENV=os.environ,LIBPATH='/usr/local/lib')
env.ShellExecute('protoc', '--outdir=. --out-lang=cpp', 'my.proto')//produces my.cc
myObj=Object('my.cc')//should wait until 'my.cc' is generated by protoc
Dependency(myObj, 'my.cc')
mainObj=Object('main.cpp')

Мой вопрос:

  1. Как указать этот ShellExecution протокола в SConstruct/SConscript?

  2. Как убедиться, что компиляция main.cpp зависит от существования my.cc, другими словами, дождаться генерации my.cc и затем выполнить?


person Troskyvs    schedule 14.09.2018    source источник


Ответы (1)


Ваши наблюдения и предположения верны, SCons не будет выполнять отдельные команды сборки в том порядке, в котором вы перечисляете их в файлах SConstruct. Он будет запускать их на основе зависимостей целей и исходных файлов в вашей сборке, либо определенных неявно (например, заголовок включает в C++), либо явно (через метод Depends()).

Таким образом, вы должны правильно определить и настроить свои зависимости, чтобы SCons выдавал желаемый результат. Для особого случая protoc в вашем примере существует специальный Builder, который поможет вам правильно построить граф зависимостей. Он доступен в нашем ToolsIndex, где также поддерживается множество других языков и диалектов. можно найти.

Эти специальные строители будут выдавать правильные целевые узлы, например. при получении входного файла *.proto, а SCons сможет автоматически определить зависимость между входным файлом protoc и вашей main программой, если вы скажете что-то вроде:

env=Environment(tools=['default','protoc'])
env.Protoc([], "test.proto")
env.Program('main', ['main.cpp'] + Glob('*.cc'))

Glob('*.cc') обнаружит ваши файлы *.cc, исходящие из инструмента protoc, и включит их в качестве зависимостей для вашей конечной цели main.

Вы всегда можете написать свои собственные Builders и Emitters в SCons, что является каноническим способом сделать новые инструменты/связки инструментов известными анализу зависимостей SCons. В Руководстве пользователя, разд. "18 Написание собственных сборщиков" и особенно наше Руководство по ToolsForFools. об этом.

person dirkbaechle    schedule 14.09.2018
comment
Спасибо, но помимо этих внешних инструментов, как сам Scons поддерживает мое требование? Спасибо. - person Troskyvs; 14.09.2018
comment
Я добавил ссылки в документацию проекта. В вашем случае необходимо добавить новый Builder и, возможно, Emitter. Предоставленные ссылки объяснят, как это сделать очень подробно. - person dirkbaechle; 14.09.2018