Waf: Node is created more than once

Решил в своём проекте заменить Make на что-то более современное, желательно, основанное на Python. Вариантов было немного: Scons и Waf. Первый при поверхностном рассмотрении показался несколько сумбурным, к тому же не очень «питоновским». Больше понравился Waf, показался более продуманным, на нём и решил пока остановиться.

Что я пытаюсь сделать:
1. скомпилировать boot32.cc (32-битный код, которому передаёт управление grub2)
2. перевести boot32.o из elf32 в elf64 для будущей линковки с остальным 64-битным кодом
3. скомпилировать все остальные 64-битные исходники (*.cc) в папке
4. прогнать шаблон линковочного скрипта через C-препроцессор
4. слинковать полученные объектные файлы в бинарник ядра

Имею следующий wscript:

APPNAME = 'Toy OS'
VERSION = '0.4'

SUPPORTED_ARCHS = ['x86_64']
DEFAULT_ARCH = 'x86_64'

SUPPORTED_CXXS = ['clang++', 'g++']
DEFAULT_CXX = 'clang++'

SUPPORTED_OPTS = ['0', '1', '3']
DEFAULT_OPT = '3'

def options(opt):
    opt.load('compiler_cxx')

    grp = opt.get_option_group('configure options')
    grp.add_option('', '--arch', dest='arch', default=DEFAULT_ARCH,
                   help="target architecture [default: '%s']" % DEFAULT_ARCH)
    grp.add_option('', '--cxx', dest='CXX', default=DEFAULT_CXX,
                   help="C++ compiler command [default: '%s']" % DEFAULT_CXX)
    grp.add_option('', '--opt', dest='opt', default=DEFAULT_OPT,
                   help="code optimization level [default: '%s']" %DEFAULT_OPT)
    grp.add_option('-d', '--debug', dest='debug', default=False,
                   action='store_true', help='produce debug builds')


def configure(conf):
    conf.load('compiler_cxx')
    conf.find_program('cpp')
    conf.find_program('objcopy')

    options = vars(conf.options)
    cases = [('arch', 'target architecture', SUPPORTED_ARCHS),
             ('CXX', 'C++ compiler', SUPPORTED_CXXS),
             ('opt', 'code optimization level', SUPPORTED_OPTS)]
    for name, desc, supported, in cases:
        if options[name] not in supported:
            conf.fatal('Unsupported %s: %s' % (desc, options[name]))
        conf.env[name] = options[name]
    conf.env.debug = conf.options.debug

    flags = ['-std=c++0x', '-Wall', '-Wextra', '-O%s' % conf.env.opt,
             '-DARCH=%s' % conf.env.arch ]
    if conf.env.debug:
        flags += ['-DDEBUG']
    if conf.env.arch == 'x86_64':
        flags += ['-fno-stack-protector']
        conf.env.cxxflags_boot32 = flags + ['-m32']
        flags += ['-m64']
    conf.env.CXXFLAGS = flags

    conf.env.SHLIB_MARKER, conf.env.STLIB_MARKER = '', ''
    conf.env.LINKFLAGS = ['-nostdlib', '-Wl,--build-id=none',
                          '-Tsrc/%s/linker_script.lds' % conf.env.arch]


def build(bld):
    source, use = [], []
    if bld.env.arch == 'x86_64':
        boot32  = 'src/x86_64/boot32.cc'
        env, env.CXXFLAGS = bld.env.derive(), bld.env.cxxflags_boot32
        bld.objects(source=boot32, target=boot32+'.1.o', env=env)
        bld(rule='objcopy -O elf64-x86-64 ${SRC} ${TGT}',
            source=boot32+'.1.o', target=boot32+'.2.o')
        source += [boot32+'.2.o']

        bld.objects(source=bld.path.ant_glob('src/x86_64/*.cc', excl=boot32),
                    target='objs_x86_64')
        use += ['objs_x86_64']

    lds = 'src/%s/linker_script' % bld.env.arch
    bld(source=lds, target=lds+'.lds', rule='cpp -E -P ${SRC} > ${TGT}')

    bld.program(source=source, use=use, target='toy.bin')

На выходе всё собирается без ошибок (вроде), но в verbose-режиме waf пишет:

* Node /home/ababo/Dropbox/toy/build/src/x86_64/boot32.cc.2.o is created more than once (full message on 'waf -v -v'). The task generators are:
1. 'src/x86_64/boot32.cc.2.o' in /home/ababo/Dropbox/toy
2. 'toy.bin' in /home/ababo/Dropbox/toy

Почему Waf считает, что линковка пересоздаёт boot32.cc.2.o? У меня есть подозрение, что я делаю что-то неправильно (с точки зрения идеологии Waf). В этом случае, буду рад, если поясните. Спасибо.
  • Вопрос задан
  • 2952 просмотра
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы