本文介绍了如何在最终编译阶段而不是检测时使Cmake使用特定的编译器和标志?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从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

但问题是我必须用Cmake打包一个库(Bullet Physics)。据我所知,Cmake还没有iOS支持。



因此,我创建了一个工具链文件。

  SET(CMAKE_SYSTEM_NAME Generic)
SET(CMAKE_SYSTEM_VERSION4.3)
SET(CMAKE_SYSTEM_PROCESSORarm)
SET(CMAKE_CROSSCOMPILING TRUE)

SET(SDKVER4.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_ARCHITECTURESarmv6armv7)

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)

并执行。

  cmake -DCMAKE_TOOLCHAIN_FILE = .. / CMAKE_IPHONEOS_TOOLCHAIN.cmake ../bullet-2.78 

cmake 本身做得很好。 make 做得很好。所有构建完成没有任何错误。然而,构建的二进制是 x64 非脂肪二进制而不是 armv6 / armv7 fat二进制。生成的 Makefile 不能用于交叉编译。在构建时似乎不使用编译器和标志(包括 -isysroot )。如何使用参数?

解决方案

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



解决方案



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

  INCLUDE(CMakeForceCompiler)

SET(CMAKE_CROSSCOMPILING TRUE)
SET(CMAKE_SYSTEM_NAMEDarwin)
SET(CMAKE_SYSTEM_PROCESSOR) )
SET(SDKROOT/ Developer / Platforms /)

SET(SDKVER4.3)
SET(DEVROOT/Developer/Platforms/iPhoneOS.platform/Developer ($DEVROOT} / usr / bin / clang)
SET(CXX$ {DEVROOT} / iPhone / OS / 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)
SET(仅限CMAKE_FIND_ROOT_PATH_MODE_INCLUDE)

和构建脚本。 这很重要!

  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

这是非常小的配置。

首先,工具链配置是只是一个阶段,找出目标机器上可用的功能。但是对iOS的交叉编译需要一些特殊的编译器标志,这是中描述的异常情况。



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



需要通过构建脚本中的shell变量导出提供交叉编译。这是非常粗糙的选项,但重要的是我们必须通过shell变量。 配置会影响生成的 Makefile 。我们必须指定正确的 CMAKE_SYSTEM_NAME Darwin )和 CMAKE_SYSTEM_PROCESSOR arm )。






更新



还有另一个试验。








这里有一个。这看起来很有前途。







Update 2



现在Bullet包含一个iOS平台的构建脚本。无论如何它的不方便,因为它不处理模拟器东西的特殊需要,我写了另一个构建脚本,使远程库调试/释放模式。




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?

解决方案

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

这篇关于如何在最终编译阶段而不是检测时使Cmake使用特定的编译器和标志?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-21 09:29