Skip to content

Instantly share code, notes, and snippets.

@dulacp
Last active December 7, 2019 07:54
Show Gist options
  • Star 10 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save dulacp/e1cdaf75b69f4815e075 to your computer and use it in GitHub Desktop.
Save dulacp/e1cdaf75b69f4815e075 to your computer and use it in GitHub Desktop.
Download & Compile Libpng for iOS (all architectures)
# Builds a Libpng framework for the iPhone and the iPhone Simulator.
# Creates a set of universal libraries that can be used on an iPhone and in the
# iPhone simulator. Then creates a pseudo-framework to make using libpng in Xcode
# less painful.
#
# To configure the script, define:
# IPHONE_SDKVERSION: iPhone SDK version (e.g. 8.1)
#
# Then go get the source tar.bz of the libpng you want to build, shove it in the
# same directory as this script, and run "./libpng.sh". Grab a cuppa. And voila.
#===============================================================================
: ${LIB_VERSION:=1.4.14}
# Current iPhone SDK
: ${IPHONE_SDKVERSION:=`xcodebuild -showsdks | grep iphoneos | egrep "[[:digit:]]+\.[[:digit:]]+" -o | tail -1`}
# Specific iPhone SDK
# : ${IPHONE_SDKVERSION:=8.1}
: ${XCODE_ROOT:=`xcode-select -print-path`}
: ${TARBALLDIR:=`pwd`}
: ${SRCDIR:=`pwd`/src}
: ${IOSBUILDDIR:=`pwd`/ios/build}
: ${OSXBUILDDIR:=`pwd`/osx/build}
: ${PREFIXDIR:=`pwd`/ios/prefix}
: ${IOSFRAMEWORKDIR:=`pwd`/ios/framework}
: ${OSXFRAMEWORKDIR:=`pwd`/osx/framework}
LIB_TARBALL=$TARBALLDIR/libpng-$LIB_VERSION.tar.gz
LIB_SRC=$SRCDIR/libpng-${LIB_VERSION}
#===============================================================================
ARM_DEV_CMD="xcrun --sdk iphoneos"
SIM_DEV_CMD="xcrun --sdk iphonesimulator"
#===============================================================================
# Functions
#===============================================================================
abort()
{
echo
echo "Aborted: $@"
exit 1
}
doneSection()
{
echo
echo "================================================================="
echo "Done"
echo
}
#===============================================================================
cleanEverythingReadyToStart()
{
echo Cleaning everything before we start to build...
rm -rf iphone-build iphonesim-build
rm -rf $IOSBUILDDIR
rm -rf $PREFIXDIR
rm -rf $IOSFRAMEWORKDIR/$FRAMEWORK_NAME.framework
doneSection
}
#===============================================================================
downloadLibpng()
{
if [ ! -s $LIB_TARBALL ]; then
echo "Downloading libpng ${LIB_VERSION}"
curl -L -o $LIB_TARBALL http://sourceforge.net/projects/libpng/files/libpng14/${LIB_VERSION}/libpng-${LIB_VERSION}.tar.gz
fi
doneSection
}
#===============================================================================
unpackLibpng()
{
[ -f "$LIB_TARBALL" ] || abort "Source tarball missing."
echo Unpacking libpng into $SRCDIR...
[ -d $SRCDIR ] || mkdir -p $SRCDIR
[ -d $LIB_SRC ] || ( cd $SRCDIR; tar xfj $LIB_TARBALL )
[ -d $LIB_SRC ] && echo " ...unpacked as $LIB_SRC"
doneSection
}
#===============================================================================
buildLibpngForIPhoneOS()
{
export CC=$XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
export CC_BASENAME=clang
export CXX=$XCODE_ROOT/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang++
export CXX_BASENAME=clang++
# avoid the `LDFLAGS` env to include the homebrew Cellar
export LDFLAGS=""
cd $LIB_SRC
echo Building Libpng for iPhoneSimulator
export CFLAGS="-O3 -arch i386 -arch x86_64 -isysroot $XCODE_ROOT/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator${IPHONE_SDKVERSION}.sdk -mios-simulator-version-min=${IPHONE_SDKVERSION} -Wno-error-implicit-function-declaration"
make distclean
./configure --prefix=$PREFIXDIR/iphonesim-build --disable-dependency-tracking --enable-static=yes --enable-shared=no
make
make install
doneSection
echo Building Libpng for iPhone
export CFLAGS="-O3 -arch armv7 -arch armv7s -arch arm64 -isysroot $XCODE_ROOT/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${IPHONE_SDKVERSION}.sdk -mios-version-min=${IPHONE_SDKVERSION}"
make distclean
./configure --host=arm-apple-darwin --prefix=$PREFIXDIR/iphone-build --disable-dependency-tracking --enable-static=yes --enable-shared=no
make
make install
doneSection
}
#===============================================================================
scrunchAllLibsTogetherInOneLibPerPlatform()
{
cd $PREFIXDIR
# iOS Device
mkdir -p $IOSBUILDDIR/armv7
mkdir -p $IOSBUILDDIR/armv7s
mkdir -p $IOSBUILDDIR/arm64
# iOS Simulator
mkdir -p $IOSBUILDDIR/i386
mkdir -p $IOSBUILDDIR/x86_64
ALL_LIBS=""
echo Splitting all existing fat binaries...
$ARM_DEV_CMD lipo "iphone-build/lib/libpng.a" -thin armv7 -o $IOSBUILDDIR/armv7/libpng.a
$ARM_DEV_CMD lipo "iphone-build/lib/libpng.a" -thin armv7s -o $IOSBUILDDIR/armv7s/libpng.a
$ARM_DEV_CMD lipo "iphone-build/lib/libpng.a" -thin arm64 -o $IOSBUILDDIR/arm64/libpng.a
$SIM_DEV_CMD lipo "iphonesim-build/lib/libpng.a" -thin i386 -o $IOSBUILDDIR/i386/libpng.a
$SIM_DEV_CMD lipo "iphonesim-build/lib/libpng.a" -thin x86_64 -o $IOSBUILDDIR/x86_64/libpng.a
echo Build an universal library
}
#===============================================================================
buildFramework()
{
: ${1:?}
FRAMEWORKDIR=$1
BUILDDIR=$2
VERSION_TYPE=Alpha
FRAMEWORK_NAME=libpng
FRAMEWORK_VERSION=A
FRAMEWORK_CURRENT_VERSION=$LIB_VERSION
FRAMEWORK_COMPATIBILITY_VERSION=$LIB_VERSION
FRAMEWORK_BUNDLE=$FRAMEWORKDIR/$FRAMEWORK_NAME.framework
echo "Framework: Building $FRAMEWORK_BUNDLE from $BUILDDIR..."
rm -rf $FRAMEWORK_BUNDLE
echo "Framework: Setting up directories..."
mkdir -p $FRAMEWORK_BUNDLE
mkdir -p $FRAMEWORK_BUNDLE/Versions
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Resources
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Headers
mkdir -p $FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/Documentation
echo "Framework: Creating symlinks..."
ln -s $FRAMEWORK_VERSION $FRAMEWORK_BUNDLE/Versions/Current
ln -s Versions/Current/Headers $FRAMEWORK_BUNDLE/Headers
ln -s Versions/Current/Resources $FRAMEWORK_BUNDLE/Resources
ln -s Versions/Current/Documentation $FRAMEWORK_BUNDLE/Documentation
ln -s Versions/Current/$FRAMEWORK_NAME $FRAMEWORK_BUNDLE/$FRAMEWORK_NAME
FRAMEWORK_INSTALL_NAME=$FRAMEWORK_BUNDLE/Versions/$FRAMEWORK_VERSION/$FRAMEWORK_NAME
echo "Lipoing library into $FRAMEWORK_INSTALL_NAME..."
$ARM_DEV_CMD lipo -create $BUILDDIR/*/libpng.a -o "$FRAMEWORK_INSTALL_NAME" || abort "Lipo $1 failed"
echo "Framework: Copying includes..."
cp -r $PREFIXDIR/iphone-build/include/* $FRAMEWORK_BUNDLE/Headers/
echo "Framework: Creating plist..."
cat > $FRAMEWORK_BUNDLE/Resources/Info.plist <<EOF
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>English</string>
<key>CFBundleExecutable</key>
<string>${FRAMEWORK_NAME}</string>
<key>CFBundleIdentifier</key>
<string>org.libpng</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>${FRAMEWORK_CURRENT_VERSION}</string>
</dict>
</plist>
EOF
doneSection
}
#===============================================================================
# Execution starts here
#===============================================================================
mkdir -p $IOSBUILDDIR
# cleanEverythingReadyToStart #may want to comment if repeatedly running during dev
echo "LIB_VERSION: $LIB_VERSION"
echo "LIB_SRC: $LIB_SRC"
echo "IOSBUILDDIR: $IOSBUILDDIR"
echo "PREFIXDIR: $PREFIXDIR"
echo "IOSFRAMEWORKDIR: $IOSFRAMEWORKDIR"
echo "IPHONE_SDKVERSION: $IPHONE_SDKVERSION"
echo "XCODE_ROOT: $XCODE_ROOT"
echo
downloadLibpng
unpackLibpng
buildLibpngForIPhoneOS
scrunchAllLibsTogetherInOneLibPerPlatform
buildFramework $IOSFRAMEWORKDIR $IOSBUILDDIR
echo "Completed successfully"
#===============================================================================
@khanhankkhan
Copy link

Hi thanks for this script, though when i download to my desktop and type

./libpngsh

Framework: Building /Users/$myusername/Desktop/ios/framework/libpng.framework from /Users/iansharp/Desktop/ios/build...
Framework: Setting up directories...
Framework: Creating symlinks...
Lipoing library into /Users/$myusername/Desktop/ios/framework/libpng.framework/Versions/A/libpng...
fatal error: /Applications/Xcode 6.4.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: can't open input file: /Users/$myusername/Desktop/ios/build/*/libpng.a (No such file or directory)

@endotronic
Copy link

@khanhankkhan, I got the same error. If you scroll up in the output, you will see that it does not unpack the libpng source correctly. Just update the script to a later version of libpng (like 1.6.20) and it goes much further. At the moment I'm stuck with the zlib dependency though - the compiler is not finding zlib.h. The same author has posted a similar gist for zlib which works for me, so there's probably just a little work incorporating zlib.

@dulaccc Thanks for sharing your script!

@endotronic
Copy link

Actually, leave the version at 1.4.14. Change the curl line in downloadLibpng() to this:
curl -L -o $LIB_TARBALL http://sourceforge.net/projects/libpng/files/libpng14/older-releases/${LIB_VERSION}/libpng-${LIB_VERSION}.tar.gz

The URL just needed "/older-releases" in the path. Now it works great. :)

Copy link

ghost commented Sep 29, 2016

When I tried to run the archive was unrecognized by tar (OSX). I changed up the script to 1.6.24 (extension is now xz). Seems to have built fine and loaded into XCode (IOS 9.3), haven't tested it out yet though. Thank you for making this great script dulaccc!

@jvcleave
Copy link

jvcleave commented Jan 1, 2017

I was able to compile 1.6.27 but in order to get around zlib errors I removed

# Include the zlib header so that the defaults below are known
@#  include <zlib.h>

from:
scripts/pnglibconf.dfa

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