Почему waf не может найти путь, который существует?

#waf

#waf

Вопрос:

Допустим, у меня есть файл x.y в /mydir/a/b (в Linux)
Когда я запускаю waf, он не находит файл.

 def configure(context):
    pass

def build(build_context):
    build_context(source='/mydir/a/b/x.y', 
       rule='echo ${SRC} > ${TGT}', 
       target='test.out')
 

Результат: источник не найден: ‘/mydir/a/b/x.y’ в bld(features=[], idx=1, meths=[‘process_rule’, ‘process_source’] …

Хорошо, может быть, тебе нужен относительный путь, Waf? И ты мне ничего не говоришь?

 def build(context):

    path_str = '/mydir/a/b'
    xy_node = context.path.find_dir(path_str)
    if xy_node is None:
        exit ("Error: Failed to find path {}".format(path_str))

    # just refer to the current script
    orig_path = context.path.find_resource('wscript')
    rel_path = xy_node.path_from(orig_path)

    print "Relative path: ", rel_path
 

Результат: Ошибка: не удалось найти path /mydir/a /b

Но этот каталог существует! Что с этим?

И, кстати, относительный путь для некоторого подкаталога (который он может найти) является одноразовым. например, a /b в текущем каталоге приводит к относительному пути «../a / b». Я бы ожидал «a / b».

Ответ №1:

В общем случае в каждом контексте есть (как минимум) два объекта узла: — path: указывает на местоположение wscript — root: указывает на корень файловой системы

Итак, в вашем случае решение заключается в использовании context.root :

 def build(context):
    print context.path.abspath()
    print context.root.abspath()

    print context.root.find_dir('/mydir/a/b')
 

Ответ №2:

Хм, похоже, я нашел ответ на форуме waf-users group, на который ответил сам мистер Надь:

Исходные файлы должны находиться в каталоге верхнего уровня. Вы можете либо:

  • создайте символическую ссылку на исходный каталог
  • скопируйте внешние исходные файлы в каталог сборки (что может вызвать проблемы, если есть структура папок для копирования)
  • установите top в общую папку, такую как ‘/’ (могут потребоваться разрешения для суперпользования, так что в целом это плохая идея)

В заключение рекомендуется добавить символическую ссылку на внешний каталог на этапе настройки. Интересно, как это будет работать, если мне это нужно как в Linux, так и в Windows…

Ответ №3:

Просто передайте узел правилу копирования вместо передачи строки, представляющей путь:

 def build(build_context):
source_node = build_context.root.find_node('/mydir/a/b/x.y')
build_context(source=source_node, 
   rule='echo ${SRC} > ${TGT}', 
   target='test.out')
 

Waf сможет найти файл, даже если он находится за пределами каталога верхнего уровня.

Комментарии:

1. Вместо этого я выбрал SCons — гораздо более интуитивно понятный, и доступно больше справок и документов 🙂

2. В документации Scons указано, что он медленнее, чем CMake ( bitbucket.org/scons/scons/wiki /… ). Это делает его не очень масштабируемым для больших потоков.

3. Однако гораздо более масштабируемый для разработки. Это побеждает