Generate Protocol Buffers files for Android NDK

This guide shows you how to generate the Protocol Buffers source files and library for Android NDK from scratch.

Generate C++ source files from the proto file

  1. Install protocol buffers v3.10.1 on your local machine.

  2. Check your installation:

    protoc --version

    You should have libprotoc 3.10.1.

  3. In the Cardboard repository, navigate to the proto folder.

  4. Generate the Protocol Buffers source files in C++:

    protoc --proto_path=. --cpp_out=. cardboard_device.proto

    You should now have cardboard_device.pb.cc and cardboard_device.pb.h.

Generate cross-compilation toolchains

  1. Download Android NDK, Revision 16b:

    wget "https://dl.google.com/android/repository/android-ndk-r16b-linux-x86_64.zip"
  2. Extract the downloaded Android NDK into a convenient location. A folder named android-ndk-r16b should appear. Navigate into it.

  3. Set the locations of the generated toolchains:

    toolchain_dir=`pwd`/..
    
  4. Generate the 32-bit standalone toolchain:

    ./build/tools/make-standalone-toolchain.sh --arch=arm --platform=android-21 --toolchain=arm-linux-android-clang5.0 --install-dir=$toolchain_dir/arm-21-toolchain-clang-32 --use-llvm --stl=libc++
    
  5. Generate the 64-bit standalone toolchain:

    ./build/tools/make-standalone-toolchain.sh --arch=arm64 --platform=android-21 --toolchain=arm-linux-android-clang5.0 --install-dir=$toolchain_dir/arm-21-toolchain-clang-64 --use-llvm --stl=libc++
    
  6. Make sure that that two directories named arm-21-toolchain-clang-32 and arm-21-toolchain-clang-64 are in the same path on your machine as the Android NDK folder. These directories contain the toolchains that were just built.

Cross-compile Protocol Buffers library

You will need a cross-compiled Protocol Buffers library to build the Cardboard SDK.

  1. Clone the Protocol Buffers repository into your local machine by running the following command in the same path as the toolchain directories.

    git clone https://github.com/protocolbuffers/protobuf.git
  2. Navigate into Protocol Buffers repository folder, and run the following commands:

    git checkout v3.10.1
    git submodule update --init --recursive
    ./autogen.sh
  3. Create the build directory:

    mkdir -p `pwd`/../libprotobuf/android
    
  4. Create a script named build_script_32.sh:

    export build_dir=`pwd`/../libprotobuf/android
    export sysroot=`pwd`/../arm-21-toolchain-clang-32/sysroot
    export PATH=`pwd`/../arm-21-toolchain-clang-32/bin:$PATH
    export CC="arm-linux-androideabi-clang --sysroot $sysroot"
    export CXX="arm-linux-androideabi-clang++ --sysroot $sysroot"
    
    ./configure \
    --host=arm-linux-androideabi \
    --with-protoc=protoc \
    --with-sysroot="$sysroot" \
    --disable-shared \
    --prefix="$build_dir/armeabi-v7a" \
    --enable-cross-compile \
    CFLAGS="-march=armv7-a -D__ANDROID_API__=21" \
    CXXFLAGS="-frtti -fexceptions -march=armv7-a -D__ANDROID_API__=21" \
    LIBS="-llog -lz -lc++_static"
    
    make -j2
    make install
    
  5. Run the script:

    bash build_script_32.sh
    
  6. Clean the protocol buffer:

    make distclean
    
  7. Create a script named build_script_64.sh:

    export build_dir=`pwd`/../libprotobuf/android
    export sysroot=`pwd`/../arm-21-toolchain-clang-64/sysroot
    export PATH=`pwd`/../arm-21-toolchain-clang-64/bin:$PATH
    export CC="aarch64-linux-android-clang --sysroot $sysroot"
    export CXX="aarch64-linux-android-clang++ --sysroot $sysroot"
    
    ./configure \
    --host=arm-linux-androideabi \
    --with-protoc=protoc \
    --with-sysroot="$sysroot" \
    --disable-shared \
    --prefix="$build_dir/arm64-v8a" \
    --enable-cross-compile \
    CFLAGS="-march=armv8-a -D__ANDROID_API__=21" \
    CXXFLAGS="-frtti -fexceptions -march=armv8-a -D__ANDROID_API__=21" \
    LIBS="-llog -lz -lc++_static"
    
    make -j2
    make install
    
  8. Run the new script:

    bash build_script_64.sh
    
  9. Run the following to generate appropriate file structure:

    mkdir -p ../libprotobuf/android/lib/armeabi-v7a
    mkdir -p ../libprotobuf/android/lib/arm64-v8a
    cp ../libprotobuf/android/armeabi-v7a/lib/libprotobuf-lite.a ../libprotobuf/android/lib/armeabi-v7a
    cp ../libprotobuf/android/arm64-v8a/lib/libprotobuf-lite.a ../libprotobuf/android/lib/arm64-v8a
    cp -r ../libprotobuf/android/armeabi-v7a/include ../libprotobuf/android/include
    rm -rf ../libprotobuf/android/armeabi-v7a
    rm -rf ../libprotobuf/android/arm64-v8a
    
  10. Navigate out of the protobuf repository. You should now have the cross-compiled libraries (libprotobuf-lite.a) in the libprotobuf/android/lib directory, and all the include files in the include (liprotobuf/android/include) directory.

  11. Follow the schema below to copy the libprotobuf directory into the proto directory in the Cardboard repository:

      proto
      ├── cardboard_device.pb.cc
      ├── cardboard_device.pb.h
      └── libprotobuf
          └── android
              ├── include
              │   └── google/*
              └── lib
                  ├── armeabi-v7a
                  │   └── libprotobuf-lite.a
                  └── arm64-v8a
                      └── libprotobuf-lite.a
      ```