鸽了这么久,正式开工


  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的更多相关文章

  1. 如何在Ubuntu 16.04上安装配置Redis

    如何在Ubuntu 16.04上安装配置Redis Redis是一个内存中的键值存储,以其灵活性,性能和广泛的语言支持而闻名.在本指南中,我们将演示如何在Ubuntu 16.04服务器上安装和配置Re ...

  2. 在 Ubuntu 16.04上安装 vsFTPd

    在 Ubuntu 16.04上安装 vsFTPd Ubuntu vsFTPd 关于 vsFTPd vsFTPd 代表 Very Secure File Transfer Protocol Daemon ...

  3. (译)综合指南:通过Ubuntu 16.04上从Source构建来安装支持GPU的Caffe2

    (译)综合指南:通过Ubuntu 16.04上从Source构建来安装支持GPU的Caffe2 译者注: 原文来自:https://tech.amikelive.com/node-706/compre ...

  4. [eShopOnContainers 学习系列] - 03 - 在远程 Ubuntu 16.04 上配置开发环境

    直接把 md 粘出来了,博客园的富文本编辑器换成 markdown,没啥效果呀 ,先凑合吧.实在不行换地方   # 在远程 Ubuntu 16.04 上配置开发环境 ## 零.因 为什么要用这么麻烦的 ...

  5. 在 Ubuntu 16.04 上安装 Eclipse Oxygen

    2017 年 6 月 28 日,Eclipse 社区(the Eclipse Community)发布了 Eclipse Oxygen.本文记录了我在 Ubuntu 16.04 上安装 Eclipse ...

  6. Ubuntu 16.04上安装SkyEye及测试

    说明一下,在Ubuntu 16.04上安装SkyEye方法不是原创,是来自互联网,仅供学习参考. 一.检查支持软件包 gcc,make,vim(optional),ssh,subversionbinu ...

  7. 如何在Ubuntu 16.04上安装Apache Web服务器

    转载自:https://www.howtoing.com/how-to-install-the-apache-web-server-on-ubuntu-16-04 介绍 Apache HTTP服务器是 ...

  8. Ubuntu 16.04上thunderbird配置163邮箱出现“配置无法被验证-请查看用户名或密码是否正确?”

    在Ubuntu 16.04 上用thunderbird配置163免费邮箱时出现的提示信息如图1: 图1 提示信息 网上有不少方法都说是将接收和发出的主机名分别改为 imap.ym.163.com 和 ...

  9. 如何在Ubuntu 16.04上安装Nginx

    原文链接https://www.digitalocean.com/community/tutorials/how-to-install-nginx-on-ubuntu-16-04 介绍 Nginx是世 ...

随机推荐

  1. 【Demo】CSS3 动画文字

    效果图: 完整代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> &l ...

  2. POSIX线程接口编程学习心得

    由于实验需要,需要了解下C语言多线程编程的知识,于是学习了下POSIX线程编程的知识,有点心得,记录并分享一下. POSIX(可移植操作系统接口)线程是提高代码响应和性能的有力手段.与标准 fork( ...

  3. POJ 3984 迷宫问题 bfs 难度:0

    http://poj.org/problem?id=3984 典型的迷宫问题,记录最快到达某个点的是哪个点即可 #include <cstdio> #include <cstring ...

  4. Tomcat : Invalid character found in the request target

    Invalid character found in the request target. The valid characters are defined in RFC 7230 and RFC ...

  5. Unit Test Generator 简介

    从Visual Studio 2012开始,创建单元测试从右键菜单中消失了,这让开发者感觉很不习惯.其实创建单元测试并不是消失了,只是独立成一个扩展Unit Test Generator,单独安装这个 ...

  6. PHP网站自动化配置的实现

    一直都在用yii2做项目,有在用自动化配置,但是没有自己去配置过.中午没事去看了下yii的初始化代码,发现都是php而已! yii2初始化项目代码 所以,我们做项目肯定是可以用php做的,于是我新建了 ...

  7. avast! 2014正式版下载

    avast!官方简体中文网站: http://www.avast.com/zh-cn/index avast!官方英文网站: http://www.avast.com/index avast!免费版官 ...

  8. Alpha冲刺(11/10)

    拖鞋旅游队团队事后诸葛亮会议 前言 队名:拖鞋旅游队 组长博客:https://www.cnblogs.com/Sulumer/p/10054510.html 时间:2018-12-1 20:00 地 ...

  9. New Concept English Two 17 43

    $课文41  你把那个叫帽子吗? 422. 'Do you call that a hat?' I said to my wife. “你把那个叫帽子吗?”我对妻子说. 423. 'You needn ...

  10. 如何修改windows系统的host文件

    方法/步骤   首先我们打开我的计算机     然后我们进入C盘的C:\Windows\System32\drivers\etc这个目录下面找到host这个文件   双点击打开,选择计算本打开,这时可 ...