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

时间:2023-01-29 02:22:06

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.

我正在尝试从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

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.

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

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?

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

1 个解决方案

#1


17  

I solved this and built Bullet Physics for iOS.

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

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.

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

So I just forced specific compiler, and Cmake will skip compiler verification stage.

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

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.

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

However some kind of toolchain configuration affects on generated Makefile. We have to specify correct CMAKE_SYSTEM_NAME (Darwin) and CMAKE_SYSTEM_PROCESSOR (arm).

但是某种工具链配置会影响生成的Makefile。我们必须指定正确的CMAKE_SYSTEM_NAME(Darwin)和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.

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

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

#1


17  

I solved this and built Bullet Physics for iOS.

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

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.

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

So I just forced specific compiler, and Cmake will skip compiler verification stage.

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

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.

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

However some kind of toolchain configuration affects on generated Makefile. We have to specify correct CMAKE_SYSTEM_NAME (Darwin) and CMAKE_SYSTEM_PROCESSOR (arm).

但是某种工具链配置会影响生成的Makefile。我们必须指定正确的CMAKE_SYSTEM_NAME(Darwin)和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.

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

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