编辑这是一个 known CMake issue .
使用 Xcode 11(特别是 Xcode 11.2.1),我曾经能够使用以下命令交叉编译 iOS 项目:
cd /path/to/project
mkdir build
cd build
cmake .. -G Xcode -DCMAKE_SYSTEM_NAME=iOS \
"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
-DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO \
-DCMAKE_IOS_INSTALL_COMBINED=YES \
-DCMAKE_INSTALL_PREFIX=install
cmake --build . --config Release --target install
这创建了一个包含两个切片的构建,一个切片用于 arm64
架构(用于在真实设备上运行),一个切片用于 x86_64
架构(用于在基于 Intel 的开发环境上的模拟器)。
升级到 Xcode 12(特别是 Xcode 12.3)后,此功能不再有效。构建始终失败并显示此错误消息(我添加的换行符):
error: unable to attach DB: error: accessing build database "/path/to/project/build/ios/build/XCBuildData/build.db":
database is locked Possibly there are two concurrent builds running in the same filesystem location.
问题似乎是 CMake 为 install
目标创建的构建后规则。在该构建后规则中,当第一个构建仍在进行时,将启动第二个构建。
if test "$CONFIGURATION" = "Release"; then :
cd /path/to/project/build/ios
/usr/local/Cellar/cmake/3.19.2/bin/cmake -DBUILD_TYPE=$CONFIGURATION -DEFFECTIVE_PLATFORM_NAME=$EFFECTIVE_PLATFORM_NAME -P cmake_install.cmake
fi
当我不再将 CMAKE_IOS_INSTALL_COMBINED
设置为 YES
时,构建成功,但生成的构建仅包含一个切片(在我的情况下是 arm64
,大概是因为这是 CMAKE_OSX_ARCHITECTURES
中列出的第一个架构。
我正在考虑为每个架构进行单独的构建,然后手动将切片拼接在一起。在我走这条路之前,有没有人能够找到更优雅的解决方案?
环境:macOS 11.1、Xcode 12.3、CMake 3.19.2
最佳答案
CMake 3.19 release notes包含此提示:
The Xcode generator now uses the Xcode “new build system” when generating for Xcode 12.0 or higher. See the
CMAKE_XCODE_BUILD_SYSTEM
variable. One may use-T buildsystem=1
to switch to the legacy build system.
因此,目前的解决方法是将 -T
选项添加到构建系统生成命令行:
cmake .. -G Xcode -T buildsystem=1
-DCMAKE_SYSTEM_NAME=iOS \
"-DCMAKE_OSX_ARCHITECTURES=arm64;x86_64" \
-DCMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH=NO \
-DCMAKE_IOS_INSTALL_COMBINED=YES \
-DCMAKE_INSTALL_PREFIX=install
只要 Xcode 仍然支持旧版构建系统,这就应该有效。 Xcode 12 Release Notes对此事有话要说:
The legacy build system is deprecated, and will be removed in a future release. (62742902)
因此,-T buildsystem=1
选项只能被视为临时解决方法。
关于CMake 构建失败,Xcode 12 和 CMAKE_IOS_INSTALL_COMBINED=YES,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65550550/