[英]How to use Fastlane with a CMake generated XCode project with dependency on WebP?
我有一个用 C++ 编写的项目,其中 CMake 用于为包括 iOS 在内的各种平台生成构建系统。该项目依赖于WebP 。 您可以在此处的 GitHub 上找到一个示例项目,该项目可用于重现内容,为了完整起见,我在本文末尾包含了相关的源文件。
iOS 的 Xcode 构建系统是使用 CMake 生成的,如下所示:
cmake -G Xcode -DCMAKE_TOOLCHAIN_FILE=third_party/ios-cmake/ios.toolchain.cmake -DPLATFORM=OS64 -DDEPLOYMENT_TARGET=15.0 -DENABLE_BITCODE=0 -S. -B cmake-build-release
我们现在可以尝试使用生成的cmake-build-release
目录中的命令使用Fastlane构建/归档应用程序:
bundle exec fastlane ios beta
然而,由于无法找到各种 webp object 文件(基于控制台 output,它似乎之前已成功编译)而失败:
...
▸ Compiling buffer_dec.c
▸ Compiling alpha_dec.c
▸ Building library libwebpdsp.a
...
** ARCHIVE FAILED **
▸ The following build commands failed:
▸ Libtool /Users/dbotha/Library/Developer/Xcode/DerivedData/CMakeFastlaneWebpTest-dlwvukebfiwjqvaqiepshuxqklhh/ArchiveIntermediates/CMakeFastlaneWebpTest/IntermediateBuildFilesPath/UninstalledProducts/iphoneos/libwebpdecoder.a normal (in target 'webpdecoder' from project 'CMakeFastlaneWebpTest')
▸ (1 failure)
▸ ❌ error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't open file: /Users/dbotha/CLionProjects/CMakeFastlaneWebpTest/cmake-build-release/third_party/libwebp/CMakeFastlaneWebpTest.build/Release-iphoneos/webpdecode.build/Objects-normal/arm64/alpha_dec.o (No such file or directory)
▸ ❌ error: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: can't open file: /Users/dbotha/CLionProjects/CMakeFastlaneWebpTest/cmake-build-release/third_party/libwebp/CMakeFastlaneWebpTest.build/Release-iphoneos/webpdecode.build/Objects-normal/arm64/buffer_dec.o (No such file or directory)
...
在内部,Fastlane 尝试使用以下命令构建/归档项目:
xcodebuild -scheme CMakeFastlaneWebpTest -project./CMakeFastlaneWebpTest.xcodeproj -configuration Release -destination 'generic/platform=iOS' -archivePath./out.xcarchive archive
有趣的是,如果我使用以下xcodebuild
命令可以成功生成存档(请注意如何使用-target
标志而不是-scheme
):
xcodebuild -project CMakeFastlaneWebpTest.xcodeproj archive -target CMakeFastlaneWebpTest -configuration Release
在这次成功尝试之后, bundle exec fastlane ios beta
现在也将成功,因为已编译的 object 文件位于预期的位置。
现在我很乐意使用我的xcodebuild
+ -target
标志方法解决这个问题,然后使用 fastlane 命令推送到 Testflight 等。但是真正的项目(不是这个玩具示例)需要很长时间来构建所以构建它两次在 CI 平台上从成本的角度来看真的很浪费。
有谁知道这里发生了什么以及我如何在没有我自己明确调用xcodebuild
的情况下使用 fastlane 在第一个实例中成功构建东西? 或者我怎样才能让 Fastlane 使用我的解决方法中成功构建的对象,这样它就不需要从头开始重建整个项目?
CMakeLists.txt
cmake_minimum_required(VERSION 3.23)
project(CMakeFastlaneWebpTest)
set(CMAKE_CXX_STANDARD 14)
add_executable(CMakeFastlaneWebpTest src/main.cpp)
# Skip building of unused webp tools which fail for me under ios:
set(WEBP_BUILD_ANIM_UTILS OFF)
set(WEBP_BUILD_CWEBP OFF)
set(WEBP_BUILD_DWEBP OFF)
set(WEBP_BUILD_GIF2WEBP OFF)
set(WEBP_BUILD_IMG2WEBP OFF)
set(WEBP_BUILD_VWEBP OFF)
set(WEBP_BUILD_WEBPINFO OFF)
set(WEBP_BUILD_WEBPMUX OFF)
set(WEBP_BUILD_EXTRAS OFF)
set(WEBP_BUILD_WEBP_JS OFF)
add_subdirectory(third_party/libwebp EXCLUDE_FROM_ALL)
target_link_libraries(CMakeFastlaneWebpTest PRIVATE webpdecoder webpdemux)
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/third_party/libwebp/src)
configure_file(${CMAKE_SOURCE_DIR}/fastlane/Appfile ${CMAKE_BINARY_DIR}/fastlane/Appfile COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/fastlane/Fastfile ${CMAKE_BINARY_DIR}/fastlane/Fastfile COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/Gemfile ${CMAKE_BINARY_DIR}/Gemfile COPYONLY)
configure_file(${CMAKE_SOURCE_DIR}/Gemfile.lock ${CMAKE_BINARY_DIR}/Gemfile.lock COPYONLY)
set_target_properties(CMakeFastlaneWebpTest PROPERTIES
XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET}
MACOSX_BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_SOURCE_DIR}/src/iOS-Info.plist.in
MACOSX_BUNDLE_GUI_IDENTIFIER com.dbotha.CMakeFastlaneWebpTest
MACOSX_BUNDLE_BUNDLE_NAME CMakeFastlaneWebpTest
MACOSX_BUNDLE_BUNDLE_VERSION "0.1"
MACOSX_BUNDLE_SHORT_VERSION_STRING "0.1"
)
set_xcode_property(CMakeFastlaneWebpTest PRODUCT_BUNDLE_IDENTIFIER "com.dbotha.CMakeFastlaneWebpTest" All)
set_xcode_property(CMakeFastlaneWebpTest CODE_SIGN_IDENTITY "iPhone Developer" All)
set_xcode_property(CMakeFastlaneWebpTest DEVELOPMENT_TEAM "GFP63373B2" All)
快车道/应用文件
app_identifier("com.dbotha.CMakeFastlaneWebpTest") # The bundle identifier of your app
apple_id("REPLACE_ME") # Your Apple Developer Portal username
itc_team_id("REPLACE_ME") # App Store Connect Team ID
team_id("REPLACE_ME") # Developer Portal Team ID
快速通道/快速文件
default_platform(:ios)
platform :ios do
desc "Push a new beta build to TestFlight"
lane :beta do
build_app(scheme: "CMakeFastlaneWebpTest", configuration: "Release")
upload_to_testflight
end
end
源代码/main.cpp
#include <iostream>
#include <webp/demux.h>
int main() {
WebPAnimDecoderOptions decOptions;
(void)decOptions;
std::cout << "Hello, World!" << std::endl;
return 0;
}
要将 Fastlane 与CMake
生成的Xcode
依赖于WebP
的项目一起使用,您可以尝试修改Fastfile
以指定要构建的目标。
在ios
通道中,您可以添加xcodebuild
操作并指定 -target 标志,后跟您要构建的目标的名称。 例如:
lane :ios do
# ...
xcodebuild(
scheme: "CMakeFastlaneWebpTest",
project: "./CMakeFastlaneWebpTest.xcodeproj",
configuration: "Release",
destination: "generic/platform=iOS",
archive_path: "./out.xcarchive",
action: "archive",
target: "CMakeFastlaneWebpTest" # Add this flag to specify the target
)
# ...
end
或者,您可以尝试修改Xcode
中的方案以正确构建WebP
依赖项。 为此,您可以 go 到 Xcode 中的"Manage Schemes"
菜单, Xcode
您要修改的方案,并将WebP
目标添加为方案的依赖项。 这应该确保在构建主要目标之前构建WebP
依赖项。
我不是该主题的专家,但根据文档,您应该提供工作空间来构建您的方案。
要构建 Xcode 工作区,您必须同时传递 -workspace 和 -scheme 选项来定义构建。 该方案的参数将控制构建哪些目标以及如何构建它们,尽管您可以将其他选项传递给 xcodebuild 以覆盖该方案的某些参数。
Scheme 控制将构建什么目标,并通过您的示例进行猜测,因为您没有提供工作区,它会在此过程中丢失。
如果您手动构建目标,该方案不会再丢失。 由于它已经构建,因此该方案不必做任何事情。
我的建议:
build_app
参数。build_app
参数中使用目标,如下所示: build_app(target: "CMakeFastlaneWebpTest", configuration: "Release")
尝试为此,您可以将以下行添加到您的 CMakeLists.txt 文件中:
set_target_properties(webpdecoder PROPERTIES XCODE_ATTRIBUTE_BUILT_PRODUCTS_DIR "${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}")
这会将 webpdecoder 目标的 BUILT_PRODUCTS_DIR 构建设置设置为当前配置的当前二进制目录。
您可能还需要在 Xcode 项目中指定 CONFIGURATION_BUILD_DIR 构建设置。 您可以通过将以下行添加到 CMakeLists.txt 文件来执行此操作:
set_target_properties(webpdecoder PROPERTIES XCODE_ATTRIBUTE_CONFIGURATION_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}")
这会将 webpdecoder 目标的 CONFIGURATION_BUILD_DIR 构建设置设置为当前配置的当前二进制目录。
这些构建设置应该可以帮助 Fastlane 找到由 CMake 编译的 object 文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.