【问题标题】:Swift Package Manager and Xcode: Retaining Xcode Settings?Swift 包管理器和 Xcode:保留 Xcode 设置?
【发布时间】:2017-05-22 12:28:16
【问题描述】:

我正在使用 Swift 开发服务器并使用 Swift 包管理器。并且发现在我的 Mac OS 系统上进行开发以生成 Xcode 项目以使用 Xcode 作为我的 IDE 时很方便(即,有时我的包依赖项必须更新。我一直使用swift package generate-xcodeproj 来做这个。我的问题出现在这一点上——我在 Xcode 中创建了一些设置。例如,我设置了一个 DEBUG 标志,并且我有一个处于复制文件阶段的 .plist 文件。这些在我重新生成时会丢失Xcode 项目。看来我不能简单地使用swift package update,因为有时文件在依赖项中会发生变化,而这些文件不会传播到 Xcode 项目。

我想要的是一种在 Xcode 之外的文件中单独建立 Xcode 设置的方法,当我执行 swift package generate-xcodeproj 时可以将其导入 Xcode。我还没有看到这样做的方法。

一个相关的问题是:当我执行swift build 时,我希望使用相同的构建设置。

建议?

【问题讨论】:

    标签: swift xcode swift-package-manager server-side-swift


    【解决方案1】:

    每次您重新生成它时,我都会使用脚本或 makefile 将您的设置导入到生成的 Xcode 项目中。你可以使用xcodeproj rubygem

    an example script

    关于在swift build 中使用你的设置,你能举一个这样的设置的例子吗?一般来说,makefile 可以读取您的设置文件并将相应的参数传递给swift build

    【讨论】:

    • 谢谢!我很快就会试一试。我需要在swift build 中使用的设置示例是设置 DEBUG 标志以有条件地编译仅调试代码。另外,我有一个需要提供的 Server.plist 文件。我在测试和非测试版本中提供了不同的功能,但这是我的 Xcode 构建配置的一部分。
    • DEBUG 标志是使用swift build-c debug|release 标志设置的。有关其他选项,请参阅an example of a Makefile
    • 我得到了那个 ruby​​gem 解决方案!我已经把它作为答案放在下面。按照上面的链接 (stackoverflow.com/users/6028420/vadim-eisenberg),我找不到 Makefile 示例。
    • @ChrisPrince 奇怪,你能访问https://github.com/IBM-Swift/GRMustache.swift 吗? Makefile 在此存储库中。
    【解决方案2】:

    Copy Files Phase 帮不上忙。

    但是我只是在玩弄条件编译,像这样:

    swift package generate-xcodeproj --xcconfig-overrides Sandbox.xcconfig
    

    沙盒.xcconfig

    FLAG_SANDBOX = -DSANDBOX
    OTHER_SWIFT_FLAGS = $(FLAG_SANDBOX)
    

    这将创建一个 Xcode 项目,其中定义了 SANDBOX

    这可以用在这样的swift代码中

    #if SANDBOX
        print("sandbox")
    #else
        print("production")
    #endif
    

    【讨论】:

    • 对环境变量或例如要传入的命令有什么建议吗?
    【解决方案3】:

    根据上面@vadim 的回答,这是我问题第一部分的xcodeproj rubygem 解决方案:

    #!/usr/bin/ruby
    
    # Tweak the .xcodeproj after creating with the swift package manager.
    
    # Resources: 
    # https://stackoverflow.com/questions/41527782/swift-package-manager-and-xcode-retaining-xcode-settings/41612477#41612477
    # https://stackoverflow.com/questions/20072937/add-run-script-build-phase-to-xcode-project-from-podspec
    # https://github.com/IBM-Swift/Kitura-Build/blob/master/build/fix_xcode_project.rb
    # http://www.rubydoc.info/github/CocoaPods/Xcodeproj/Xcodeproj%2FProject%2FObject%2FAbstractTarget%3Anew_shell_script_build_phase
    # http://www.rubydoc.info/github/CocoaPods/Xcodeproj/Xcodeproj/Project/Object/AbstractTarget
    # https://gist.github.com/niklasberglund/129065e2612d00c811d0
    # https://github.com/CocoaPods/Xcodeproj
    # https://stackoverflow.com/questions/34367048/how-do-you-automate-do-copy-files-in-build-phases-using-a-cocoapods-post-insta?rq=1
    
    require 'xcodeproj'
    
    path_to_project = "Server.xcodeproj"
    project = Xcodeproj::Project.open(path_to_project)
    
    # 1) Add Copy Files Phase for Server.plist to the Products directory for Server target
    target = project.targets.select { |target| target.name == 'Server' }.first
    puts "Add Copy Files Phase to #{target}"
    phase = target.new_copy_files_build_phase()
    
    # Contrary to the docs (see http://www.rubydoc.info/github/CocoaPods/Xcodeproj/Xcodeproj/Project/Object/PBXCopyFilesBuildPhase) I believe this is not a path, but rather a code, e.g., 16 indicates to copy the file to the Products Directory.
    phase.dst_subfolder_spec = "16"
    
    fileRef = project.new(Xcodeproj::Project::Object::PBXFileReference)
    fileRef.path = 'Server.plist'
    
    phase.add_file_reference(fileRef)   
    
    # 2) Add in script phase for testing target-- because I haven't figured out to get access to the Products directory at test-run time.
    target = project.targets.select { |target| target.name == 'ServerTests' }.first
    puts "Add Script Phase to #{target}"
    phase = target.new_shell_script_build_phase()
    phase.shell_script = "cp Server.plist /tmp"
    
    # 3) Add in DEBUG flag
    
    # A little overkill, but hopefully appending a DEBUG flag in the Debug configuration for each target doesn't hurt it.
    project.targets.each do |target|
        puts "Appending DEBUG flag to #{target}"
    
        if target.build_settings('Debug')['OTHER_SWIFT_FLAGS'].nil?
            target.build_settings('Debug')['OTHER_SWIFT_FLAGS'] = ""
        end
    
        target.build_settings('Debug')['OTHER_SWIFT_FLAGS'] << '-DDEBUG'
    end
    
    project.save()
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-15
      • 2022-10-22
      • 1970-01-01
      • 2019-04-21
      • 2017-06-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多