Skip to content

Instantly share code, notes, and snippets.

@huandu
Forked from BennettSmith/..build-protbuf-2.5.0.md
Last active August 29, 2015 14:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save huandu/94ddddf3f80dde6c74a4 to your computer and use it in GitHub Desktop.
Save huandu/94ddddf3f80dde6c74a4 to your computer and use it in GitHub Desktop.
Build script for protobuf 2.5.0 on iOS devices

Google Protobuf 2.5.0 - Mac OS X and iOS Support

The script in this gist will help you buid the Google Protobuf library for use with Mac OS X and iOS. Other methods (such as homebrew or direct compilation) have issues that prevent their use. The libraries built by this script are universal and support all iOS device architectures including the simluator.

Get the Script

The easiest way to use this script is to simply clone the gist onto your machine using the following command:

$ git clone https://gist.github.com/7150245.git build-protobuf

Performing the Build

The script will automatically download the tarball from Google Code, so all you need to do is run the script.

$ cd build-protobuf
$ ./build-protobuf-2.5.0.sh

Results

Build results are found in a folder called protobuf. This folder contains bin, include and lib folders. In addition to these three folders the script also installs the Python language bindings for the Mac OS X build of protobuf. These files are installed in the user's home directory. On my machine the folder is:

${HOME}/Library/Python/2.7/lib/python/site-packages

Integration with Xcode

Create a build rule in your Xcode project with the following settings.

Process *Source files with names matching:* `*.proto`
Using *Custom script:*

cd ${INPUT_FILE_DIR}
${SRCROOT}/Google/protobuf/bin/protoc --proto_path=${INPUT_FILE_DIR} ${INPUT_FILE_PATH} --cpp_out=${DERIVED_FILE_DIR}

Output Files
$(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).pb.cc
$(DERIVED_FILE_DIR)/$(INPUT_FILE_BASE).pb.h

Depending on where you choose to install the protobuf build, you will need to adjust the path to protoc.

History

This gist is forked from https://gist.github.com/BennettSmith/7150245. I fork it to support extracting code and patches from local tar files. I also fix some bugs to make it work well with simulator.

