Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
314 views
in Technique[技术] by (71.8m points)

ios - How can I make Cmake use specific compiler and flags when final compilation stage instead of detection?

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?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I solved this and built Bullet Physics for iOS.

Solution

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.

Description

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


Update

There is another trials. Anyway these don't work for me anymore.

Here's one more. This looks promising.

Update 2

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...