Cross-Compiling TensorFlow Lite for ZYNQ 7000 (ARMv7-A + VFPv3)
If you’re like me — wrestling with the challenge of deploying TensorFlow Lite on a ZYNQ 7000 board (or any platform without out-of-the-box…
Cross-Compiling TensorFlow Lite for ZYNQ 7000 (ARMv7-A + VFPv3)

If you’re like me — wrestling with the challenge of deploying TensorFlow Lite on a ZYNQ 7000 board (or any platform without out-of-the-box support) — and you’ve spent frustrating hours digging through forums and GitHub issues, unsure of what to try next — this blog post is for you.
In this guide, I’ll walk you through the exact steps I used to build TensorFlow Lite from source for the ARMv7-A architecture (specifically targeting the vfpv3 floating-point unit), which powers the PYNQ-Z1 board.
Target Device Specifications:
- Development Board: PYNQ-Z1
- CPU: ARM Cortex-A9
- Arch: ARMv7-A (32-bit)
- FPU: vfpv3
How It Started
When I ran interpreter.invoke() using the default tflite-runtime wheel, it crashed with:
Illegal instruction (core dumped)
Root Cause of the Issue
The error occurs because the prebuilt TensorFlow Lite wheels are compiled for newer ARM configurations, like those using vfpv4 or ARMv8-A instruction sets. Unfortunately, the Cortex-A9 in the ZYNQ 7000 series does not support these instructions, leading to an immediate crash when unsupported ops are executed.
To fix this, we need to cross-compile TensorFlow Lite with the correct compiler flags for ARMv7-A and vfpv3, ensuring binary compatibility with the ZYNQ 7000’s CPU.
Verifying target device specifications:
cat /proc/cpuinfo
Host Environment Specifications
This is the setup I used to build the TensorFlow Lite wheel inside a Docker container:
- CPU: 8 cores × Intel(R) Xeon(R) CPU E5–2640
- Architecture: x86_64
- RAM: 32 GB
- Operating System: Ubuntu 22.04.1 LTS
Packages
- Python: 3.10
- Numpy: 1.26.4
- TensorFlow: v2.15.0
💡 Note: While this setup worked for me, the build process can be memory-intensive. If you’re using a VM or a system with limited resources, consider increasing your swap size or reducing parallel build jobs (e.g., using
make -j1).
⚙Building TFLite wheel
- Install Required Packages
sudo apt update
sudo apt install -y cmake python3-pip
pip3 install pybind11
- Clone TensorFlow source from git, and check out to v2.15.0
git clone https://github.com/tensorflow/tensorflow.git tensorflow_src
cd tensorflow_src
git checkout v2.15.0
- Change the vector floating-point version in download_toolchains.sh file. The file is located in tensorflow/lite/tools/cmake/download_toolchains.sh.
## Before
case $1 in
armhf)
if [[ ! -d "${TOOLCHAINS_DIR}/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf" ]]; then
curl -LO https://storage.googleapis.com/mirror.tensorflow.org/developer.arm.com/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz >&2
tar xvf gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz -C ${TOOLCHAINS_DIR} >&2
fi
ARMCC_ROOT=${TOOLCHAINS_DIR}/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf
echo "ARMCC_FLAGS=\"-march=armv7-a -mfpu=neon-vfpv4 -funsafe-math-optimizations \
-isystem ${ARMCC_ROOT}/lib/gcc/arm-linux-gnueabihf/8.3.0/include \
-isystem ${ARMCC_ROOT}/lib/gcc/arm-linux-gnueabihf/8.3.0/include-fixed \
-isystem ${ARMCC_ROOT}/arm-linux-gnueabihf/include/c++/8.3.0 \
-isystem ${ARMCC_ROOT}/arm-linux-gnueabihf/libc/usr/include \
-isystem \"\${CROSSTOOL_PYTHON_INCLUDE_PATH}\" \
-isystem /usr/include\""
echo "ARMCC_PREFIX=${ARMCC_ROOT}/bin/arm-linux-gnueabihf-"
;;
## After
case $1 in
armhf)
if [[ ! -d "${TOOLCHAINS_DIR}/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf" ]]; then
curl -LO https://storage.googleapis.com/mirror.tensorflow.org/developer.arm.com/media/Files/downloads/gnu-a/8.3-2019.03/binrel/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz >&2
tar xvf gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz -C ${TOOLCHAINS_DIR} >&2
fi
ARMCC_ROOT=${TOOLCHAINS_DIR}/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf
echo "ARMCC_FLAGS=\"-march=armv7-a -mfpu=neon-vfpv3 -funsafe-math-optimizations \
-isystem ${ARMCC_ROOT}/lib/gcc/arm-linux-gnueabihf/8.3.0/include \
-isystem ${ARMCC_ROOT}/lib/gcc/arm-linux-gnueabihf/8.3.0/include-fixed \
-isystem ${ARMCC_ROOT}/arm-linux-gnueabihf/include/c++/8.3.0 \
-isystem ${ARMCC_ROOT}/arm-linux-gnueabihf/libc/usr/include \
-isystem \"\${CROSSTOOL_PYTHON_INCLUDE_PATH}\" \
-isystem /usr/include\""
echo "ARMCC_PREFIX=${ARMCC_ROOT}/bin/arm-linux-gnueabihf-"
;;
“ARMCC_FLAGS=\”-march=armv7-a -mfpu=neon-vfpv3 -funsafe-math-optimizations \
- Build the wheel using docker
make -j1 -C tensorflow/lite/tools/pip_package docker-build \
TENSORFLOW_TARGET=armhf PYTHON_VERSION=3.10
💡make -j1: Make the build system run only one job (build task) at a time. You can increase for faster build with high memory usage
Build takes 1–2 hrs. After build is completed the wheel files are locate in /tensorflow/tensorflow/lite/tools/pip_package/gen/tflite_pip/python3.10/dist directory.
📦Installing on TFLite on Target:
- Copy the built wheel into the target device.
- Check wheel for compatibility: Unzip the wheel and cross-check the architecture it is built to.
unzip tflite_runtime-2.15.0-cp310-cp310-linux_armv7l.whl -d tflite_unziped
cd tflite_unziped/tflite_runtime
readelf -A _pywrap_tensorflow_interpreter_wrapper.so
💡
readelf -Alets you verify that the compiled binary matches your target CPU’s expected instruction set (in this case: ARMv7-A + VFPv3).
💻Output:
Attribute Section: aeabi File Attributes Tag_CPU_name: “7-A” Tag_CPU_arch: v7 Tag_CPU_arch_profile: Application Tag_ARM_ISA_use: Yes Tag_THUMB_ISA_use: Thumb-2 Tag_FP_arch: VFPv3 Tag_Advanced_SIMD_arch: NEONv1 Tag_ABI_PCS_wchar_t: 4 Tag_ABI_FP_denormal: Needed Tag_ABI_FP_exceptions: Needed Tag_ABI_FP_number_model: IEEE 754 Tag_ABI_align_needed: 8-byte Tag_ABI_align_preserved: 8-byte, except leaf SP Tag_ABI_enum_size: int Tag_ABI_VFP_args: VFP registers Tag_CPU_unaligned_access: v6
If this is how your output looks, then you have cross-compiled your TFLite for ARM Cortex-A9 architecture (ARMv7, vfpv3).
- Install the wheel using pip
python3.10 -m pip install ./tflite_runtime-2.15.0-cp310-cp310-linux_armv7l.whl
🧩Conclusion:
Successfully running TensorFlow Lite on the ZYNQ 7000 takes a bit of low-level elbow grease — especially when prebuilt binaries aren’t compatible. But once you tailor the build to your target architecture, it opens the door to efficient ML on embedded platforms like the PYNQ-Z1.
If you found this helpful or ran into any issues, feel free to connect or drop a comment below. I’d love to hear how it went for you. Cheers!
메타데이터
- post_id
- 1a5e0358b83e
- slug
- cross-compiling-tensorflow-lite-for-zynq-7000-armv7-a-vfpv3-1a5e0358b83e
- url
- https://medium.com/@harshith.n001/cross-compiling-tensorflow-lite-for-zynq-7000-armv7-a-vfpv3-1a5e0358b83e
- canonical_url
- https://medium.com/@harshith.n001/cross-compiling-tensorflow-lite-for-zynq-7000-armv7-a-vfpv3-1a5e0358b83e
- author_url
- https://medium.com/@harshith.n001
- status
- ok
- fetched_at
- 2026-07-19 22:08:37