简体   繁体   English

如何将 Fastlane 与 CMake 生成的 XCode 依赖于 WebP 的项目一起使用?

[英]How to use Fastlane with a CMake generated XCode project with dependency on WebP?

I have a project written in C++ where CMake is used to generate the build system for various platforms including iOS. The project has a dependency on WebP .我有一个用 C++ 编写的项目,其中 CMake 用于为包括 iOS 在内的各种平台生成构建系统。该项目依赖于WebP You can find an example project on GitHub here that can be used to reproduce things & I've included the relevant source files at the end of this post for completeness.您可以在此处的 GitHub 上找到一个示例项目,该项目可用于重现内容,为了完整起见,我在本文末尾包含了相关的源文件。

The Xcode build system for iOS is generated using CMake as follows: 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

We can now attempt to build/archive the app using Fastlane with the command from within the generated cmake-build-release directory:我们现在可以尝试使用生成的cmake-build-release目录中的命令使用Fastlane构建/归档应用程序:

bundle exec fastlane ios beta

However this fails due to being unable to locate various webp object files (that based on console output it appears to have previously successfully compiled):然而,由于无法找到各种 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)

...

Internally Fastlane attempted to build/archive the project with the following command:在内部,Fastlane 尝试使用以下命令构建/归档项目:

xcodebuild -scheme CMakeFastlaneWebpTest -project./CMakeFastlaneWebpTest.xcodeproj -configuration Release -destination 'generic/platform=iOS' -archivePath./out.xcarchive archive

Interestingly an archive can be successfully generated if I use the following xcodebuild command (note how -target flag is used instead of -scheme ):有趣的是,如果我使用以下xcodebuild命令可以成功生成存档(请注意如何使用-target标志而不是-scheme ):

xcodebuild -project CMakeFastlaneWebpTest.xcodeproj archive -target CMakeFastlaneWebpTest -configuration Release

After this successful attempt bundle exec fastlane ios beta will now also succeed as the compiled object files are where it expected them to be.在这次成功尝试之后, bundle exec fastlane ios beta现在也将成功,因为已编译的 object 文件位于预期的位置。

Now I'd happily workaround this issue using my xcodebuild + -target flag approach and then use the fastlane command to push to Testflight, etc. but the real project (not this toy example) takes a very long time to build so building it twice is really wasteful from a cost point of view on CI platforms.现在我很乐意使用我的xcodebuild + -target标志方法解决这个问题,然后使用 fastlane 命令推送到 Testflight 等。但是真正的项目(不是这个玩具示例)需要很长时间来构建所以构建它两次在 CI 平台上从成本的角度来看真的很浪费。

Does anyone have any idea what's going on here & how I can successfully build things in the first instance using fastlane without my own explicit call to xcodebuild first?有谁知道这里发生了什么以及我如何在没有我自己明确调用xcodebuild的情况下使用 fastlane 在第一个实例中成功构建东西? Or alternatively how can I have Fastlane use the successfully built objects from my workaround so it doesn't need to rebuild the entire project from scratch?或者我怎样才能让 Fastlane 使用我的解决方法中成功构建的对象,这样它就不需要从头开始重建整个项目?


CMakeLists.txt 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)

fastlane/Appfile快车道/应用文件

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

fastlane/Fastfile快速通道/快速文件

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

src/main.cpp源代码/main.cpp

#include <iostream>
#include <webp/demux.h>

int main() {
    WebPAnimDecoderOptions decOptions;
    (void)decOptions;
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

To use Fastlane with a CMake generated Xcode project that has a dependency on WebP , you can try modifying the Fastfile to specify the target that you want to build.要将 Fastlane 与CMake生成的Xcode依赖于WebP的项目一起使用,您可以尝试修改Fastfile以指定要构建的目标。

In the ios lane, you can add the xcodebuild action and specify the -target flag followed by the name of the target that you want to build.ios通道中,您可以添加xcodebuild操作并指定 -target 标志,后跟您要构建的目标的名称。 For example:例如:

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

Alternatively, you can try modifying the scheme in Xcode to correctly build the WebP dependency.或者,您可以尝试修改Xcode中的方案以正确构建WebP依赖项。 To do this, you can go to the "Manage Schemes" menu in Xcode , select the scheme that you want to modify, and add the WebP target as a dependency of the scheme.为此,您可以 go 到 Xcode 中的"Manage Schemes"菜单, Xcode您要修改的方案,并将WebP目标添加为方案的依赖项。 This should ensure that the WebP dependency is built before the main target is built.这应该确保在构建主要目标之前构建WebP依赖项。

I'm not an expert in this topic but according to the documentation you should provide workspace to build your scheme.我不是该主题的专家,但根据文档,您应该提供工作空间来构建您的方案。

To build an Xcode workspace, you must pass both the -workspace and -scheme options to define the build.要构建 Xcode 工作区,您必须同时传递 -workspace 和 -scheme 选项来定义构建。 The parameters of the scheme will control which targets are built and how they are built, although you may pass other options to xcodebuild to override some parameters of the scheme.该方案的参数将控制构建哪些目标以及如何构建它们,尽管您可以将其他选项传递给 xcodebuild 以覆盖该方案的某些参数。

Scheme controls what target will be build, and guessing by your example, since you do not provide a workspace, it gets lost in the process. Scheme 控制将构建什么目标,并通过您的示例进行猜测,因为您没有提供工作区,它会在此过程中丢失。

The scheme is not lost anymore if you build the target manually.如果您手动构建目标,该方案不会再丢失。 Since it is already build the scheme does not have to do a thing.由于它已经构建,因此该方案不必做任何事情。

My proposals:我的建议:

  • Option 1: Try adding workspace to build_app parameters in Fastfile.选项 1:尝试将工作区添加到build_app参数。
  • Option 2: Don't bother with building scheme just use target in the build_app parameters in Fastfile like so: build_app(target: "CMakeFastlaneWebpTest", configuration: "Release")选项 2:不要打扰构建方案,只需在 Fastfile 的build_app参数中使用目标,如下所示: build_app(target: "CMakeFastlaneWebpTest", configuration: "Release")

Try To do this, you can add the following line to your CMakeLists.txt file:尝试为此,您可以将以下行添加到您的 CMakeLists.txt 文件中:

set_target_properties(webpdecoder PROPERTIES XCODE_ATTRIBUTE_BUILT_PRODUCTS_DIR "${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}")

This will set the BUILT_PRODUCTS_DIR build setting for the webpdecoder target to the current binary directory for the current configuration.这会将 webpdecoder 目标的 BUILT_PRODUCTS_DIR 构建设置设置为当前配置的当前二进制目录。

You may also need to specify the CONFIGURATION_BUILD_DIR build setting in your Xcode project.您可能还需要在 Xcode 项目中指定 CONFIGURATION_BUILD_DIR 构建设置。 You can do this by adding the following line to your CMakeLists.txt file:您可以通过将以下行添加到 CMakeLists.txt 文件来执行此操作:

set_target_properties(webpdecoder PROPERTIES XCODE_ATTRIBUTE_CONFIGURATION_BUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/\${CONFIGURATION}")

This will set the CONFIGURATION_BUILD_DIR build setting for the webpdecoder target to the current binary directory for the current configuration.这会将 webpdecoder 目标的 CONFIGURATION_BUILD_DIR 构建设置设置为当前配置的当前二进制目录。

These build settings should help Fastlane locate the object files that were compiled by CMake.这些构建设置应该可以帮助 Fastlane 找到由 CMake 编译的 object 文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM