需要帮助使用 Bazel + Linaro 交叉编译 nsync
Need help cross-compiling nsync using Bazel + Linaro
我正在尝试交叉编译 nsync using Bazel and running into the exact same error described in this question,即:
.///platform/c++11/platform.h:29:17: fatal error: mutex: No such file or directory
发布该问题的人似乎和我在同一个 Bazel cross-build tutorial 工作,但他们对根本原因得出了截然不同的结论(即,他们声称这是用户错误,因为输入错误的包含路径)。在我的例子中,所有路径都是正确的,但它们被 nsync 的构建 ignored/overridden。我真的可以使用一些帮助来确定需要进行哪些更改才能使用 Linaro 工具链正确构建 nsync。
这是一个小脚本,可以在我的系统上 100% 地重现问题:
#!/bin/bash
# File: repro-nsync-error.sh
set -euo pipefail
# Work in a temp folder
mkdir tempxxx && cd tempxxx
# Clone the bits
git clone https://github.com/bazelbuild/bazel.git
git clone https://github.com/google/nsync.git
# Copy custom toolchain example files from the Bazel toolchain tutorial into nsync project
cd nsync
cp -a ../bazel/src/test/shell/bazel/testdata/bazel_toolchain_test_data/compilers .
cp -a ../bazel/src/test/shell/bazel/testdata/bazel_toolchain_test_data/tools/arm_compiler ./tools
cat ../bazel/src/test/shell/bazel/testdata/bazel_toolchain_test_data/WORKSPACE.linaro >> ./WORKSPACE
# Set executable bit on wrapper scripts
chmod +x ./tools/arm_compiler/linaro_linux_gcc/arm-linux-gnueabihf-*
# Nix the `.linaro` extension that the Bazel project uses to 'hide' the
# example files during normal Bazel builds, otherwise Bazel won't 'see' them
for file in $(find -name "*.linaro"); do mv "${file}" "$(dirname ${file})/$(basename ${file%.*})"; done
# Attempt to build
bazel build --verbose_failures --crosstool_top=//tools/arm_compiler:toolchain --cpu=armeabi-v7a //:nsync_cpp
这是我 运行 时得到的输出:
$ ./repro-nsync-error.sh
Cloning into 'bazel'...
remote: Counting objects: 305983, done.
remote: Compressing objects: 100% (184/184), done.
remote: Total 305983 (delta 127), reused 273 (delta 104), pack-reused 305624
Receiving objects: 100% (305983/305983), 457.28 MiB | 2.62 MiB/s, done.
Resolving deltas: 100% (188973/188973), done.
Checking connectivity... done.
Cloning into 'nsync'...
remote: Counting objects: 944, done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 944 (delta 10), reused 23 (delta 7), pack-reused 910
Receiving objects: 100% (944/944), 316.81 KiB | 0 bytes/s, done.
Resolving deltas: 100% (496/496), done.
Checking connectivity... done.
WARNING: ignoring http_proxy in environment.
Starting local Bazel server and connecting to it...
.........
INFO: Analysed target //:nsync_cpp (10 packages loaded).
INFO: Found 1 target...
ERROR: /home/evadeflow/Desktop/tempxxx/nsync/BUILD:463:1: C++ compilation of rule '//:nsync_cpp' failed (Exit 1): arm-linux-gnueabihf-gcc failed: error executing command
(cd /home/evadeflow/.cache/bazel/_bazel_evadeflow/595bcf82ccc39f6a61512641b728b082/execroot/__main__ && \
exec env - \
PATH=/home/evadeflow/.virtualenvs/tfbootstrap/bin:/home/evadeflow/.local/bin:/home/evadeflow/.virtualenvs/tfbootstrap/bin:/home/evadeflow/.local/bin:/usr/lib64/qt-3.3/bin:/usr/lib64/ccache:/home/evadeflow/.local/bin:/usr/local/bin:/usr/bin:/home/evadeflow/bin:/usr/local/sbin:/usr/sbin:/home/evadeflow/bin:/home/evadeflow/bin:/home/evadeflow/bin:/home/evadeflow/bin \
PWD=/proc/self/cwd \
tools/arm_compiler/linaro_linux_gcc/arm-linux-gnueabihf-gcc '--sysroot=external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/libc' '-mfloat-abi=hard' -nostdinc -isystem external/org_linaro_components_toolchain_gcc_5_3_1/lib/gcc/arm-linux-gnueabihf/5.3.1/include -isystem external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/libc/usr/include -isystem external/org_linaro_components_toolchain_gcc_5_3_1/lib/gcc/arm-linux-gnueabihf/5.3.1/include-fixed -isystem external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/libc/usr/include -U_FORTIFY_SOURCE -fstack-protector -fPIE '-fdiagnostics-color=always' -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -MD -MF bazel-out/armeabi-v7a-fastbuild/bin/_objs/nsync_cpp/internal/dll.pic.d -fPIC -iquote . -iquote bazel-out/armeabi-v7a-fastbuild/genfiles -iquote external/bazel_tools -iquote bazel-out/armeabi-v7a-fastbuild/genfiles/external/bazel_tools -isystem public -isystem bazel-out/armeabi-v7a-fastbuild/genfiles/public -isystem bazel-out/armeabi-v7a-fastbuild/bin/public -x c++ '-std=c++11' -DNSYNC_ATOMIC_CPP11 -DNSYNC_USE_CPP11_TIMEPOINT -I.///platform/c++11 -I.///platform/gcc -I.///platform/arm -I.///public -I.///internal -I.///platform/posix '-D_POSIX_C_SOURCE=200809L' -pthread -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -c internal/dll.c -o bazel-out/armeabi-v7a-fastbuild/bin/_objs/nsync_cpp/internal/dll.pic.o)
Use --sandbox_debug to see verbose messages from the sandbox
In file included from internal/dll.c:16:0:
.///platform/c++11/platform.h:29:17: fatal error: mutex: No such file or directory
compilation terminated.
Target //:nsync_cpp failed to build
INFO: Elapsed time: 15.023s, Critical Path: 6.77s
INFO: 0 processes.
FAILED: Build did NOT complete successfully
我怀疑为 nsync 编写的 Bazel 构建文件根本无法与 Bazel 自定义工具链教程中概述的交叉构建方法配合使用,但是...我没有足够的 Bazel 经验来知道如何开始将它们冲压成型...
更新 1:我想出了一块拼图。编译失败的文件似乎都有 .c
扩展名,暗示它们应该是 'straight' C 源代码;但是,它们最终包括 platform/c++11/platform.h
,其中包含以下行:
#include <mutex>
工具链的 -isystem
标志将在正确的包含路径中切换—如果文件是使用 g++
编译的。但事实上它们有一个 .c
扩展意味着 arm-linux-gnueabihf-gcc
被用来代替 arm-linux-gnueabihf-g++
,所以 C++ 的 -isystem
标志没有被应用,我们最终得到fatal error: mutex: No such file or directory
.
为了检验这个新出现的假设,我写了这个小脚本:
#!/bin/bash
# File: build.sh
set -euo pipefail
bazel build -s --verbose_failures --crosstool_top=//tools/arm_compiler:toolchain --cpu=armeabi-v7a \
--cxxopt="-isystem external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1/arm-linux-gnueabihf" \
--cxxopt="-isystem external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1" \
--cxxopt="-isystem external/org_linaro_components_toolchain_gcc_5_3_1/include/c++/5.3.1/arm-linux-gnueabihf" \
--cxxopt="-isystem external/org_linaro_components_toolchain_gcc_5_3_1/include/c++/5.3.1" \
//:nsync_cpp
当我 运行 时,它会失败并出现相同的错误,但是如果我 s/cxxopt/copt
和 s/isystem /I
如下所示 - 它会成功编译:
#!/bin/bash
# File: build.sh
set -euo pipefail
bazel build -s --verbose_failures --crosstool_top=//tools/arm_compiler:toolchain --cpu=armeabi-v7a \
--copt="-Iexternal/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1/arm-linux-gnueabihf" \
--copt="-Iexternal/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1" \
--copt="-Iexternal/org_linaro_components_toolchain_gcc_5_3_1/include/c++/5.3.1/arm-linux-gnueabihf" \
--copt="-Iexternal/org_linaro_components_toolchain_gcc_5_3_1/include/c++/5.3.1" \
//:nsync_cpp
所以...我绝对可以看到 'wrong' 编译器标志的应用位置。但我不确定 'right' 解决问题的方法是什么。以上似乎是一种 'brute force' 方法,可能会产生意想不到的副作用[?],所以我仍在寻找更清洁的解决方案。
问题在于,在 CROSSTOOL 中,包含互斥 header 的包含目录仅添加到 C++ 命令行。我可以看到这是怎么回事,mutex 所在的目录是 org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1/mutex
,请注意 c++
。如果您认为该目录对于 C 编译也有效,原则上的解决方法是在 CROSSTOOL 中将 cxx_flag
更改为 compiler_flag
。
你说得对,g++ 与 gcc 不同。 https://github.com/bazelbuild/bazel/issues/4644 有问题。但这与您的问题并没有真正的关系,只有 bazel 没有将 cxx_flags 放入 C 编译命令行,而不是 gcc。还是我遗漏了什么?
而且我建议不要依赖 Bazel 测试数据交叉工具 :)
我正在尝试交叉编译 nsync using Bazel and running into the exact same error described in this question,即:
.///platform/c++11/platform.h:29:17: fatal error: mutex: No such file or directory
发布该问题的人似乎和我在同一个 Bazel cross-build tutorial 工作,但他们对根本原因得出了截然不同的结论(即,他们声称这是用户错误,因为输入错误的包含路径)。在我的例子中,所有路径都是正确的,但它们被 nsync 的构建 ignored/overridden。我真的可以使用一些帮助来确定需要进行哪些更改才能使用 Linaro 工具链正确构建 nsync。
这是一个小脚本,可以在我的系统上 100% 地重现问题:
#!/bin/bash
# File: repro-nsync-error.sh
set -euo pipefail
# Work in a temp folder
mkdir tempxxx && cd tempxxx
# Clone the bits
git clone https://github.com/bazelbuild/bazel.git
git clone https://github.com/google/nsync.git
# Copy custom toolchain example files from the Bazel toolchain tutorial into nsync project
cd nsync
cp -a ../bazel/src/test/shell/bazel/testdata/bazel_toolchain_test_data/compilers .
cp -a ../bazel/src/test/shell/bazel/testdata/bazel_toolchain_test_data/tools/arm_compiler ./tools
cat ../bazel/src/test/shell/bazel/testdata/bazel_toolchain_test_data/WORKSPACE.linaro >> ./WORKSPACE
# Set executable bit on wrapper scripts
chmod +x ./tools/arm_compiler/linaro_linux_gcc/arm-linux-gnueabihf-*
# Nix the `.linaro` extension that the Bazel project uses to 'hide' the
# example files during normal Bazel builds, otherwise Bazel won't 'see' them
for file in $(find -name "*.linaro"); do mv "${file}" "$(dirname ${file})/$(basename ${file%.*})"; done
# Attempt to build
bazel build --verbose_failures --crosstool_top=//tools/arm_compiler:toolchain --cpu=armeabi-v7a //:nsync_cpp
这是我 运行 时得到的输出:
$ ./repro-nsync-error.sh
Cloning into 'bazel'...
remote: Counting objects: 305983, done.
remote: Compressing objects: 100% (184/184), done.
remote: Total 305983 (delta 127), reused 273 (delta 104), pack-reused 305624
Receiving objects: 100% (305983/305983), 457.28 MiB | 2.62 MiB/s, done.
Resolving deltas: 100% (188973/188973), done.
Checking connectivity... done.
Cloning into 'nsync'...
remote: Counting objects: 944, done.
remote: Compressing objects: 100% (24/24), done.
remote: Total 944 (delta 10), reused 23 (delta 7), pack-reused 910
Receiving objects: 100% (944/944), 316.81 KiB | 0 bytes/s, done.
Resolving deltas: 100% (496/496), done.
Checking connectivity... done.
WARNING: ignoring http_proxy in environment.
Starting local Bazel server and connecting to it...
.........
INFO: Analysed target //:nsync_cpp (10 packages loaded).
INFO: Found 1 target...
ERROR: /home/evadeflow/Desktop/tempxxx/nsync/BUILD:463:1: C++ compilation of rule '//:nsync_cpp' failed (Exit 1): arm-linux-gnueabihf-gcc failed: error executing command
(cd /home/evadeflow/.cache/bazel/_bazel_evadeflow/595bcf82ccc39f6a61512641b728b082/execroot/__main__ && \
exec env - \
PATH=/home/evadeflow/.virtualenvs/tfbootstrap/bin:/home/evadeflow/.local/bin:/home/evadeflow/.virtualenvs/tfbootstrap/bin:/home/evadeflow/.local/bin:/usr/lib64/qt-3.3/bin:/usr/lib64/ccache:/home/evadeflow/.local/bin:/usr/local/bin:/usr/bin:/home/evadeflow/bin:/usr/local/sbin:/usr/sbin:/home/evadeflow/bin:/home/evadeflow/bin:/home/evadeflow/bin:/home/evadeflow/bin \
PWD=/proc/self/cwd \
tools/arm_compiler/linaro_linux_gcc/arm-linux-gnueabihf-gcc '--sysroot=external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/libc' '-mfloat-abi=hard' -nostdinc -isystem external/org_linaro_components_toolchain_gcc_5_3_1/lib/gcc/arm-linux-gnueabihf/5.3.1/include -isystem external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/libc/usr/include -isystem external/org_linaro_components_toolchain_gcc_5_3_1/lib/gcc/arm-linux-gnueabihf/5.3.1/include-fixed -isystem external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/libc/usr/include -U_FORTIFY_SOURCE -fstack-protector -fPIE '-fdiagnostics-color=always' -Wall -Wunused-but-set-parameter -Wno-free-nonheap-object -fno-omit-frame-pointer -MD -MF bazel-out/armeabi-v7a-fastbuild/bin/_objs/nsync_cpp/internal/dll.pic.d -fPIC -iquote . -iquote bazel-out/armeabi-v7a-fastbuild/genfiles -iquote external/bazel_tools -iquote bazel-out/armeabi-v7a-fastbuild/genfiles/external/bazel_tools -isystem public -isystem bazel-out/armeabi-v7a-fastbuild/genfiles/public -isystem bazel-out/armeabi-v7a-fastbuild/bin/public -x c++ '-std=c++11' -DNSYNC_ATOMIC_CPP11 -DNSYNC_USE_CPP11_TIMEPOINT -I.///platform/c++11 -I.///platform/gcc -I.///platform/arm -I.///public -I.///internal -I.///platform/posix '-D_POSIX_C_SOURCE=200809L' -pthread -no-canonical-prefixes -Wno-builtin-macro-redefined '-D__DATE__="redacted"' '-D__TIMESTAMP__="redacted"' '-D__TIME__="redacted"' -c internal/dll.c -o bazel-out/armeabi-v7a-fastbuild/bin/_objs/nsync_cpp/internal/dll.pic.o)
Use --sandbox_debug to see verbose messages from the sandbox
In file included from internal/dll.c:16:0:
.///platform/c++11/platform.h:29:17: fatal error: mutex: No such file or directory
compilation terminated.
Target //:nsync_cpp failed to build
INFO: Elapsed time: 15.023s, Critical Path: 6.77s
INFO: 0 processes.
FAILED: Build did NOT complete successfully
我怀疑为 nsync 编写的 Bazel 构建文件根本无法与 Bazel 自定义工具链教程中概述的交叉构建方法配合使用,但是...我没有足够的 Bazel 经验来知道如何开始将它们冲压成型...
更新 1:我想出了一块拼图。编译失败的文件似乎都有 .c
扩展名,暗示它们应该是 'straight' C 源代码;但是,它们最终包括 platform/c++11/platform.h
,其中包含以下行:
#include <mutex>
工具链的 -isystem
标志将在正确的包含路径中切换—如果文件是使用 g++
编译的。但事实上它们有一个 .c
扩展意味着 arm-linux-gnueabihf-gcc
被用来代替 arm-linux-gnueabihf-g++
,所以 C++ 的 -isystem
标志没有被应用,我们最终得到fatal error: mutex: No such file or directory
.
为了检验这个新出现的假设,我写了这个小脚本:
#!/bin/bash
# File: build.sh
set -euo pipefail
bazel build -s --verbose_failures --crosstool_top=//tools/arm_compiler:toolchain --cpu=armeabi-v7a \
--cxxopt="-isystem external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1/arm-linux-gnueabihf" \
--cxxopt="-isystem external/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1" \
--cxxopt="-isystem external/org_linaro_components_toolchain_gcc_5_3_1/include/c++/5.3.1/arm-linux-gnueabihf" \
--cxxopt="-isystem external/org_linaro_components_toolchain_gcc_5_3_1/include/c++/5.3.1" \
//:nsync_cpp
当我 运行 时,它会失败并出现相同的错误,但是如果我 s/cxxopt/copt
和 s/isystem /I
如下所示 - 它会成功编译:
#!/bin/bash
# File: build.sh
set -euo pipefail
bazel build -s --verbose_failures --crosstool_top=//tools/arm_compiler:toolchain --cpu=armeabi-v7a \
--copt="-Iexternal/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1/arm-linux-gnueabihf" \
--copt="-Iexternal/org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1" \
--copt="-Iexternal/org_linaro_components_toolchain_gcc_5_3_1/include/c++/5.3.1/arm-linux-gnueabihf" \
--copt="-Iexternal/org_linaro_components_toolchain_gcc_5_3_1/include/c++/5.3.1" \
//:nsync_cpp
所以...我绝对可以看到 'wrong' 编译器标志的应用位置。但我不确定 'right' 解决问题的方法是什么。以上似乎是一种 'brute force' 方法,可能会产生意想不到的副作用[?],所以我仍在寻找更清洁的解决方案。
问题在于,在 CROSSTOOL 中,包含互斥 header 的包含目录仅添加到 C++ 命令行。我可以看到这是怎么回事,mutex 所在的目录是 org_linaro_components_toolchain_gcc_5_3_1/arm-linux-gnueabihf/include/c++/5.3.1/mutex
,请注意 c++
。如果您认为该目录对于 C 编译也有效,原则上的解决方法是在 CROSSTOOL 中将 cxx_flag
更改为 compiler_flag
。
你说得对,g++ 与 gcc 不同。 https://github.com/bazelbuild/bazel/issues/4644 有问题。但这与您的问题并没有真正的关系,只有 bazel 没有将 cxx_flags 放入 C 编译命令行,而不是 gcc。还是我遗漏了什么?
而且我建议不要依赖 Bazel 测试数据交叉工具 :)