Skip to content

Instantly share code, notes, and snippets.

@shotamatsuda
Created May 6, 2015 12:45
Show Gist options
  • Save shotamatsuda/cf433a2bda8bc0a7f371 to your computer and use it in GitHub Desktop.
Save shotamatsuda/cf433a2bda8bc0a7f371 to your computer and use it in GitHub Desktop.
Build Skia as universal static libraries for OSX and iOS
readonly DEPOT_TOOLS_GIT='https://chromium.googlesource.com/chromium/tools/depot_tools.git'
readonly SKIA_GIT='https://skia.googlesource.com/skia.git'
readonly PROJECT_DIR="$(cd "$(dirname "$0")/../"; pwd)"
readonly BUILD_DIR="${PROJECT_DIR}/build"
readonly DEPOT_TOOLS_DIR="${BUILD_DIR}/depot_tools"
readonly SKIA_DIR="${BUILD_DIR}/skia"
download_depot_tools() {
echo 'Downloading depot tools...'
git clone "${DEPOT_TOOLS_GIT}" "${DEPOT_TOOLS_DIR}"
}
download_skia() {
echo 'Downloading skia...'
export PATH="${DEPOT_TOOLS_DIR}":"${PATH}"
mkdir -p "${SKIA_DIR}/skia"
pushd "${SKIA_DIR}/skia"
gclient config --name . --unmanaged "${SKIA_GIT}"
gclient sync
git checkout master
popd
}
build_skia() {
pushd "${SKIA_DIR}/skia"
export GYP_GENERATORS='ninja,xcode'
echo 'Building for OS X...'
GYP_DEFINES="skia_os='mac' skia_arch_width='32'" './gyp_skia'
ninja -C 'out/Release' skia_lib tools
copy_libraries_in_place "${SKIA_DIR}/skia/out/Release" 'osx' 'i386'
GYP_DEFINES="skia_os='mac' skia_arch_width='64'" './gyp_skia'
ninja -C 'out/Release' skia_lib tools
copy_libraries_in_place "${SKIA_DIR}/skia/out/Release" 'osx' 'x86_64'
echo 'Building for iOS...'
GYP_DEFINES="skia_os='ios' skia_arch_type='arm' armv7='1' arm_neon='0'" './gyp_skia'
ninja -C "out/Release-iphoneos" skia_lib tools
copy_libraries_in_place "${SKIA_DIR}/skia/out/Release-iphoneos" 'ios' 'armv7'
echo 'Building for iOS Simulator...'
build_skia_for_ios_simulator 'i386' 'x86'
copy_libraries_in_place "${SKIA_DIR}/skia/out/Release-iphonesimulator" 'ios' 'i386'
build_skia_for_ios_simulator 'x86_64' 'x86_64'
copy_libraries_in_place "${SKIA_DIR}/skia/out/Release-iphonesimulator" 'ios' 'x86_64'
popd
}
build_skia_for_ios_simulator() {
local arch=$1
local arch_type=$2
GYP_DEFINES="skia_os='ios' skia_arch_type='${arch_type}'" './gyp_skia'
# Because gyp_skia doesn't generate ninja files for iPhone Simulator, we need
# to replace the occurrences of the target architecture and the SDK directory
# by hand.
find 'out/Release-iphonesimulator' -type f -name '*.ninja' -exec \
sed -i -e "s/armv7/${arch}/g" {} \;
find 'out/Release-iphonesimulator' -type f -name '*.ninja' -exec \
sed -i -e 's|iPhoneOS.platform|iPhoneSimulator.platform|g' {} \;
find 'out/Release-iphonesimulator' -type f -name '*.ninja' -exec \
sed -i -e 's|SDKs/iPhoneOS|SDKs/iPhoneSimulator|g' {} \;
ninja -C 'out/Release-iphonesimulator' skia_lib tools
}
copy_libraries_in_place() {
local dir=$1
local platform=$2
local arch=$3
echo 'Copying libraries in place...'
mkdir -p "${SKIA_DIR}/${platform}/${arch}"
for file in $(find "${dir}" -name '*.a'); do
cp -n "${file}" "${SKIA_DIR}/${platform}/${arch}"
done
}
decompose_libraries() {
echo 'Decomposing libraries to object files...'
decompose_library 'osx' 'i386'
decompose_library 'osx' 'x86_64'
decompose_library 'ios' 'armv7'
decompose_library 'ios' 'i386'
decompose_library 'ios' 'x86_64'
}
decompose_library() {
local platform=$1
local arch=$2
mkdir -p "${SKIA_DIR}/${platform}/${arch}/obj"
for file in $(find "${SKIA_DIR}/${platform}/${arch}" -name '*.a'); do
cd "${SKIA_DIR}/${platform}/${arch}/obj"; ar -x "${file}"
done
}
create_universal_libraries() {
echo 'Linking everything within architectures...'
rm "${SKIA_DIR}"/osx/*/libskia.a
rm "${SKIA_DIR}"/ios/*/libskia.a
pushd "${SKIA_DIR}/osx/i386"; xcrun ar crus "libskia.a" obj/*.o; popd
pushd "${SKIA_DIR}/osx/x86_64"; xcrun ar crus "libskia.a" obj/*.o; popd
pushd "${SKIA_DIR}/ios/armv7"; xcrun ar crus "libskia.a" obj/*.o; popd
pushd "${SKIA_DIR}/ios/i386"; xcrun ar crus "libskia.a" obj/*.o; popd
pushd "${SKIA_DIR}/ios/x86_64"; xcrun ar crus "libskia.a" obj/*.o; popd
echo 'Creating universal files...'
rm "${SKIA_DIR}"/osx/libskia.a
rm "${SKIA_DIR}"/ios/libskia.a
xcrun lipo -create "${SKIA_DIR}"/osx/*/libskia.a -o "${SKIA_DIR}/osx/libskia.a"
xcrun lipo -create "${SKIA_DIR}"/ios/*/libskia.a -o "${SKIA_DIR}/ios/libskia.a"
}
download_depot_tools
download_skia
build_skia
decompose_libraries
create_universal_libraries
@Phando
Copy link

Phando commented May 14, 2015

This is a great script. I copied and tried to run the script today. Unfortunately there were lots of failing errors during the ios portion of the build:

duplicate symbol _main in: obj/tools/chrome_fuzz.chrome_fuzz.o obj/experimental/iOSSampleApp/Shared/chrome_fuzz.skia_ios.o ld: 1 duplicate symbol for architecture armv7 clang: error: linker command failed with exit code 1 (use -v to see invocation) [125/227] OBJCXX obj/experimental/SimpleiOSApp/test_image_decoder.SimpleApp.o ninja: build stopped: subcommand failed.

The last error was this:
fatal error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/lipo: /Users/build/skia/ios/i386/libskia.a and /Users/build/skia/ios/x86_64/libskia.a have the same architectures (i386) and can't be in the same fat output file

Any help building this would be much appreciated.

Thanks again

@aakrandan
Copy link

Hi,

Actually i have created an assembly file, and included all the c++ header file in my objective c project. But i am not sure how to use the library to actually draw something and then show it.

any help is appreciated.

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