在Ubuntu 16.04上使用bazel交叉编译tensorflow
鸽了这么久,正式开工
Author: carbon
email: ecras_y@163.com
参考资料:
https://github.com/tensorflow/tensorflow
https://github.com/snipsco/tensorflow-build
年中6月份的时候被抽到AI项目组,有幸接触目前最火的深度学习神经网络,
从开始到现在,一直坚守在google的tensorflow
目前行业的趋势是在PC或者服务器集群上进行训练,然后将训练好的模型export到mobile设备上,
由mobile设备加载使用这些训练好的模型。
我早几年前做过很多嵌入式的项目,所以将tensorflow移植到mobile嵌入式平台上的任务就落到了我的身上,我也当仁不让,
一撸到底。
目前仅支持交叉编译tensorflow的c和c++模块。
python模块由于链接目标库问题,在mobile设备上也没有训练模型的需求,
兼具性能的考虑,暂时没做python这一块的交叉编译支持。感兴趣的同学可以自己试试看。
测试板子使用树莓派,
树莓派可以跑完整的Linux操作系统,如果需要在树莓派上运行基于python的tensorflow,
需要在树莓派上进行编译,但是可能需要编译几天时间
基于以后可能需要将项目export到其它的嵌入式系统上,需要考虑到通用性
Android的编译比较特殊,直接使用官方的预编译好的组件即可
这里只考虑非Android和iOS的嵌入式平台
tensorflow编译使用bazel进行自动化编译管理,涉及到:
1. 子模块网络下载
2. 预编译期代码生成(generate files)
3. 模块之间依赖判定
4. 代码编译
如果将工程更改为Makefile编译,工作量巨大,难以操作
最好的做法还是使用bazel,加入交叉编译支持
bazel交叉编译官方有一些指导文档,有很好的参考意义
https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain
下载源码
使用git命令下载tensorflow源码
git clone git@github.com:tensorflow/tensorflow.git
google在最近发布了tensorflow lite,用于支持mobile设备,
更小的编译目标文件,更好的性能
但是还没有export到最新的tag中,所以这里我们直接基于master分支来操作
git checkout master
git checkout -b cross-compile
文章最后加入对交叉编译tensorflow lite的说明
编译之前需要先修正数据对齐bug
x86和x64平台无对齐问题
但是在某些arm平台上,需要地址对齐,
否则程序会在运行时,访问内存奇数地址或者未对齐地址,导致crash
vim tensorflow/core/lib/gtl/inlined_vector.h +288
将 T* unused_aligner 替换为 uint64_t unused_aligner
强制为8字节对齐
准备交叉编译工具链
这里以树莓派为例
git clone https://github.com/raspberrypi/tools.git
下载完成之后,将工具链路径添加到PATH中
脚本编写
目录结构
.
└── tensorflow
├── armv6-compiler
│ ├── BUILD
│ ├── CROSSTOOL
│ └── cross_toolchain_target_armv6.BUILD
├── build_armv6.sh
├── build_tflite.sh
└── WORKSPACE
1. 修改WORKSPACE文件,添加交叉编译工具链仓库描述
打开WORKSPACE文件,按照bazel的语法在文件末尾添加以下内容
new_local_repository(
name='toolchain_target_armv6',
path='/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf',
build_file = 'armv6-compiler/cross_toolchain_target_armv6.BUILD'
)
参数说明:
交叉编译工具链别名: toolchain_target_armv6
交叉编译工具链路经: /path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf
交叉编译工具链描述文件: armv6-compiler/cross_toolchain_target_armv6.BUILD
2. 编写WORKSPACE仓库引用的交叉编译工具链的BUILD描述文件
mkdir armv6-compiler && cd armv6-compiler
touch cross_toolchain_target_armv6.BUILD
vi cross_toolchain_target_armv6.BUILD
具体语法规则参考详见
https://github.com/bazelbuild/bazel/wiki/Building-with-a-custom-toolchain
脚本内容如下:
package(default_visibility = ['//visibility:public']) filegroup(
name = 'gcc',
srcs = [
'bin/arm-linux-gnueabihf-gcc',
],
) filegroup(
name = 'ar',
srcs = [
'bin/arm-linux-gnueabihf-ar',
],
) filegroup(
name = 'ld',
srcs = [
'bin/arm-linux-gnueabihf-ld',
],
) filegroup(
name = 'nm',
srcs = [
'bin/arm-linux-gnueabihf-nm',
],
) filegroup(
name = 'objcopy',
srcs = [
'bin/arm-linux-gnueabihf-objcopy',
],
) filegroup(
name = 'objdump',
srcs = [
'bin/arm-linux-gnueabihf-objdump',
],
) filegroup(
name = 'strip',
srcs = [
'bin/arm-linux-gnueabihf-strip',
],
) filegroup(
name = 'as',
srcs = [
'bin/arm-linux-gnueabihf-as',
],
) filegroup(
name = 'compiler_pieces',
srcs = glob([
'arm-linux-gnueabihf/**',
'libexec/**',
'lib/gcc/arm-linux-gnueabihf/**',
'include/**',
]),
) filegroup(
name = 'compiler_components',
srcs = [
':gcc',
':ar',
':ld',
':nm',
':objcopy',
':objdump',
':strip',
':as',
],
)
cross_toolchain_target_armv6.BUILD
3. 编写CROSSTOOL文件
CROSSTOOL文件负责描述交叉编译工具链,从编译选项到链接选项,非常繁杂
很多选项是放屁脱裤子,吃力不讨好
愚以为这bazel有点反人类阿
文件内容以下:
major_version: "local"
minor_version: ""
default_target_cpu: "armv6" default_toolchain {
cpu: "armv6"
toolchain_identifier: "arm-linux-gnueabihf"
} default_toolchain {
cpu: "k8"
toolchain_identifier: "local"
} toolchain {
abi_version: "gcc"
abi_libc_version: "glibc_2.23"
builtin_sysroot: ""
compiler: "compiler"
host_system_name: "raspberrypi"
needsPic: true
supports_gold_linker: false
supports_incremental_linker: false
supports_fission: false
supports_interface_shared_objects: false
supports_normalizing_ar: true
supports_start_end_lib: false
supports_thin_archives: true
target_libc: "glibc_2.23"
target_cpu: "armv6"
target_system_name: "raspberrypi"
toolchain_identifier: "arm-linux-gnueabihf" tool_path { name: "ar" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-ar" }
tool_path { name: "compat-ld" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-ld" }
tool_path { name: "cpp" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-cpp" }
tool_path { name: "dwp" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-dwp" }
tool_path { name: "gcc" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc" }
tool_path { name: "gcov" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-gcov" }
tool_path { name: "ld" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-ld" }
tool_path { name: "nm" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-nm" }
tool_path { name: "objcopy" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-objcopy" }
objcopy_embed_flag: "-I"
objcopy_embed_flag: "binary"
tool_path { name: "objdump" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-objdump" }
tool_path { name: "strip" path: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/bin/arm-linux-gnueabihf-strip" } compiler_flag: "-nostdinc"
compiler_flag: "-mfloat-abi=hard"
compiler_flag: "-mfpu=neon-vfpv4"
compiler_flag: "-funsafe-math-optimizations" compiler_flag: "-isystem"
compiler_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/include"
compiler_flag: "-isystem"
compiler_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/usr/include"
compiler_flag: "-isystem"
compiler_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/sysroot/usr/include" compiler_flag: "-isystem"
compiler_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.3/include"
compiler_flag: "-isystem"
compiler_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.3/include-fixed" compiler_flag: "-isystem"
compiler_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/include/c++/4.9.3"
compiler_flag: "-isystem"
compiler_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/include/c++/4.9.3/arm-linux-gnueabihf" cxx_flag: "-isystem"
cxx_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/include"
cxx_flag: "-isystem"
cxx_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/usr/include"
cxx_flag: "-isystem"
cxx_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/sysroot/usr/include"
cxx_flag: "-isystem"
cxx_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/include/c++/4.9.3"
cxx_flag: "-isystem"
cxx_flag: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/include/c++/4.9.3/arm-linux-gnueabihf"
cxx_flag: "-std=c++11" cxx_builtin_include_directory: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/include"
cxx_builtin_include_directory: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/usr/include"
cxx_builtin_include_directory: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/sysroot/usr/include"
cxx_builtin_include_directory: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.3/include"
cxx_builtin_include_directory: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/lib/gcc/arm-linux-gnueabihf/4.9.3/include-fixed"
cxx_builtin_include_directory: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/include/c++/4.9.3"
cxx_builtin_include_directory: "/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/include/c++/4.9.3/arm-linux-gnueabihf" linker_flag: "-lstdc++"
linker_flag: "-L/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/lib"
linker_flag: "-L/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/arm-linux-gnueabihf/lib"
linker_flag: "-L/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot/lib"
linker_flag: "-L/path/to/toolchain/arm-bcm2708/arm-rpi-4.9.3-linux-gnueabihf/arm-linux-gnueabihf/arm-linux-gnueabihf/sysroot/usr/lib"
linker_flag: "-Wl,--dynamic-linker=/lib/ld-linux-armhf.so.3" # Anticipated future default.
# This makes GCC and Clang do what we want when called through symlinks.
unfiltered_cxx_flag: "-no-canonical-prefixes"
linker_flag: "-no-canonical-prefixes" # Make C++ compilation deterministic. Use linkstamping instead of these
# compiler symbols.
unfiltered_cxx_flag: "-Wno-builtin-macro-redefined"
unfiltered_cxx_flag: "-D__DATE__=\"redacted\""
unfiltered_cxx_flag: "-D__TIMESTAMP__=\"redacted\""
unfiltered_cxx_flag: "-D__TIME__=\"redacted\"" # Security hardening on by default.
# Conservative choice; -D_FORTIFY_SOURCE= may be unsafe in some cases.
# We need to undef it before redefining it as some distributions now have
# it enabled by default.
compiler_flag: "-U_FORTIFY_SOURCE"
compiler_flag: "-fstack-protector"
compiler_flag: "-fPIE"
linker_flag: "-pie"
linker_flag: "-Wl,-z,relro,-z,now" # Enable coloring even if there's no attached terminal. Bazel removes the
# escape sequences if --nocolor is specified.
compiler_flag: "-fdiagnostics-color=always" # All warnings are enabled. Maybe enable -Werror as well?
compiler_flag: "-Wall"
# Enable a few more warnings that aren't part of -Wall.
compiler_flag: "-Wunused-but-set-parameter"
# But disable some that are problematic.
compiler_flag: "-Wno-free-nonheap-object" # has false positives # Keep stack frames for debugging, even in opt mode.
compiler_flag: "-fno-omit-frame-pointer" # Stamp the binary with a unique identifier.
linker_flag: "-Wl,--build-id=md5"
linker_flag: "-Wl,--hash-style=gnu" compilation_mode_flags {
mode: DBG
# Enable debug symbols.
compiler_flag: "-g"
}
compilation_mode_flags {
mode: OPT # No debug symbols.
# Maybe we should enable https://gcc.gnu.org/wiki/DebugFission for opt or
# even generally? However, that can't happen here, as it requires special
# handling in Bazel.
compiler_flag: "-g0" # Conservative choice for -O
# -O3 can increase binary size and even slow down the resulting binaries.
# Profile first and / or use FDO if you need better performance than this.
compiler_flag: "-O3" # Disable assertions
compiler_flag: "-DNDEBUG" # Removal of unused code and data at link time (can this increase binary size in some cases?).
compiler_flag: "-ffunction-sections"
compiler_flag: "-fdata-sections"
linker_flag: "-Wl,--gc-sections"
}
} toolchain {
toolchain_identifier: "local"
abi_libc_version: "local"
abi_version: "local"
builtin_sysroot: ""
compiler: "compiler"
compiler_flag: "-U_FORTIFY_SOURCE"
compiler_flag: "-D_FORTIFY_SOURCE=2"
compiler_flag: "-fstack-protector"
compiler_flag: "-Wall"
compiler_flag: "-Wl,-z,-relro,-z,now"
compiler_flag: "-B/usr/bin"
compiler_flag: "-B/usr/bin"
compiler_flag: "-Wunused-but-set-parameter"
compiler_flag: "-Wno-free-nonheap-object"
compiler_flag: "-fno-omit-frame-pointer"
compiler_flag: "-isystem"
compiler_flag: "/usr/include"
cxx_builtin_include_directory: "/usr/include/c++/5.4.0"
cxx_builtin_include_directory: "/usr/include/c++/5"
cxx_builtin_include_directory: "/usr/lib/gcc/x86_64-linux-gnu/5/include"
cxx_builtin_include_directory: "/usr/include/x86_64-linux-gnu/c++/5.4.0"
cxx_builtin_include_directory: "/usr/include/c++/5.4.0/backward"
cxx_builtin_include_directory: "/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include"
cxx_builtin_include_directory: "/usr/local/include"
cxx_builtin_include_directory: "/usr/lib/gcc/x86_64-linux-gnu/5.4.0/include-fixed"
cxx_builtin_include_directory: "/usr/lib/gcc/x86_64-linux-gnu/5/include-fixed"
cxx_builtin_include_directory: "/usr/include/x86_64-linux-gnu"
cxx_builtin_include_directory: "/usr/include"
cxx_flag: "-std=c++11"
host_system_name: "local"
linker_flag: "-lstdc++"
linker_flag: "-lm"
linker_flag: "-Wl,-no-as-needed"
linker_flag: "-B/usr/bin"
linker_flag: "-B/usr/bin"
linker_flag: "-pass-exit-codes"
needsPic: true
objcopy_embed_flag: "-I"
objcopy_embed_flag: "binary"
supports_fission: false
supports_gold_linker: false
supports_incremental_linker: false
supports_interface_shared_objects: false
supports_normalizing_ar: false
supports_start_end_lib: false
supports_thin_archives: false
target_cpu: "k8"
target_libc: "local"
target_system_name: "local"
unfiltered_cxx_flag: "-fno-canonical-system-headers"
unfiltered_cxx_flag: "-Wno-builtin-macro-redefined"
unfiltered_cxx_flag: "-D__DATE__=\"redacted\""
unfiltered_cxx_flag: "-D__TIMESTAMP__=\"redacted\""
unfiltered_cxx_flag: "-D__TIME__=\"redacted\""
tool_path {name: "ar" path: "/usr/bin/ar" }
tool_path {name: "cpp" path: "/usr/bin/cpp" }
tool_path {name: "dwp" path: "/usr/bin/dwp" }
tool_path {name: "gcc" path: "/usr/bin/gcc" }
tool_path {name: "gcov" path: "/usr/bin/gcov" }
tool_path {name: "ld" path: "/usr/bin/ld" }
tool_path {name: "nm" path: "/usr/bin/nm" }
tool_path {name: "objcopy" path: "/usr/bin/objcopy" }
tool_path {name: "objdump" path: "/usr/bin/objdump" }
tool_path {name: "strip" path: "/usr/bin/strip" } compilation_mode_flags {
mode: DBG
compiler_flag: "-g"
}
compilation_mode_flags {
mode: OPT
compiler_flag: "-g0"
compiler_flag: "-O3"
compiler_flag: "-DNDEBUG"
compiler_flag: "-ffunction-sections"
compiler_flag: "-fdata-sections"
linker_flag: "-Wl,--gc-sections"
}
linking_mode_flags { mode: DYNAMIC }
}
CROSSTOOL
toolchain:
有两个描述
一个用于描述交叉编译工具链
一个用于描述本地编译环境
tensorflow编译时会同时用到本地编译环境和交叉编译环境
本地编译描述使用bazel build官网的描述即可
以下为交叉编译描述的一些事项:
abi_libc_version:
target_libc:
可以通过以下代码提前获取
printf("GNU libc version: %s\n", gnu_get_libc_version());
host_system_name:
树莓派3的值是armeabi-v6
Android的一般是armeabi-v7a
全志A33的也是armeabi-v7a
target_cpu:
树莓派3的值是armv6
Android的一般是armeabi-v7a
这个值需要和BUILD文件里面的描述一致
同时编译时--cpu来指定该用哪个交叉编译工具链
tensorflow里面有些依赖的模块BUILD文件描述里会用到这个值,稍后提到
tool_path:
涉及到的变量,替换为交叉编译工具链的绝对路径即可
compiler_flag:
编译选项,由于嵌入式平台,所以-nostdinc是必须的,否则会提示缺失头文件导致编译失败
-isystem 用于设置include的系统头文件目录
可以在交叉编译的工具链目录使用find命令查找
find /path/to/toolchain -name 'include*' -type d
一般找到的目录包括include和include-fixed,而且不会遗漏sysroot中的目录
其实这一步令人非常不解,因为工具链知道自己的头文件目录,根本不需指定
使用这个方法,导致可能会遗漏导致编译失败
cxx_flag:
和compiler_flag大同小异,需要额外指定c++的头文件目录
同时多了一个-std=c++11的值,用于开启c++11的特性
如果工具链不支持c++11,可以关掉
cxx_builtin_include_directory:
我觉得这个值和cxx_flag描述重复了
但是为了避免出错,依葫芦画瓢,把cxx_flag的值重新赋给它即可
linker_flag:
编译链接选项
主要是指定链接库
因为使用了c++11特性,第一个值就是-lstdc++
其它的值可以使用find命令查找
find /path/to/toolchain -name 'lib*' -type d
将查找结果赋值给-L即可
最后一个值是指定linker的加载器
典型值是-Wl,--dynamic-linker=/lib/ld-linux-armhf.so.3
可以在嵌入式设备上使用find命令找到具体的值
find / -name 'ld*' -type f
4. 编写BUILD文件
The BUILD file next to the CROSSTOOL is what ties everything together.
这个BUILD文件负责将以上的东西都串联起来,组成一个交叉编译工具链的完整描述
cc_toolchain_suite:
负责描述所有的编译工具链
里面的值必须和之前的cpu值定义相一致
bazel根据这个文件查找相对应的工具链
其它的选项并不复杂,不做赘述
脚本内容如下:
package(default_visibility = ["//visibility:public"]) cc_toolchain_suite(
name = "toolchain",
toolchains = {
"armv6|compiler": ":cc-compiler-armv6",
"k8|compiler": ":cc-compiler-local",
},
) filegroup(
name = "empty",
srcs = [],
) filegroup(
name = "arm_linux_all_files",
srcs = [
"@toolchain_target_armv6//:compiler_pieces",
],
) cc_toolchain(
name = "cc-compiler-local",
all_files = ":empty",
compiler_files = ":empty",
cpu = "local",
dwp_files = ":empty",
dynamic_runtime_libs = [":empty"],
linker_files = ":empty",
objcopy_files = ":empty",
static_runtime_libs = [":empty"],
strip_files = ":empty",
supports_param_files = ,
) cc_toolchain(
name = "cc-compiler-armv6",
all_files = ":arm_linux_all_files",
compiler_files = ":arm_linux_all_files",
cpu = "armv6",
dwp_files = ":empty",
dynamic_runtime_libs = [":empty"],
linker_files = ":arm_linux_all_files",
objcopy_files = "arm_linux_all_files",
static_runtime_libs = [":empty"],
strip_files = "arm_linux_all_files",
supports_param_files = ,
)
BUILD
5. 编写build_armv6.sh文件
目的是避免每次重复输入命令
使用-march=armv6指定树莓派的架构
查看树莓派官网,树莓派3支持硬件浮点运算,并且支持到neon vfp v4
使用-mfloat-abi=hard -mfpu=neon-vfpv4打开浮点运算硬件支持
gcc需要-funsafe-math-optimizations额外打开浮点运算硬件支持
使用--crosstool_top=//armv6-compiler:toolchain --cpu=armv6 --config=opt
指定编译工具链为树莓派交叉编译工具链
#!/bin/bash
bazel build --copt="-fPIC" --copt="-march=armv6" \
--copt="-mfloat-abi=hard" \
--copt="-mfpu=neon-vfpv4" \
--copt="-funsafe-math-optimizations" \
--copt="-Wno-unused-function" \
--copt="-Wno-sign-compare" \
--copt="-ftree-vectorize" --copt="-fomit-frame-pointer" \
--cxxopt="-Wno-maybe-uninitialized" \
--cxxopt="-Wno-narrowing" \
--cxxopt="-Wno-unused" \
--cxxopt="-Wno-comment" \
--cxxopt="-Wno-unused-function" \
--cxxopt="-Wno-sign-compare" \
--cxxopt="-funsafe-math-optimizations" \
--linkopt="-mfloat-abi=hard" \
--linkopt="-mfpu=neon-vfpv4" \
--linkopt="-funsafe-math-optimizations" \
--verbose_failures \
--crosstool_top=//armv6-compiler:toolchain --cpu=armv6 --config=opt \
tensorflow/examples/label_image/...
build_armv6.sh
6. 在所有编译之前仅而且必须运行一遍configure
jmalloc可以选Yes,但是这里还是建议选No,使用C库的malloc
除了最后一个使用-march=来指定参数,其它一律选No
新版本的代码加入了一个Android交叉编译交互的配置
和本文不相干,选No
7. 编译
运行build_armv6.sh即可开始编译
编译开始时bazel会自动下载依赖组件
同时很快将因为错误停止编译
修正编译错误
1. 编译时bazel会从网络上下载依赖的子模块,需要网络支持,并且需要梯子翻墙
否则会出现如下错误:
java.io.IOException: Error downloading
2. 为nsync添加交叉编译支持
缺乏配置描述,会在编译时出现类似以下错误
external/nsync/BUILD:401:13: Configurable attribute "copts" doesn't match this configuration
根据错误提示,打开nsync对应工程的BUILD文件
vi /path/to/bazel-cache/external/nsync/BUILD
参考android_arm的描述增加树莓派的配置描述
config_setting(
name = "armv6",
values = {"cpu": "armv6"},
)
本来想做个patch贴上来,太懒了,这里先将就
具体代码内容如下:
# -*- mode: python; -*- # nsync is a C library that exports synchronization primitives, such as reader
# writer locks with conditional critical sections, designed to be open sourced
# in portable C. See https://github.com/google/nsync
#
# See public/*.h for API. When compiled with C++11 rather than C, it's in the
# "nsync" name space.
#
# BUILD file usage:
# deps = "@nsync://nsync" for C version
# deps = "@nsync://nsync_cpp" for C++11 version.
# The latter uses no OS-specific system calls or architecture-specific atomic
# operations. package(default_visibility = ["//visibility:public"]) licenses(["notice"]) # Apache 2.0 exports_files(["LICENSE"]) # ---------------------------------------------
# Parameters to the compilation: compiler (e.g., for atomics), architecture
# (e.g., for load and store barrier behaviour), and OS.
# Bazel merges these into one, somewhat slippery, "cpu" string.
# Bazel uses a rather verbose mechanism for choosing which implementations
# are needed on given platforms; hence all the config_setting() rules below. config_setting(
name = "gcc_linux_x86_32_1",
values = {"cpu": "piii"},
) config_setting(
name = "gcc_linux_x86_64_1",
values = {"cpu": "k8"},
) config_setting(
name = "gcc_linux_x86_64_2",
values = {"cpu": "haswell"},
) config_setting(
name = "gcc_linux_aarch64",
values = {"cpu": "arm"},
) config_setting(
name = "gcc_linux_ppc64",
values = {"cpu": "ppc"},
) config_setting(
name = "gcc_linux_s390x",
values = {"cpu": "s390x"},
) config_setting(
name = "clang_macos_x86_64",
values = {"cpu": "darwin"},
) config_setting(
name = "android_x86_32",
values = {"cpu": "x86"},
) config_setting(
name = "android_x86_64",
values = {"cpu": "x86_64"},
) config_setting(
name = "android_armeabi",
values = {"cpu": "armeabi"},
) config_setting(
name = "android_arm",
values = {"cpu": "armeabi-v7a"},
) config_setting(
name = "android_arm64",
values = {"cpu": "arm64-v8a"},
) config_setting(
name = "msvc_windows_x86_64",
values = {"cpu": "x64_windows"},
) config_setting(
name = "freebsd",
values = {"cpu": "freebsd"},
) config_setting(
name = "ios_x86_64",
values = {"cpu": "ios_x86_64"},
) config_setting(
name = "raspberry",
values = {"cpu": "armv6"},
) # ---------------------------------------------
# Compilation options. load(":bazel/pkg_path_name.bzl", "pkg_path_name") # Compilation options that apply to both C++11 and C.
NSYNC_OPTS_GENERIC = select({
# Select the CPU architecture include directory.
# This select() has no real effect in the C++11 build, but satisfies a
# #include that would otherwise need a #if.
":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/x86_32"],
":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/x86_64"],
":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/x86_64"],
":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/aarch64"],
":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/ppc64"],
":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/s390x"],
":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"],
":freebsd": ["-I" + pkg_path_name() + "/platform/x86_64"],
":ios_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"],
":android_x86_32": ["-I" + pkg_path_name() + "/platform/x86_32"],
":android_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"],
":android_armeabi": ["-I" + pkg_path_name() + "/platform/arm"],
":android_arm": ["-I" + pkg_path_name() + "/platform/arm"],
":raspberry": ["-I" + pkg_path_name() + "/platform/arm"],
":android_arm64": ["-I" + pkg_path_name() + "/platform/aarch64"],
":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/x86_64"],
}) + [
"-I" + pkg_path_name() + "/public",
"-I" + pkg_path_name() + "/internal",
"-I" + pkg_path_name() + "/platform/posix",
] + select({
":msvc_windows_x86_64": [
],
":freebsd": ["-pthread"],
"//conditions:default": [
"-D_POSIX_C_SOURCE=200809L",
"-pthread",
],
}) # Options for C build, rather then C++11 build.
NSYNC_OPTS = select({
# Select the OS include directory.
":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/linux"],
":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/linux"],
":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/linux"],
":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/linux"],
":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/linux"],
":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/linux"],
":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/macos"],
":freebsd": ["-I" + pkg_path_name() + "/platform/freebsd"],
":ios_x86_64": ["-I" + pkg_path_name() + "/platform/macos"],
":android_x86_32": ["-I" + pkg_path_name() + "/platform/linux"],
":android_x86_64": ["-I" + pkg_path_name() + "/platform/linux"],
":android_armeabi": ["-I" + pkg_path_name() + "/platform/linux"],
":android_arm": ["-I" + pkg_path_name() + "/platform/linux"],
":raspberry": ["-I" + pkg_path_name() + "/platform/linux"],
":android_arm64": ["-I" + pkg_path_name() + "/platform/linux"],
":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/win32"],
"//conditions:default": [],
}) + select({
# Select the compiler include directory.
":gcc_linux_x86_32_1": ["-I" + pkg_path_name() + "/platform/gcc"],
":gcc_linux_x86_64_1": ["-I" + pkg_path_name() + "/platform/gcc"],
":gcc_linux_x86_64_2": ["-I" + pkg_path_name() + "/platform/gcc"],
":gcc_linux_aarch64": ["-I" + pkg_path_name() + "/platform/gcc"],
":gcc_linux_ppc64": ["-I" + pkg_path_name() + "/platform/gcc"],
":gcc_linux_s390x": ["-I" + pkg_path_name() + "/platform/gcc"],
":clang_macos_x86_64": ["-I" + pkg_path_name() + "/platform/clang"],
":freebsd": ["-I" + pkg_path_name() + "/platform/clang"],
":ios_x86_64": ["-I" + pkg_path_name() + "/platform/clang"],
":android_x86_32": ["-I" + pkg_path_name() + "/platform/gcc"],
":android_x86_64": ["-I" + pkg_path_name() + "/platform/gcc"],
":android_armeabi": ["-I" + pkg_path_name() + "/platform/gcc"],
":android_arm": ["-I" + pkg_path_name() + "/platform/gcc"],
":raspberry": ["-I" + pkg_path_name() + "/platform/gcc"],
":android_arm64": ["-I" + pkg_path_name() + "/platform/gcc"],
":msvc_windows_x86_64": ["-I" + pkg_path_name() + "/platform/msvc"],
}) + select({
# Apple deprecated their atomics library, yet recent versions have no
# working version of stdatomic.h; so some recent versions need one, and
# other versions prefer the other. For the moment, just ignore the
# depreaction.
":clang_macos_x86_64": ["-Wno-deprecated-declarations"],
"//conditions:default": [],
}) + NSYNC_OPTS_GENERIC # Options for C++11 build, rather then C build.
NSYNC_OPTS_CPP = select({
":msvc_windows_x86_64": [
"/TP",
],
"//conditions:default": [
"-x",
"c++",
"-std=c++11",
],
}) + select({
# Some versions of MacOS (notably Sierra) require -D_DARWIN_C_SOURCE
# to include some standard C++11 headers, like <mutex>.
":clang_macos_x86_64": ["-D_DARWIN_C_SOURCE"],
"//conditions:default": [],
}) + [
"-DNSYNC_ATOMIC_CPP11",
"-DNSYNC_USE_CPP11_TIMEPOINT",
"-I" + pkg_path_name() + "/platform/c++11",
] + select({
# must follow the -I...platform/c++11
":ios_x86_64": ["-I" + pkg_path_name() + "/platform/gcc_no_tls"],
":msvc_windows_x86_64": [
"-I" + pkg_path_name() + "/platform/win32",
"-I" + pkg_path_name() + "/platform/msvc",
],
"//conditions:default": ["-I" + pkg_path_name() + "/platform/gcc"],
}) + NSYNC_OPTS_GENERIC # Link options (for tests) built in C (rather than C++11).
NSYNC_LINK_OPTS = select({
":msvc_windows_x86_64": [],
"//conditions:default": ["-pthread"],
}) # Link options (for tests) built in C++11 (rather than C).
NSYNC_LINK_OPTS_CPP = select({
":msvc_windows_x86_64": [],
"//conditions:default": ["-pthread"],
}) # ---------------------------------------------
# Header files the source may include. # Internal library headers.
NSYNC_INTERNAL_HEADERS = [
"internal/common.h",
"internal/dll.h",
"internal/headers.h",
"internal/sem.h",
"internal/wait_internal.h",
] # Internal test headers.
NSYNC_TEST_HEADERS = NSYNC_INTERNAL_HEADERS + [
"testing/array.h",
"testing/atm_log.h",
"testing/closure.h",
"testing/heap.h",
"testing/smprintf.h",
"testing/testing.h",
"testing/time_extra.h",
] # Platform specific headers.
# This declares headers for all platforms, not just the one
# we're building for, to avoid a more complex build file.
NSYNC_INTERNAL_HEADERS_PLATFORM = [
"platform/aarch64/cputype.h",
"platform/alpha/cputype.h",
"platform/arm/cputype.h",
"platform/atomic_ind/atomic.h",
"platform/c++11/atomic.h",
"platform/c++11/platform.h",
"platform/c11/atomic.h",
"platform/clang/atomic.h",
"platform/clang/compiler.h",
"platform/cygwin/platform.h",
"platform/decc/compiler.h",
"platform/freebsd/platform.h",
"platform/gcc/atomic.h",
"platform/gcc/compiler.h",
"platform/gcc_new/atomic.h",
"platform/gcc_new_debug/atomic.h",
"platform/gcc_no_tls/compiler.h",
"platform/gcc_old/atomic.h",
"platform/lcc/compiler.h",
"platform/lcc/nsync_time_init.h",
"platform/linux/platform.h",
"platform/win32/atomic.h",
"platform/macos/platform_c++11_os.h",
"platform/msvc/compiler.h",
"platform/netbsd/atomic.h",
"platform/netbsd/platform.h",
"platform/openbsd/platform.h",
"platform/osf1/platform.h",
"platform/macos/atomic.h",
"platform/macos/platform.h",
"platform/pmax/cputype.h",
"platform/posix/cputype.h",
"platform/posix/nsync_time_init.h",
"platform/posix/platform_c++11_os.h",
"platform/ppc32/cputype.h",
"platform/ppc64/cputype.h",
"platform/s390x/cputype.h",
"platform/shark/cputype.h",
"platform/tcc/compiler.h",
"platform/win32/platform.h",
"platform/win32/platform_c++11_os.h",
"platform/x86_32/cputype.h",
"platform/x86_64/cputype.h",
] # ---------------------------------------------
# The nsync library. # Linux-specific library source.
NSYNC_SRC_LINUX = [
"platform/linux/src/nsync_semaphore_futex.c",
"platform/posix/src/per_thread_waiter.c",
"platform/posix/src/yield.c",
"platform/posix/src/time_rep.c",
"platform/posix/src/nsync_panic.c",
] # Android-specific library source.
NSYNC_SRC_ANDROID = [
"platform/posix/src/nsync_semaphore_sem_t.c",
"platform/posix/src/per_thread_waiter.c",
"platform/posix/src/yield.c",
"platform/posix/src/time_rep.c",
"platform/posix/src/nsync_panic.c",
] # MacOS-specific library source.
NSYNC_SRC_MACOS = [
"platform/posix/src/clock_gettime.c",
"platform/posix/src/nsync_semaphore_mutex.c",
"platform/posix/src/per_thread_waiter.c",
"platform/posix/src/yield.c",
"platform/posix/src/time_rep.c",
"platform/posix/src/nsync_panic.c",
] # Windows-specific library source.
NSYNC_SRC_WINDOWS = [
"platform/posix/src/nsync_panic.c",
"platform/posix/src/per_thread_waiter.c",
"platform/posix/src/time_rep.c",
"platform/posix/src/yield.c",
"platform/win32/src/clock_gettime.c",
"platform/win32/src/init_callback_win32.c",
"platform/win32/src/nanosleep.c",
"platform/win32/src/nsync_semaphore_win32.c",
"platform/win32/src/pthread_cond_timedwait_win32.c",
"platform/win32/src/pthread_key_win32.cc",
] # FreeBSD-specific library source.
NSYNC_SRC_FREEBSD = [
"platform/posix/src/nsync_semaphore_sem_t.c",
"platform/posix/src/per_thread_waiter.c",
"platform/posix/src/yield.c",
"platform/posix/src/time_rep.c",
"platform/posix/src/nsync_panic.c",
] # OS-specific library source.
NSYNC_SRC_PLATFORM = select({
":gcc_linux_x86_32_1": NSYNC_SRC_LINUX,
":gcc_linux_x86_64_1": NSYNC_SRC_LINUX,
":gcc_linux_x86_64_2": NSYNC_SRC_LINUX,
":gcc_linux_aarch64": NSYNC_SRC_LINUX,
":gcc_linux_ppc64": NSYNC_SRC_LINUX,
":gcc_linux_s390x": NSYNC_SRC_LINUX,
":clang_macos_x86_64": NSYNC_SRC_MACOS,
":freebsd": NSYNC_SRC_FREEBSD,
":ios_x86_64": NSYNC_SRC_MACOS,
":android_x86_32": NSYNC_SRC_ANDROID,
":android_x86_64": NSYNC_SRC_ANDROID,
":android_armeabi": NSYNC_SRC_ANDROID,
":android_arm": NSYNC_SRC_ANDROID,
":android_arm64": NSYNC_SRC_ANDROID,
":msvc_windows_x86_64": NSYNC_SRC_WINDOWS,
":raspberry": NSYNC_SRC_LINUX,
}) # C++11-specific (OS and architecture independent) library source.
NSYNC_SRC_PLATFORM_CPP = [
"platform/c++11/src/nsync_semaphore_mutex.cc",
"platform/c++11/src/time_rep_timespec.cc",
"platform/c++11/src/nsync_panic.cc",
"platform/c++11/src/yield.cc",
] + select({
# MacOS and Android don't have working C++11 thread local storage.
":clang_macos_x86_64": ["platform/posix/src/per_thread_waiter.c"],
":android_x86_32": ["platform/posix/src/per_thread_waiter.c"],
":android_x86_64": ["platform/posix/src/per_thread_waiter.c"],
":android_armeabi": ["platform/posix/src/per_thread_waiter.c"],
":android_arm": ["platform/posix/src/per_thread_waiter.c"],
":android_arm64": ["platform/posix/src/per_thread_waiter.c"],
":ios_x86_64": ["platform/posix/src/per_thread_waiter.c"],
":msvc_windows_x86_64": [
"platform/win32/src/clock_gettime.c",
"platform/win32/src/pthread_key_win32.cc",
"platform/c++11/src/per_thread_waiter.cc",
],
"//conditions:default": ["platform/c++11/src/per_thread_waiter.cc"],
}) # Generic library source.
NSYNC_SRC_GENERIC = [
"internal/common.c",
"internal/counter.c",
"internal/cv.c",
"internal/debug.c",
"internal/dll.c",
"internal/mu.c",
"internal/mu_wait.c",
"internal/note.c",
"internal/once.c",
"internal/sem_wait.c",
"internal/time_internal.c",
"internal/wait.c",
] # Generic library header files.
NSYNC_HDR_GENERIC = [
"public/nsync.h",
"public/nsync_atomic.h",
"public/nsync_counter.h",
"public/nsync_cpp.h",
"public/nsync_cv.h",
"public/nsync_debug.h",
"public/nsync_mu.h",
"public/nsync_mu_wait.h",
"public/nsync_note.h",
"public/nsync_once.h",
"public/nsync_time.h",
"public/nsync_time_internal.h",
"public/nsync_waiter.h",
] # The library compiled in C, rather than C++11.
cc_library(
name = "nsync",
srcs = NSYNC_SRC_GENERIC + NSYNC_SRC_PLATFORM,
hdrs = NSYNC_HDR_GENERIC,
copts = NSYNC_OPTS,
includes = ["public"],
textual_hdrs = NSYNC_INTERNAL_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM,
) # The library compiled in C++11, rather than C.
cc_library(
name = "nsync_cpp",
srcs = NSYNC_SRC_GENERIC + NSYNC_SRC_PLATFORM_CPP,
hdrs = NSYNC_HDR_GENERIC,
copts = NSYNC_OPTS_CPP,
includes = ["public"],
textual_hdrs = NSYNC_INTERNAL_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM,
) # nsync_headers provides just the header files for use in projects that need to
# build shared libraries for dynamic loading. Bazel seems unable to cope
# otherwise.
cc_library(
name = "nsync_headers",
hdrs = glob(["public/*.h"]),
includes = ["public"],
) # ---------------------------------------------
# Test code. # Linux-specific test library source.
NSYNC_TEST_SRC_LINUX = [
"platform/posix/src/start_thread.c",
] # Android-specific test library source.
NSYNC_TEST_SRC_ANDROID = [
"platform/posix/src/start_thread.c",
] # MacOS-specific test library source.
NSYNC_TEST_SRC_MACOS = [
"platform/posix/src/start_thread.c",
] # Windows-specific test library source.
NSYNC_TEST_SRC_WINDOWS = [
"platform/win32/src/start_thread.c",
] # FreeBSD-specific test library source.
NSYNC_TEST_SRC_FREEBSD = [
"platform/posix/src/start_thread.c",
] # OS-specific test library source.
NSYNC_TEST_SRC_PLATFORM = select({
":gcc_linux_x86_32_1": NSYNC_TEST_SRC_LINUX,
":gcc_linux_x86_64_1": NSYNC_TEST_SRC_LINUX,
":gcc_linux_x86_64_2": NSYNC_TEST_SRC_LINUX,
":gcc_linux_aarch64": NSYNC_TEST_SRC_LINUX,
":gcc_linux_ppc64": NSYNC_TEST_SRC_LINUX,
":gcc_linux_s390x": NSYNC_TEST_SRC_LINUX,
":clang_macos_x86_64": NSYNC_TEST_SRC_MACOS,
":freebsd": NSYNC_TEST_SRC_FREEBSD,
":ios_x86_64": NSYNC_TEST_SRC_MACOS,
":android_x86_32": NSYNC_TEST_SRC_ANDROID,
":android_x86_64": NSYNC_TEST_SRC_ANDROID,
":android_armeabi": NSYNC_TEST_SRC_ANDROID,
":android_arm": NSYNC_TEST_SRC_ANDROID,
":android_arm64": NSYNC_TEST_SRC_ANDROID,
":msvc_windows_x86_64": NSYNC_TEST_SRC_WINDOWS,
":raspberry": NSYNC_TEST_SRC_LINUX,
}) # C++11-specific (OS and architecture independent) test library source.
NSYNC_TEST_SRC_PLATFORM_CPP = [
"platform/c++11/src/start_thread.cc",
] # Generic test library source.
NSYNC_TEST_SRC_GENERIC = [
"testing/array.c",
"testing/atm_log.c",
"testing/closure.c",
"testing/smprintf.c",
"testing/testing.c",
"testing/time_extra.c",
] # The test library compiled in C, rather than C++11.
cc_library(
name = "nsync_test_lib",
testonly = 1,
srcs = NSYNC_TEST_SRC_GENERIC + NSYNC_TEST_SRC_PLATFORM,
hdrs = ["testing/testing.h"],
copts = NSYNC_OPTS,
textual_hdrs = NSYNC_TEST_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM,
deps = [":nsync"],
) # The test library compiled in C++11, rather than C.
cc_library(
name = "nsync_test_lib_cpp",
testonly = 1,
srcs = NSYNC_TEST_SRC_GENERIC + NSYNC_TEST_SRC_PLATFORM_CPP,
hdrs = ["testing/testing.h"],
copts = NSYNC_OPTS_CPP,
textual_hdrs = NSYNC_TEST_HEADERS + NSYNC_INTERNAL_HEADERS_PLATFORM,
deps = [":nsync_cpp"],
) # ---------------------------------------------
# The tests, compiled in C rather than C++11. cc_test(
name = "counter_test",
size = "small",
srcs = ["testing/counter_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "cv_mu_timeout_stress_test",
size = "small",
srcs = ["testing/cv_mu_timeout_stress_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "cv_test",
size = "small",
srcs = ["testing/cv_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "cv_wait_example_test",
size = "small",
srcs = ["testing/cv_wait_example_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "dll_test",
size = "small",
srcs = ["testing/dll_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "mu_starvation_test",
size = "small",
srcs = ["testing/mu_starvation_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "mu_test",
size = "small",
srcs = ["testing/mu_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "mu_wait_example_test",
size = "small",
srcs = ["testing/mu_wait_example_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "mu_wait_test",
size = "small",
srcs = ["testing/mu_wait_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "note_test",
size = "small",
srcs = ["testing/note_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "once_test",
size = "small",
srcs = ["testing/once_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "pingpong_test",
size = "small",
srcs = ["testing/pingpong_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) cc_test(
name = "wait_test",
size = "small",
srcs = ["testing/wait_test.c"],
copts = NSYNC_OPTS,
linkopts = NSYNC_LINK_OPTS,
deps = [
":nsync",
":nsync_test_lib",
],
) # ---------------------------------------------
# The tests, compiled in C++11, rather than C. cc_test(
name = "counter_cpp_test",
size = "small",
srcs = ["testing/counter_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "cv_mu_timeout_stress_cpp_test",
size = "small",
srcs = ["testing/cv_mu_timeout_stress_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "cv_cpp_test",
size = "small",
srcs = ["testing/cv_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "cv_wait_example_cpp_test",
size = "small",
srcs = ["testing/cv_wait_example_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "dll_cpp_test",
size = "small",
srcs = ["testing/dll_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "mu_starvation_cpp_test",
size = "small",
srcs = ["testing/mu_starvation_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "mu_cpp_test",
size = "small",
srcs = ["testing/mu_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "mu_wait_example_cpp_test",
size = "small",
srcs = ["testing/mu_wait_example_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "mu_wait_cpp_test",
size = "small",
srcs = ["testing/mu_wait_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "note_cpp_test",
size = "small",
srcs = ["testing/note_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "once_cpp_test",
size = "small",
srcs = ["testing/once_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "pingpong_cpp_test",
size = "small",
srcs = ["testing/pingpong_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
) cc_test(
name = "wait_cpp_test",
size = "small",
srcs = ["testing/wait_test.c"],
copts = NSYNC_OPTS_CPP,
linkopts = NSYNC_LINK_OPTS_CPP,
deps = [
":nsync_cpp",
":nsync_test_lib_cpp",
],
)
nsync BUILD
3. 再次运行build_armv6.sh编译即可
如果还出现错误,可以继续返回步骤2,修复错误
也可以给我邮件,但回复可能很慢
编译成功,目标文件生成目录:
bazel-bin/tensorflow/examples/label_image
bazel-bin/tensorflow/libtensorflow_framework.so
bazel并没有执行strip,如果有必要,需要手动执行strip
4. 刚发现最新的代码,使用-O2会触发树莓派交叉编译工具链崩溃
解决办法是,修改CROSSTOOL,更改为-O3
交叉编译tensorflow lite
1. Activate fpu support
vi tensorflow/contrib/lite/kernels/internal/BUILD
Add
config_setting(
name = "armv6",
values = { "cpu": "armv6", },
)
Add value
"armv6": [
"-O2",
"-mfpu=neon-vfpv4",
"-mfloat-abi=hard",
],
to NEON_FLAGS_IF_APPLICABLE
and replace armv7a value with armv6
Add
":armv6": [
":neon_tensor_utils",
],
":armv7a": [
":neon_tensor_utils",
],
to cc_library tensor_utils select options
2. 编译编译脚本sh
#!/bin/bash tflite_model="tensorflow/contrib/lite/kernels/internal:tensor_utils_test"
if [ $@"z" == "z" ]
then
echo "$0 ${tflite_model}"
else
tflite_model=$@
fi
bazel build --copt="-fPIC" --copt="-march=armv6" \
--copt="-mfloat-abi=hard" \
--copt="-mfpu=neon-vfpv4" \
--copt="-funsafe-math-optimizations" \
--copt="-Wno-unused-function" \
--copt="-Wno-sign-compare" \
--copt="-ftree-vectorize" \
--copt="-fomit-frame-pointer" \
--cxxopt='--std=c++11' \
--cxxopt="-Wno-maybe-uninitialized" \
--cxxopt="-Wno-narrowing" \
--cxxopt="-Wno-unused" \
--cxxopt="-Wno-comment" \
--cxxopt="-Wno-unused-function" \
--cxxopt="-Wno-sign-compare" \
--cxxopt="-funsafe-math-optimizations" \
--linkopt="-lstdc++" \
--linkopt="-mfloat-abi=hard" \
--linkopt="-mfpu=neon-vfpv4" \
--linkopt="-funsafe-math-optimizations" \
--verbose_failures \
--strip=always \
--crosstool_top=//armv6-compiler:toolchain --cpu=armv6 --config=opt \
$@
build_tflite.sh
3. 输出库和头文件
libbuiltin_ops.a libframework.a libneon_tensor_utils.a libquantization_util.a libtensor_utils.a
libcontext.a libfarmhash.a libgemm_support.a libportable_tensor_utils.a libstring_util.a
使用find命令和cp命令组合,将它们拷贝出来备用
头文件目录
tensorflow/contrib/lite
bazel-tensorflow/external/flatbuffers/include
4. Build toco
tensorflow lite加载的model文件需要预先使用toco转换格式
5. Configure and Build
configure with -march=native before building toco
bazel build tensorflow/contrib/lite/toco:toco
restore configure to cross compile after toco built
6. Run toco
具体用法参考tensorflow lite官网说明
bazel run --config=opt tensorflow/contrib/lite/toco:toco -- \
--input_file=(pwd)/mobilenet_v1_1.0_224/frozen_graph.pb \
--input_format=TENSORFLOW_GRAPHDEF --output_format=TFLITE \
--output_file=/tmp/mobilenet_v1_1.0_224.lite --inference_type=FLOAT \
--input_type=FLOAT --input_arrays=input \
--output_arrays=MobilenetV1/Predictions/Reshape_1 --input_shapes=1,224,224,3
7. Done
enjoy
https://github.com/tensorflow/tensorflow
在Ubuntu 16.04上使用bazel交叉编译tensorflow的更多相关文章
- 如何在Ubuntu 16.04上安装配置Redis
如何在Ubuntu 16.04上安装配置Redis Redis是一个内存中的键值存储,以其灵活性,性能和广泛的语言支持而闻名.在本指南中,我们将演示如何在Ubuntu 16.04服务器上安装和配置Re ...
- 在 Ubuntu 16.04上安装 vsFTPd
在 Ubuntu 16.04上安装 vsFTPd Ubuntu vsFTPd 关于 vsFTPd vsFTPd 代表 Very Secure File Transfer Protocol Daemon ...
- (译)综合指南:通过Ubuntu 16.04上从Source构建来安装支持GPU的Caffe2
(译)综合指南:通过Ubuntu 16.04上从Source构建来安装支持GPU的Caffe2 译者注: 原文来自:https://tech.amikelive.com/node-706/compre ...
- [eShopOnContainers 学习系列] - 03 - 在远程 Ubuntu 16.04 上配置开发环境
直接把 md 粘出来了,博客园的富文本编辑器换成 markdown,没啥效果呀 ,先凑合吧.实在不行换地方 # 在远程 Ubuntu 16.04 上配置开发环境 ## 零.因 为什么要用这么麻烦的 ...
- 在 Ubuntu 16.04 上安装 Eclipse Oxygen
2017 年 6 月 28 日,Eclipse 社区(the Eclipse Community)发布了 Eclipse Oxygen.本文记录了我在 Ubuntu 16.04 上安装 Eclipse ...
- Ubuntu 16.04上安装SkyEye及测试
说明一下,在Ubuntu 16.04上安装SkyEye方法不是原创,是来自互联网,仅供学习参考. 一.检查支持软件包 gcc,make,vim(optional),ssh,subversionbinu ...
- 如何在Ubuntu 16.04上安装Apache Web服务器
转载自:https://www.howtoing.com/how-to-install-the-apache-web-server-on-ubuntu-16-04 介绍 Apache HTTP服务器是 ...
- Ubuntu 16.04上thunderbird配置163邮箱出现“配置无法被验证-请查看用户名或密码是否正确?”
在Ubuntu 16.04 上用thunderbird配置163免费邮箱时出现的提示信息如图1: 图1 提示信息 网上有不少方法都说是将接收和发出的主机名分别改为 imap.ym.163.com 和 ...
- 如何在Ubuntu 16.04上安装Nginx
原文链接https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04 介绍 Nginx是世 ...
随机推荐
- 快递100API接口调用代码示例
package com.util; import java.io.IOException; import java.io.InputStream; import java.net.MalformedU ...
- Eclipse.导出可执行的jar(包含第3方jar)
1.不包含 第三方jar 的情况: (1)项目右键--> Export... --> 选择"JAR file"(记得有看到有的博客上写的是选择"Runnabl ...
- 史上最强大的40多个纯CSS绘制的图形[转]
今天在国外的网站上看到了很多看似简单却又非常强大的纯CSS绘制的图形,里面有最简单的矩形.圆形和三角形,也有各种常见的多边形,甚至是阴阳太极和网站小图标,真的非常强大,分享给大家. Square(正方 ...
- apache配置文件详解与优化
apache配置文件详解与优化 一.总结 一句话总结:结合apache配置文件中的英文说明和配置详解一起看 1.apache模块配置用的什么标签? IfModule 例如: <IfModule ...
- C#通过WMI读取MAC地址
该方法依赖WMI的系统服务,该服务一般不会被关闭;但如果系统服务缺失或者出现问题,该方法无法取得MAC地址,需要重启Windows Management Instrumentation服务. publ ...
- TTL的具体含义
TTL(Time To Live)生存时间值,在IP数据包从源到目的的整个转发路径上,每经过一个路由器,路由器都会修改这个TTL字段值,具体的做法是把该TTL的值减1,然后再将IP包转发出去.如果在I ...
- Unsupported major.minor version 51.0解决办法(转)
我使用的是Eclipse-jee-indigo + JDK 1.6.23环境,结果使用时出现Unsupported major.minor version 51.0错误提示,下面我来介绍Unsuppo ...
- iptable filter nat MASQUERADE snat dat
在这里,系统会根据IP数据包中的destination ip address中的IP地址对数据包进行分发.如果destination ip adress是本机地址,数据将会被转交给INPUT链.如果不 ...
- IOS-网络(大文件下载)
一.不合理方式 // // ViewController.m // IOS_0131_大文件下载 // // Created by ma c on 16/1/31. // Copyright © 20 ...
- HDU 1045 dfs + 回溯
题目链接:http://acm.hrbust.edu.cn/vj/index.php?/vj/index.php?c=&c=contest-contest&cid=134#proble ...