Настройка SCons для использования отдельных инструментов для генерации и сборки кода - PullRequest
5 голосов
/ 24 ноября 2011

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

По умолчанию в конфигурации SCons нет явного шага, на котором создаются файлы сборки (.s).

Чтобы обойти это, я создал свой собственный Builder, который испускает файлы сборки.

code_generator = Builder(action = '$CC -$LOTS_OF_FLAGS -S $SOURCE -o $TARGET', suffix = '.s')
env.Append(BUILDERS = {'CodeGenerator':code_generator})

Затем я использую это Builder в моих исходных файлах и передаю полученный NodeList в Program.

for file in Glob('*.c'):
  sources += env.CodeGenerator(file)

env.Program('say_hello', sources) 

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

Однако, когда я пытаюсь заменить соответствующие переменные так, чтобы SCons использовал пользовательский набор инструментов (используя env.Replace(CC='clang')...), генерируется только один файл сборки. Мой пользовательский Builder не вызывается ни для какого другого файла, и SCons пытается установить связь только с одним объектным файлом (который явно не работает)

  1. Как я могу заставить SCons запускать компоновщик на всех файлах и включать те объектные файлы для ссылки?
  2. Есть ли лучший способ выполнить то, что я пытаюсь сделать? Я только начинаю работать с SCons.

1 Ответ

3 голосов
/ 24 ноября 2011

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

В этом случае, я полагаю, вы ищете аргумент ключевого слова single_source, который:

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

При поиске источника Builder single_source необходимо оценить как True (илиэквивалент).Таким образом, ваш код может быть переписан с одной очень незначительной модификацией.

env = Environment()
code_generator = Builder(action = '$CC $CCFLAGS -S $SOURCE -o $TARGET',
                         single_source = 1,
                         suffix = '.s')
env.Replace(CC= 'clang')
env.Append(BUILDERS = {'CodeGenerator' : code_generator})
sources = env.CodeGenerator(file)
env.Program('say_hello', sources)

Что для каталога с файлами: foo.c и bar.c выдает:

scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
clang -S bar.c -o bar.s
as -o bar.o bar.s
clang -S foo.c -o foo.s
as -o foo.o foo.s
clang -o say_hello bar.o foo.o
scons: done building targets.
...