Bazel и автоматически сгенерированные файлы cpp / hpp

Я начинаю использовать Bazel в качестве системы сборки проектов на C ++.

Однако я столкнулся со следующей проблемой:

Я нахожусь в сценарии, когда я автоматически создаю файл file.hpp file.cpp (грамотное программирование).

Чтобы воспроизвести мою проблему, можно просто использовать этот минимальный генератор:

-- file.sh --
#!/bin/sh
echo "int foo();" >> file.hpp
echo "#include \"myLib/file.hpp\"\n\nint foo() { return 2017; }" >> file.cpp

Репо моего проекта: (WORKSPACE - пустой файл)

├── myLib
│   ├── BUILD
│   └── file.sh
└── WORKSPACE

Файл BUILD - это

genrule(
  name = "tangle_file",
  srcs = ["file.sh"],
  outs = ["file.cpp","file.hpp"],
  cmd =  "./$(location file.sh);cp file.cpp $(@D);cp file.hpp $(@D);"
)

cc_library(
    name = "file",
    srcs = ["file.cpp"],
    hdrs = ["file.hpp"],
#    deps = [":tangle_file"],
    visibility = ["//bin:__pkg__"],
)

У меня две проблемы:

Вопрос (A), касающийся части genrule ():

Тот факт, что я должен использовать

cmd =  "./$(location file.sh);cp file.cpp $(@D);cp file.hpp $(@D);"

довольно загадочный.

Моя первая попытка была:

cmd =  "./$(location file.sh)"

Однако в этом случае я получаю следующую ошибку:

объявленный вывод myLib / file.cpp не был создан genrule. Вероятно, это связано с тем, что genrule на самом деле не создавал этот вывод, или потому, что вывод был каталогом, а genrule был запущен удаленно (обратите внимание, что только содержимое объявленных выходных файлов копируется из genrules, запускаемых удаленно)

Вопрос (B), касающийся части cc_library ()

Я не знаю, как сообщить Bazel, что цель : file зависит от цели : tangle_file.

Если я раскомментирую:

deps = [":tangle_file"],

Я получаю следующую ошибку:

в атрибуте deps правила cc_library // myLib: file: genrule правило '// myLib: tangle_file' здесь неуместно (ожидаемые cc_inc_library, cc_library, objc_library, экспериментальные_objc_library или cc_proto_library).


person Picaud Vincent    schedule 01.06.2017    source источник


Ответы (1)


Вопрос (А)

Вы видите ошибку, потому что genrule cmd не запускается внутри своего выходного каталога. Если вы жестко запрограммировали bazel-out/local-fastbuild/genfiles/myLib/file.cpp вместо file.cpp в своем file.sh скрипте, это сработает. Однако рекомендуется, чтобы ваш скрипт принимал в качестве аргумента свой выходной каталог.

Например,

genrule(
  name = "tangle_file",
  srcs = ["file.sh"],
  outs = ["file.cpp","file.hpp"],
  cmd =  "./$(location file.sh) $(@D)"
)

и

#!/bin/sh
echo "int foo();" >> $1/file.hpp
echo "#include \"myLib/file.hpp\"\n\nint foo() { return 2017; }" >> $1/file.cpp

Вопрос (B)

Тот факт, что у вас есть

srcs = ["file.cpp"],
hdrs = ["file.hpp"],

в вашем cc_library это то, что сообщает Bazel, что это зависит от genrule, поскольку genrule создает эти файлы. Если вы хотите сделать его более явным, вы можете использовать синтаксис метки, который делает то же самое:

srcs = ["//myLib:file.cpp"],
hdrs = ["//myLib:file.hpp"],
person Adam    schedule 01.06.2017
comment
Спасибо! Я пропатчил свои файлы согласно вашим объяснениям, и все заработало как шарм! - person Picaud Vincent; 01.06.2017