问题描述
我正在尝试从 Mac OS X 交叉编译到 iOS.使用 clang
很容易将源代码交叉编译到 iOS 目标.我们只需要 3 个参数即可使其工作.
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
但问题是我必须构建一个与 Cmake 一起打包的库(Bullet Physics).据我所知,Cmake 尚不支持 iOS.
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)
并执行.
cmake -DCMAKE_TOOLCHAIN_FILE=../CMAKE_IPHONEOS_TOOLCHAIN.cmake ../bullet-2.78
cmake
本身做得很好.make
做得很好.所有构建完成,没有任何错误.然而,构建的二进制文件是 x64
非胖二进制文件,而不是 armv6/armv7
胖二进制文件.生成的 Makefile
不适用于交叉编译.构建时似乎没有使用编译器和标志(包括 -isysroot
).我怎样才能让它使用参数?
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?
推荐答案
我解决了这个问题并为 iOS 构建了 Bullet Physics.
I solved this and built Bullet Physics for iOS.
这是我使用的工具链配置.
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)
还有构建脚本.这很重要!
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.
首先,工具链配置只是确定目标机器上可用功能的一个阶段.但是交叉编译到 iOS 需要一些特殊的编译器标志,这是 Cmake wiki 中描述的异常情况.
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.
所以我只是强制特定的编译器,Cmake会跳过编译器验证阶段.
So I just forced specific compiler, and Cmake will skip compiler verification stage.
其次,通过构建脚本中的 shell 变量导出提供交叉编译所需的所有编译器标志.这是非常粗略的选项,但重要的是我们必须通过 shell 变量传递.不适用于工具链配置.
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.
然而,某种工具链配置会影响生成的Makefile
.我们必须指定正确的CMAKE_SYSTEM_NAME
(Darwin
)和CMAKE_SYSTEM_PROCESSOR
(arm
).
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.
现在 Bullet 包含适用于 iOS 平台的构建脚本.无论如何这很不方便,因为它不处理模拟器的特殊需求,我写了另一个构建脚本,它为调试/发布模式制作了远库.
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
这篇关于在最终编译阶段而不是检测时,如何让 Cmake 使用特定的编译器和标志?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!