Skip to content

Instantly share code, notes, and snippets.

@StatusReport
Forked from petewarden/..build-protobuf-3.0.0.md
Last active May 21, 2021 08:32
Show Gist options
  • Save StatusReport/2e9744ed40ba50745531f0a61d93a2e3 to your computer and use it in GitHub Desktop.
Save StatusReport/2e9744ed40ba50745531f0a61d93a2e3 to your computer and use it in GitHub Desktop.
Build Google Protobuf 3.x for iOS. Builds all supported architectures and produces a universal binary static library.

Google Protobuf 3.x - 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 simulator.

This gist was adapted from the original at https://gist.github.com/BennettSmith/7150245, and updated to deal with Xcode 8 and iOS 10, and download protobuf version 3.3.2.

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/petewarden/c8d172709018780eb069

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.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.

#!/bin/bash -x
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_IOS_SIM=1
BUILD_ARM64_IPHONE=1
PB_VERSION=3.11.4
# Set this to the minimum iOS SDK version you wish to support.
MIN_SDK_VERSION=11.0
(
PREFIX=`pwd`/protobuf
mkdir -p ${PREFIX}/platform
EXTRA_MAKE_FLAGS="-j8"
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}')
OSX_VERSION=darwin15.0.0
MACOSX_PLATFORM=${XCODEDIR}/Platforms/MacOSX.platform
MACOSX_SYSROOT=${MACOSX_PLATFORM}/Developer/${OSX_SDK}.sdk
IPHONEOS_PLATFORM=$(xcrun --sdk iphoneos --show-sdk-platform-path)
IPHONEOS_SYSROOT=$(xcrun --sdk iphoneos --show-sdk-path)
IPHONESIMULATOR_PLATFORM=$(xcrun --sdk iphonesimulator --show-sdk-platform-path)
IPHONESIMULATOR_SYSROOT=$(xcrun --sdk iphonesimulator --show-sdk-path)
CC=clang
CFLAGS="-DNDEBUG -Os -pipe -fPIC -fno-exceptions"
CXX=clang
CXXFLAGS="${CFLAGS} -std=c++11 -stdlib=libc++"
LDFLAGS="-stdlib=libc++"
LIBS="-lc++ -lc++abi"
LIBDIR="${PREFIX}/platform"
echo "$(tput setaf 2)"
echo "####################################"
echo " Cleanup any earlier build attempts"
echo "####################################"
echo "$(tput sgr0)"
(
cd /tmp
if [ -d ${PREFIX} ]
then
rm -rf ${PREFIX}
fi
mkdir ${PREFIX}
mkdir ${PREFIX}/platform
)
echo "$(tput setaf 2)"
echo "##########################################"
echo " Fetch Google Protobuf $PB_VERSION from source."
echo "##########################################"
echo "$(tput sgr0)"
(
cd /tmp
curl -L https://github.com/google/protobuf/archive/v${PB_VERSION}.tar.gz --output /tmp/protobuf-${PB_VERSION}.tar.gz
if [ -d /tmp/protobuf-${PB_VERSION} ]
then
rm -rf /tmp/protobuf-${PB_VERSION}
fi
tar xvf /tmp/protobuf-${PB_VERSION}.tar.gz
)
cd /tmp/protobuf-$PB_VERSION
./autogen.sh
if [ $? -ne 0 ]
then
echo "./autogen.sh command failed."
exit 1
fi
if [ $BUILD_X86_64_MAC -eq 1 ]
then
echo "$(tput setaf 2)"
echo "#####################"
echo " x86_64 for Mac OS X"
echo " and python bindings"
echo "#####################"
echo "$(tput sgr0)"
(
make distclean
./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} test
make ${EXTRA_MAKE_FLAGS} install
cd /tmp/protobuf-$PB_VERSION/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_IOS_SIM -eq 1 ]
then
echo "$(tput setaf 2)"
echo "###########################"
echo " x86_64 for iPhone Simulator"
echo "###########################"
echo "$(tput sgr0)"
(
cd /tmp/protobuf-$PB_VERSION
make distclean
./configure \
--host=x86_64-apple-${OSX_VERSION} \
--disable-shared \
--enable-cross-compile \
--with-protoc="${PROTOC_PATH}" \
--prefix=${LIBDIR}/iossim_x86_64 \
--exec-prefix=${LIBDIR}/iossim_x86_64 \
"CFLAGS=${CFLAGS} \
-mios-simulator-version-min=${MIN_SDK_VERSION} \
-arch x86_64 \
-isysroot ${IPHONESIMULATOR_SYSROOT}" \
"CXX=${CXX}" \
"CXXFLAGS=${CXXFLAGS} \
-mios-simulator-version-min=${MIN_SDK_VERSION} \
-arch x86_64 \
-isysroot \
${IPHONESIMULATOR_SYSROOT}" \
LDFLAGS="-arch x86_64 \
-mios-simulator-version-min=${MIN_SDK_VERSION} \
${LDFLAGS} \
-L${IPHONESIMULATOR_SYSROOT}/usr/lib/ \
-L${IPHONESIMULATOR_SYSROOT}/usr/lib/system" \
"LIBS=${LIBS}"
make ${EXTRA_MAKE_FLAGS}
make ${EXTRA_MAKE_FLAGS} install
)
X86_64_IOS_SIM_PROTOBUF=iossim_x86_64/lib/libprotobuf.a
X86_64_IOS_SIM_PROTOBUF_LITE=iossim_x86_64/lib/libprotobuf-lite.a
else
X86_64_IOS_SIM_PROTOBUF=
X86_64_IOS_SIM_PROTOBUF_LITE=
fi
if [ $BUILD_ARM64_IPHONE -eq 1 ]
then
echo "$(tput setaf 2)"
echo "##################"
echo " arm64 for iPhone"
echo "##################"
echo "$(tput sgr0)"
(
cd /tmp/protobuf-$PB_VERSION
make distclean
./configure \
--host=arm \
--with-protoc="${PROTOC_PATH}" \
--disable-shared \
--prefix=${LIBDIR}/ios_arm64 \
--exec-prefix=${LIBDIR}/ios_arm64 \
"CFLAGS=${CFLAGS} \
-miphoneos-version-min=${MIN_SDK_VERSION} \
-arch arm64 \
-isysroot ${IPHONEOS_SYSROOT}" \
"CXXFLAGS=${CXXFLAGS} \
-miphoneos-version-min=${MIN_SDK_VERSION} \
-arch arm64 \
-isysroot ${IPHONEOS_SYSROOT}" \
LDFLAGS="-arch arm64 \
-miphoneos-version-min=${MIN_SDK_VERSION} \
${LDFLAGS}" \
"LIBS=${LIBS}"
make ${EXTRA_MAKE_FLAGS}
make ${EXTRA_MAKE_FLAGS} install
)
ARM64_IPHONE_PROTOBUF=ios_arm64/lib/libprotobuf.a
ARM64_IPHONE_PROTOBUF_LITE=ios_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 ${ARM64_IPHONE_PROTOBUF} ${X86_64_IOS_SIM_PROTOBUF} -create -output universal/libprotobuf.a
lipo ${ARM64_IPHONE_PROTOBUF_LITE} ${X86_64_IOS_SIM_PROTOBUF_LITE} -create -output universal/libprotobuf-lite.a
)
echo "$(tput setaf 2)"
echo "########################"
echo " Finalize the packaging"
echo "########################"
echo "$(tput sgr0)"
(
cd ${PREFIX}
mkdir bin
mkdir lib
cp -r platform/x86_64/bin/protoc bin
cp -r platform/universal/* lib
file lib/libprotobuf.a
file lib/libprotobuf-lite.a
)
# ) 2>&1
) 2>&1 | tee build.log
echo "$(tput setaf 2)"
echo Done!
echo "$(tput sgr0)"
@zsafder
Copy link

zsafder commented Mar 7, 2018

I am trying to use this script to build protobuf cpp but end with the following errors

cp: platform/universal/*: No such file or directory

  • file lib/libprotobuf.a
    lib/libprotobuf.a: cannot open `lib/libprotobuf.a' (No such file or directory)
  • file lib/libprotobuf-lite.a
    lib/libprotobuf-lite.a: cannot open `lib/libprotobuf-lite.a' (No such file or directory)

I have just clone the repo and run .sh file. Am I missing something?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment