使用自定义的Clang + Libc++编译Tensorflow(而不是stdlibc++)

6
我正在尝试使用自定义的clang/llvm工具链编译tensorflow,并使用clang的本地libc++(而不是借用Gcc的stdlibc++)。
看起来bazel plain假设每个clang都将使用Gcc的库,因为我得到了这些错误:
$ bazel build --cxxopt=-std=c++11 --cxxopt=-stdlib=libc++ tensorflow:libtensorflow.so
INFO: Found 1 target...
INFO: From Compiling 
external/protobuf/src/google/protobuf/compiler/js/embed.cc [for host]:
external/protobuf/src/google/protobuf/compiler/js/embed.cc:37:12: 
warning: unused variable 'output_file' [-Wunused-const-variable]
const char output_file[] = "well_known_types_embed.cc";
            ^
1 warning generated.
ERROR: /home/hbucher/.cache/bazel/_bazel_hbucher/ad427c7fddd5b68de5e1cfaa7cd8c8cc/external/com_googlesource_code_re2/BUILD:11:1: undeclared inclusion(s) in rule '@com_googlesource_code_re2//:re2':
this rule is missing dependency declarations for the following files included by 'external/com_googlesource_code_re2/re2/bitstate.cc':
  '/home/hbucher/install/include/c++/v1/stddef.h'
  '/home/hbucher/install/include/c++/v1/__config'

我尝试入侵bazel中的tools/cpp/CROSSTOOL,因为一些帖子建议添加该行

cxx_builtin_include_directory: "/home/hbucher/install/include/c++/v1"

但是尝试了很多次都没有成功,似乎没有什么区别。
然后我试图按照bazel教程创建一个自定义工具链。但这篇文章并没有多大帮助,因为他们其实是在编写一个交叉工具链,而我尝试做的是调整现有主机规则,一些我尝试调整其参数的方法被bazel似乎都撤销了。
现在我的github存储库已经到了这个地步:https://github.com/HFTrader/BazelCustomToolchain 然而它无法编译,我甚至无法弄清楚如何开始调试此消息。
$  bazel build --crosstool_top=@hbclang//:toolchain tensorflow:libtensorflow.so                                                                                             
.....................                                                                                                                                                                                                                                                                                                                                   
ERROR: The crosstool_top you specified was resolved to 
'@hbclang//:toolchain', which does not contain a CROSSTOOL file. You can 
use a crosstool from the depot by specifying its label.
INFO: Elapsed time: 2.216s  

我已将以下内容添加到我的tensorflow/WORKSPACE文件中:

new_local_repository(                                                                                                                                                                                                                                                                                                                           
  name="hbclang",                                                                                                                                                                                                                                                                                                                                 
  path="/home/hbucher/BazelCustomToolchain",                                                                                                                                                                                                                                                                                     
  build_file = "/home/hbucher/BazelCustomToolchain/BUILD",      
)

我曾在bazel的谷歌讨论组上提出过这个问题,但他们将我重定向到了stackoverflow。目前我已经快要放弃了。
有人尝试过这个吗?还是说我正在开创先河?
谢谢。
2个回答

3
解决了。虽然不是按照预期的方式,但对我来说有效。
export INSTALL_DIR="$HOME/install"
export CC=$INSTALL_DIR/bin/clang
export CXX=$INSTALL_DIR/bin/clang++
export CXXFLAGS="-stdlib=libc++ -L$INSTALL_DIR/lib"
export LDFLAGS="-L$INSTALL_DIR/lib -lm -lrt"
export LD_LIBRARY_PATH="/usr/lib:/lib/x86_64-linux-gnu/:$INSTALL_DIR/lib"
git clone https://github.com/tensorflow/tensorflow.git tensorflow-github
cd tensorflow-github
mkdir build-tmp && cd build-tmp
cmake ../tensorflow/contrib/cmake/
make -j4

使用cmake易如反掌


是的,不幸的是他们完全放弃了CMake支持。 - Slava
@Slava,他们没有吗? - 0xB00B
@tanishq-banyal 是的,他们确实这样做了。我在他们的 Github 存储库中没有看到 CMakeLists 文件,只有糟糕的 Bazel 构建文件。 - Slava
@Slava 哦,是的,我记错了,他们只支持tflite的CMake。 - 0xB00B

2

[2020-05-24:编辑以使答案保持最新状态。]

简而言之:要使用特定的Clang二进制文件和libc++构建Bazel项目,我用以下方法(其中INSTALL_DIR是我安装llvm的位置):

CC="$INSTALL_DIR/bin/clang" \
BAZEL_CXXOPTS="-stdlib=libc++:-isystem$INSTALL_DIR/include" \
BAZEL_LINKOPTS="-stdlib=libc++" \
BAZEL_LINKLIBS="-L$INSTALL_DIR/lib:-Wl,-rpath,$INSTALL_DIR/lib:-lc++:-lm" \
bazel test //...

背景:

您可以使用--repo_env选项,例如--repo_env=CC=clang,将这些默认值放入您的项目或系统范围内的.bazelrc中。

这种方法使用了Bazel的C++工具链自动配置,它不会尝试在BUILD文件中声明所有工具链输入。这是为了简化用户配置。因此,每当您以Bazel无法知晓的方式修改C++工具链(重新构建llvm等)时,都必须运行bazel clean --expunge来清除缓存,并在下一次重新运行自动配置。

在Bazel中指定C++工具链的强大解决方案是使用CcToolchainConfigInfo。请参阅文档参考资料


Crosstool 文件的作用就是定义 C++ 工具链,这样 Bazel 就不必硬编码任何内容。这使我们能够拥有相同的、相当独立于平台的 BUILD 文件,可在 Linux/Mac/Windows 平台上工作,所有平台相关的逻辑都封装在 Crosstool 中。因此,它实际上比您提到的工具更加健壮。我们付出的代价是增加了复杂性,但我们正在积极努力使它更简单。虽然还没有完全达到,但我现在正在为这个非常使用场景撰写更好的文档。 - hlopko
你的辞令和侮辱让我没有动力去帮助你(我们并没有义务这样做!)。请清楚地描述您的问题,逐一解决。到目前为止,我们已经解决了与您的crosstool及其构建文件相关的问题,然后修复了local_repository问题。您是指clang二进制文件本身的路径还是包含目录?我认为应该是后者,cxx_builtin_include_directory消息应该是解决方案。如果不是,请详细说明您的问题,我就无法理解。 - hlopko
看,我找到了另一种方法——我正在使用箱子中自带的GCC编译tensorflow,并从bazel构建内部构建应用程序,以便我可以使用共享内存进行接口。虽然不是理想的方法,但目前它可以完成工作。如果我找到解决方案,我会在这里发布。 - user4705621
无论我放什么 - 它都找不到工具链。我使用 bazel build --crosstool_top=@hbclang//:toolchain tensorflow:libtensorflow_all.so --cpu=linux_x86_64 运行,并在工具链中放置 cpu="linux_x86_64"compiler="clang",但 bazel 仍然给出 cc_toolchain_suite '@hbclang//:toolchain' does not contain a toolchain for CPU 'linux_x86_64' and compiler 'clang'. - user4705621
这对我来说在本地安装的LLVM 10.0.1和TF主分支上没有起作用。我仍然得到一个链接了libstdc++的二进制文件。 - pooya13

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接