在最终编译阶段而不是检测时,如何让Cmake使用特定的编译器和标志?

Eon*_*nil 14 cmake cross-compiling ios

我正在尝试从Mac OS X交叉编译到iOS.使用clang交叉编译源到iOS目标很容易.我们只需要3个参数即可使用.

clang
-arch armv6
-isysroot /Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS4.3.sdk
-miphoneos-version-min=4.3
Run Code Online (Sandbox Code Playgroud)

但问题是我必须建立一个与Cmake打包在一起的库(Bullet Physics).据我所知,Cmake还没有iOS支持.

所以,我制作了一个工具链文件.

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)
Run Code Online (Sandbox Code Playgroud)

并执行.

cmake   -DCMAKE_TOOLCHAIN_FILE=../CMAKE_IPHONEOS_TOOLCHAIN.cmake ../bullet-2.78
Run Code Online (Sandbox Code Playgroud)

cmake本身做得很好.make做得好.所有构建完成没有任何错误.但是构建的二进制文件x64是非胖二进制而不是armv6/armv7胖二进制文件.生成Makefile不适用于交叉编译.它-isysroot在构建时似乎没有使用编译器和标志(包括).如何让它使用参数?

Eon*_*nil 17

我解决了这个问题并为iOS构建了Bullet Physics.

这是我使用的工具链配置.

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)
Run Code Online (Sandbox Code Playgroud)

和构建脚本.这个很重要!

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
Run Code Online (Sandbox Code Playgroud)

这是非常小的配置.但是你明白了.

描述

首先,工具链配置只是确定目标机器上可用功能的一个阶段.但是交叉编译到iOS需要一些特殊的编译器标志,这是Cmake wiki上描述的异常情况.

所以我只强制使用特定的编译器,而Cmake将跳过编译器验证阶段.

其次,在构建脚本中通过shell变量导出提供交叉编译所需的所有编译器标志.这是非常粗略的选项,但重要的是我们必须通过shell变量传递.没有工具链配置.

但是某种工具链配置会影响生成Makefile.我们必须指定correct CMAKE_SYSTEM_NAME(Darwin)和CMAKE_SYSTEM_PROCESSOR(arm).


更新

还有另一项试验.无论如何,这些对我来说不再适用.

还有一个.这很有希望.

更新2

现在Bullet包含iOS平台的构建脚本.反正这是不方便的,因为它不办理模拟器东西特殊需要,我又写了构建脚本,这使得远库调试/释放模式.

https://github.com/Eonil/Bullet-PhysicsEngine-BuildScript