I'm trying to cross-compiling from Mac OS X to iOS. It was easy using clang
to cross-compile a source to iOS target. We need only 3 parameters get it to work.
clang
-arch armv6
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk
-miphoneos-version-min=4.3
But the problem is I have to build a library (Bullet Physics) packaged with Cmake. And as far as I know, Cmake has no iOS support yet.
So, I made a toolchain file.
SET (CMAKE_SYSTEM_NAME "Generic")
SET (CMAKE_SYSTEM_VERSION "4.3")
SET (CMAKE_SYSTEM_PROCESSOR "arm")
SET (CMAKE_CROSSCOMPILING TRUE)
SET (SDKVER "4.3")
SET (DEVROOT "/Developer/Platforms/iPhoneOS.platform/Developer")
SET (SDKROOT "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk")
SET (CMAKE_OSX_SYSROOT "${SDKROOT}")
SET (CMAKE_OSX_ARCHITECTURES "armv6" "armv7")
SET (CMAKE_C_COMPILER "${DEVROOT}/usr/bin/clang")
SET (CMAKE_CXX_COMPILER "${DEVROOT}/usr/bin/clang++")
SET (CMAKE_C_FLAGS "-arch armv6 -arch armv7 -isysroot ${SDKROOT} -std=c99 -x objective-c -DNDEBUG=1")
SET (CMAKE_CXX_FLAGS "-arch armv6 -arch armv7 -isysroot ${SDKROOT} -x objective-c++ -DNDEBUG=1")
SET (CMAKE_EXE_LINKER_FLAGS "-miphoneos-version-min=${SDKVER}")
SET (CMAKE_SHARED_LINKER_FLAGS "-miphoneos-version-min=${SDKVER}")
SET (CMAKE_MODULE_LINKER_FLAGS "-miphoneos-version-min=${SDKVER}")
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
And executed.
cmake -DCMAKE_TOOLCHAIN_FILE=../CMAKE_IPHONEOS_TOOLCHAIN.cmake ../bullet-2.78
cmake
itself done well. make
done well. All build complete without any error. However built binary was x64
non-fat binary instead of armv6/armv7
fat binary. Generated Makefile
doesn't work for cross-compile. It doesn't seem to use compiler and flags (including -isysroot
) when building. How can I make it use the parameters?
Compile-time flags are boolean values provided through the compiler via a macro method. They allow to conditionally include or exclude code based on compile time conditions. There are several default flags provided by the compiler with information about compiler options and the target platform.
The CMAKE_SYSROOT content is passed to the compiler in the --sysroot flag, if supported. The path is also stripped from the RPATH / RUNPATH if necessary on installation. The CMAKE_SYSROOT is also used to prefix paths searched by the find_* commands.
I solved this and built Bullet Physics for iOS.
Here's toolchain configuration that I used.
INCLUDE(CMakeForceCompiler)
SET (CMAKE_CROSSCOMPILING TRUE)
SET (CMAKE_SYSTEM_NAME "Darwin")
SET (CMAKE_SYSTEM_PROCESSOR "arm")
SET (SDKVER "4.3")
SET (DEVROOT "/Developer/Platforms/iPhoneOS.platform/Developer")
SET (SDKROOT "/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS${SDKVER}.sdk")
SET (CC "${DEVROOT}/usr/bin/clang")
SET (CXX "${DEVROOT}/usr/bin/clang++")
CMAKE_FORCE_C_COMPILER (${CC} CLang)
CMAKE_FORCE_CXX_COMPILER (${CXX} CLang)
SET (CMAKE_FIND_ROOT_PATH "${SDKROOT}" "${DEVROOT}")
SET (CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET (CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET (CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
And the build script. This is important!
PKG_NAME=bullet-2.78
BUILD_DIR=build
rm -rf ${PKG_NAME} ${BUILD_DIR}
tar -x -f ${PKG_NAME}-r2387.tar
mkdir build
cd build
DEVROOT=/Developer/Platforms/iPhoneOS.platform/Developer
SYSROOT=$DEVROOT/SDKs/iPhoneOS4.3.sdk
CC=$DEVROOT/usr/bin/clang
CXX=$DEVROOT/usr/bin/clang++
CFLAGS="-arch armv6 -arch armv7 -isysroot $SYSROOT -miphoneos-version-min=4.0"
CXXFLAGS=$CFLAGS
LDFLAGS=$CFLAGS
export CC=$CC
export CXX=$CXX
export CFLAGS=$CFLAGS
export CXXFLAGS=$CXXFLAGS
export LDFLAGS=$LDFLAGS
cmake ../$PKG_NAME -DCMAKE_TOOLCHAIN_FILE=../CMAKE_IPHONEOS_TOOLCHAIN.cmake
make
lipo -info src/LinearMath/libLinearMath.a
This is very minimal configuration. However you got the idea.
First, the toolchain configuration is just a stage figuring out features available on target machine. But cross compilation to iOS require some special compiler flags, and this is exception situation described on Cmake wiki.
So I just forced specific compiler, and Cmake will skip compiler verification stage.
Second, all compiler flags needed for cross compilation offered via shell variable export in build script. This is very rough options, however important is we have to pass via shell variables. Not with toolchain configuration.
However some kind of toolchain configuration affects on generated Makefile
. We have to specify correct CMAKE_SYSTEM_NAME
(Darwin
) and CMAKE_SYSTEM_PROCESSOR
(arm
).
There is another trials. Anyway these don't work for me anymore.
Here's one more. This looks promising.
Now Bullet includes a build script for iOS platforms. Anyway it's inconvenient because it does not handle special needs for simulator stuffs, and I wrote another build script which makes far library for debug/release mode.
https://github.com/Eonil/Bullet-PhysicsEngine-BuildScript
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With