#!/bin/bash
set -e
CURRENT_SCRIPT=$(dirname $0)
TMP_DIR=/tmp
SRC_PREFIX=protobuf-2.5.0
SRC_FILENAME="${SRC_PREFIX}.tar.gz"
TARGET_DIR="${CURRENT_SCRIPT}/.."
INCLUDE_DIR="${TARGET_DIR}/include/ios/protobuf"
LIB_DIR="${TARGET_DIR}/lib/ios/protobuf"
echo "$(tput setaf 2)"
echo Building Google Protobuf for Mac OS X / iOS.
echo Use 'tail -f build.log' to monitor progress.
echo "$(tput sgr0)"
# Controls which architectures are build/included in the
# universal binaries and libraries this script produces.
# Set each to '1' to include, '0' to exclude.
BUILD_X86_64_MAC=1
BUILD_X86_64_SIM=1
BUILD_I386_IOS_SIM=1
BUILD_ARMV7_IPHONE=1
BUILD_ARMV7S_IPHONE=1
BUILD_ARM64_IPHONE=1
GOOGLE_NAMESPACE=google
# Set this to the minimum iOS SDK version you wish to support.
IOS_MIN_SDK=6.0
(
PREFIX="${TMP_DIR}/${GOOGLE_NAMESPACE}"
PLATFORM_DIR="${PREFIX}/platform"
mkdir -p "$PLATFORM_DIR"
EXTRA_MAKE_FLAGS="-j4"
XCODEDIR=`xcode-select --print-path`
OSX_SDK=$(xcodebuild -showsdks | grep macosx | sort | head -n 1 | awk '{print $NF}')
IOS_SDK=$(xcodebuild -showsdks | grep iphoneos | sort | head -n 1 | awk '{print $NF}')
SIM_SDK=$(xcodebuild -showsdks | grep iphonesimulator | sort | head -n 1 | awk '{print $NF}')
MACOSX_PLATFORM=${XCODEDIR}/Platforms/MacOSX.platform
MACOSX_SYSROOT=${MACOSX_PLATFORM}/Developer/${OSX_SDK}.sdk
IPHONEOS_PLATFORM=${XCODEDIR}/Platforms/iPhoneOS.platform
IPHONEOS_SYSROOT=${IPHONEOS_PLATFORM}/Developer/SDKs/${IOS_SDK}.sdk
IPHONESIMULATOR_PLATFORM=${XCODEDIR}/Platforms/iPhoneSimulator.platform
IPHONESIMULATOR_SYSROOT=${IPHONESIMULATOR_PLATFORM}/Developer/SDKs/${SIM_SDK}.sdk
CC=clang++
CFLAGS="-DNDEBUG -O3 -fcxx-exceptions -fno-inline"
CXX=clang++
CXXFLAGS="${CFLAGS} -std=c++11 -stdlib=libc++"
LDFLAGS="-stdlib=libc++"
LIBS="-lc++ -lc++abi"
echo "$(tput setaf 2)"
echo "####################################"
echo " Cleanup any earlier build attempts"
echo "####################################"
echo "$(tput sgr0)"
(
cd $TMP_DIR
if [ -d ${PREFIX} ]
then
rm -rf ${PREFIX}
fi
mkdir -p ${PREFIX}/platform
)
echo "$(tput setaf 2)"
echo "##########################################"
echo " Fetch Google Protobuf 2.5.0 from source."
echo "##########################################"
echo "$(tput sgr0)"
(
cp "${CURRENT_SCRIPT}/${SRC_FILENAME}" "${TMP_DIR}/${SRC_FILENAME}"
if [ -d "${TMP_DIR}/${SRC_PREFIX}" ]
then
rm -rf "${TMP_DIR}/${SRC_PREFIX}"
fi
cd "${TMP_DIR}"
tar xvf "${TMP_DIR}/${SRC_FILENAME}"
)
if [ $BUILD_X86_64_MAC -eq 1 ]
then
echo "$(tput setaf 2)"
echo "#####################"
echo " x86_64 for MacOSX"
echo " and python bindings"
echo "#####################"
echo "$(tput sgr0)"
(
cd "${TMP_DIR}/${SRC_PREFIX}"
./configure --disable-shared --prefix=${PREFIX} --exec-prefix=${PREFIX}/platform/x86_64 "CC=${CC}" "CFLAGS=${CFLAGS} -arch x86_64" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch x86_64" "LDFLAGS=${LDFLAGS}" "LIBS=${LIBS}"
make ${EXTRA_MAKE_FLAGS}
make ${EXTRA_MAKE_FLAGS} install
cd python
python setup.py build
python setup.py install --user
)
X86_64_MAC_PROTOBUF=x86_64/lib/libprotobuf.a
X86_64_MAC_PROTOBUF_LITE=x86_64/lib/libprotobuf-lite.a
else
X86_64_MAC_PROTOBUF=
X86_64_MAC_PROTOBUF_LITE=
fi
if [ $BUILD_X86_64_SIM -eq 1 ]
then
echo "$(tput setaf 2)"
echo "#####################"
echo " x86_64 for iPhone Simulator"
echo "#####################"
echo "$(tput sgr0)"
(
cd "${TMP_DIR}/${SRC_PREFIX}"
./configure --build=x86_64-apple-darwin13.0.0 --host=i386-apple-darwin13.0.0 --with-protoc=${PREFIX}/platform/x86_64/bin/protoc --disable-shared --prefix=${PREFIX} --exec-prefix=${PREFIX}/platform/i386 "CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch x86_64 -isysroot ${IPHONESIMULATOR_SYSROOT}" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch x86_64 -isysroot ${IPHONESIMULATOR_SYSROOT}" LDFLAGS="-arch i386 -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"
make ${EXTRA_MAKE_FLAGS}
make ${EXTRA_MAKE_FLAGS} install
)
X86_64_SIM_PROTOBUF=x86_64/lib/libprotobuf.a
X86_64_SIM_PROTOBUF_LITE=x86_64/lib/libprotobuf-lite.a
else
X86_64_SIM_PROTOBUF=
X86_64_SIM_PROTOBUF_LITE=
fi
if [ $BUILD_I386_IOS_SIM -eq 1 ]
then
echo "$(tput setaf 2)"
echo "###########################"
echo " i386 for iPhone Simulator"
echo "###########################"
echo "$(tput sgr0)"
(
cd "${TMP_DIR}/${SRC_PREFIX}"
make ${EXTRA_MAKE_FLAGS} distclean
./configure --build=x86_64-apple-darwin13.0.0 --host=i386-apple-darwin13.0.0 --with-protoc=${PREFIX}/platform/x86_64/bin/protoc --disable-shared --prefix=${PREFIX} --exec-prefix=${PREFIX}/platform/i386 "CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch i386 -isysroot ${IPHONESIMULATOR_SYSROOT}" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch i386 -isysroot ${IPHONESIMULATOR_SYSROOT}" LDFLAGS="-arch i386 -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"
make ${EXTRA_MAKE_FLAGS}
make ${EXTRA_MAKE_FLAGS} install
)
I386_IOS_SIM_PROTOBUF=i386/lib/libprotobuf.a
I386_IOS_SIM_PROTOBUF_LITE=i386/lib/libprotobuf-lite.a
else
I386_IOS_SIM_PROTOBUF=
I386_IOS_SIM_PROTOBUF_LITE=
fi
if [ $BUILD_ARMV7_IPHONE -eq 1 ]
then
echo "$(tput setaf 2)"
echo "##################"
echo " armv7 for iPhone"
echo "##################"
echo "$(tput sgr0)"
(
cd "${TMP_DIR}/${SRC_PREFIX}"
make ${EXTRA_MAKE_FLAGS} distclean
./configure --build=x86_64-apple-darwin13.0.0 --host=armv7-apple-darwin13.0.0 --with-protoc=${PREFIX}/platform/x86_64/bin/protoc --disable-shared --prefix=${PREFIX} --exec-prefix=${PREFIX}/platform/armv7 "CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch armv7 -isysroot ${IPHONEOS_SYSROOT}" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch armv7 -isysroot ${IPHONEOS_SYSROOT}" LDFLAGS="-arch armv7 -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"
make ${EXTRA_MAKE_FLAGS}
make ${EXTRA_MAKE_FLAGS} install
)
ARMV7_IPHONE_PROTOBUF=armv7/lib/libprotobuf.a
ARMV7_IPHONE_PROTOBUF_LITE=armv7/lib/libprotobuf-lite.a
else
ARMV7_IPHONE_PROTOBUF=
ARMV7_IPHONE_PROTOBUF_LITE=
fi
if [ $BUILD_ARMV7S_IPHONE -eq 1 ]
then
echo "$(tput setaf 2)"
echo "###################"
echo " armv7s for iPhone"
echo "###################"
echo "$(tput sgr0)"
(
cd "${TMP_DIR}/${SRC_PREFIX}"
make ${EXTRA_MAKE_FLAGS} distclean
./configure --build=x86_64-apple-darwin13.0.0 --host=armv7s-apple-darwin13.0.0 --with-protoc=${PREFIX}/platform/x86_64/bin/protoc --disable-shared --prefix=${PREFIX} --exec-prefix=${PREFIX}/platform/armv7s "CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch armv7s -isysroot ${IPHONEOS_SYSROOT}" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch armv7s -isysroot ${IPHONEOS_SYSROOT}" LDFLAGS="-arch armv7s -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"
make ${EXTRA_MAKE_FLAGS}
make ${EXTRA_MAKE_FLAGS} install
)
ARMV7S_IPHONE_PROTOBUF=armv7s/lib/libprotobuf.a
ARMV7S_IPHONE_PROTOBUF_LITE=armv7s/lib/libprotobuf-lite.a
else
ARMV7S_IPHONE_PROTOBUF=
ARMV7S_IPHONE_PROTOBUF_LITE=
fi
if [ $BUILD_ARM64_IPHONE -eq 1 ]
then
echo "$(tput setaf 2)"
echo "########################################"
echo " Patch Protobuf 2.5.0 for 64bit support"
echo "########################################"
echo "$(tput sgr0)"
cp "${CURRENT_SCRIPT}/patches/0001-Add-generic-GCC-support-for-atomic-operations.patch" "${TMP_DIR}"
cp "${CURRENT_SCRIPT}/patches/0001-Add-generic-gcc-header-to-Makefile.am.patch" "${TMP_DIR}"
(
cd "${TMP_DIR}/${SRC_PREFIX}"
make ${EXTRA_MAKE_FLAGS} distclean
patch -p1 < "${TMP_DIR}/0001-Add-generic-GCC-support-for-atomic-operations.patch"
patch -p1 < "${TMP_DIR}/0001-Add-generic-gcc-header-to-Makefile.am.patch"
)
echo "$(tput setaf 2)"
echo "##################"
echo " arm64 for iPhone"
echo "##################"
echo "$(tput sgr0)"
(
cd "${TMP_DIR}/${SRC_PREFIX}"
./configure --build=x86_64-apple-darwin13.0.0 --host=arm --with-protoc=${PREFIX}/platform/x86_64/bin/protoc --disable-shared --prefix=${PREFIX} --exec-prefix=${PREFIX}/platform/arm64 "CC=${CC}" "CFLAGS=${CFLAGS} -miphoneos-version-min=${IOS_MIN_SDK} -arch arm64 -isysroot ${IPHONEOS_SYSROOT}" "CXX=${CXX}" "CXXFLAGS=${CXXFLAGS} -arch arm64 -isysroot ${IPHONEOS_SYSROOT}" LDFLAGS="-arch arm64 -miphoneos-version-min=${IOS_MIN_SDK} ${LDFLAGS}" "LIBS=${LIBS}"
make ${EXTRA_MAKE_FLAGS}
make ${EXTRA_MAKE_FLAGS} install
)
ARM64_IPHONE_PROTOBUF=arm64/lib/libprotobuf.a
ARM64_IPHONE_PROTOBUF_LITE=arm64/lib/libprotobuf-lite.a
else
ARM64_IPHONE_PROTOBUF=
ARM64_IPHONE_PROTOBUF_LITE=
fi
echo "$(tput setaf 2)"
echo "############################"
echo " Create Universal Libraries"
echo "############################"
echo "$(tput sgr0)"
(
cd ${PREFIX}/platform
mkdir universal
lipo ${X86_64_SIM_PROTOBUF} \
${ARM64_IPHONE_PROTOBUF} \
${ARMV7S_IPHONE_PROTOBUF} \
${ARMV7_IPHONE_PROTOBUF} \
${I386_IOS_SIM_PROTOBUF} \
-create -output universal/libprotobuf.a
lipo ${X86_64_SIM_PROTOBUF_LITE} \
${ARM64_IPHONE_PROTOBUF_LITE} \
${ARMV7S_IPHONE_PROTOBUF_LITE} \
${ARMV7_IPHONE_PROTOBUF_LITE} \
${I386_IOS_SIM_PROTOBUF_LITE} \
-create -output universal/libprotobuf-lite.a
)
echo "$(tput setaf 2)"
echo "########################"
echo " Finalize the packaging"
echo "########################"
echo "$(tput sgr0)"
(
mkdir -p "$INCLUDE_DIR"
mkdir -p "$LIB_DIR"
cp -r $PREFIX/platform/x86_64/lib/* "$LIB_DIR"
cp -r $PREFIX/platform/universal/* "$LIB_DIR"
cp -r $PREFIX/include/* "$INCLUDE_DIR"
rm -rf $PREFIX/platform
file "${LIB_DIR}/libprotobuf.a"
file "${LIB_DIR}/libprotobuf-lite.a"
file "${LIB_DIR}/libprotoc.a"
)
) 2>&1
#) >build.log 2>&1
echo "$(tput setaf 2)"
echo Done!
echo "$(tput sgr0)"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment