【问题标题】:Xcode unittest build failed with error "Undefined symbols for architecture x86_64"Xcode unittest 构建失败,出现错误“架构 x86_64 的未定义符号”
【发布时间】:2015-09-05 06:56:12
【问题描述】:

我的单元测试目标构建失败并出现以下错误:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_MCStore", referenced from:
      objc-class-ref in MCStoreTests.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

基本信息:

  • Xcode6.2
  • iOS8.2 SDK

我检查过的内容:

  • Symbols Hidden by Default
  • Other Linker Flags 是-framework XCTest
  • Framework Search Paths 是 $(SDKROOT)/Developer/Library/Frameworks $(inherited)

【问题讨论】:

  • MCStore 类在哪里实现?
  • 它在我的应用程序目标中实现。
  • 并且测试目标包含那个实现文件?
  • 不,我已将我的应用程序目标添加到 unittest 目标依赖项中

标签: ios xcode


【解决方案1】:

对我来说,当我尝试在以前只有 UI 测试的项目中编写和运行单元测试时,我收到了类似的错误消息。经过数小时的故障排除后,我意识到问题在于我当前的测试目标用于 UI 测试,不是单元测试。

要解决这个问题,我只需要添加一个新的 Unit Testing Bundle 目标,然后确保我尝试运行的每个单元测试文件都有其 Target Membership设置为我刚刚创建的新目标。

【讨论】:

    【解决方案2】:

    Xcode 12.3 (12C33) – 我刚刚删除了测试目标和所有引用。然后创建新的测试目标,并添加回我所有的测试文件✓ 正常工作

    【讨论】:

    • 我注意到测试目标在 Xcode 版本之间以某种方式中断。因此,这种方式获得了全新的开始。
    【解决方案3】:

    在我的情况下,当我需要测试存在于我的应用程序一部分的 framework 中的类时出现此错误:

    测试框架类。
    1. macOS 添加测试目标。
    2. 选择项目/目标窗口。选择测试目标。
    3. 转到“构建阶段”,“将二进制文件与库链接”,添加您要测试的框架
    4. 在测试类(setup/teardown)中,将“import”添加到要从该框架测试的类中

    【讨论】:

      【解决方案4】:

      在我的特定情况下,我试图测试 release 配置并遇到此特定错误。在尝试了不同的编译标志后,我发现在我的项目(不是特定目标,但也可能工作)上为发布配置设置 Enable Testability 可以解决问题。

      【讨论】:

        【解决方案5】:

        在将测试目标添加到 2 或 3 个 Xcode 版本之前创建的旧项目后遇到相同的链接器错误。此外,项目有各种 xcodeproject/target/bundle 名称。所有可能的重命名清理Build settingsBuild phasesScheme 操作对我都不起作用。

        经过长期努力后真正奏效的是在最新的 Xcode 版本中从头开始重新创建项目以及所有目标。它终于链接了!而且在这种情况下你甚至不需要手动修改Search pathsBundle loader,Xcode 会帮你搞定。

        【讨论】:

          【解决方案6】:

          对我有用的只是在 podfile 上使用测试目标。

          target 'MyAppName' do
            use_frameworks!
          
            pod 'SwiftLint'
            pod 'RxSwift'
            pod 'RxCocoa'
            pod 'RxDataSources'
            pod 'RxGRDB'
          
            target 'UnitTestTarget' do
              inherit! :search_paths  
            end
          end
          

          【讨论】:

            【解决方案7】:

            所以这对我有用...

            override func setUp() {
            
                super.setUp()
            
                let promise = expectation(description: "App has finished running")
            
                DispatchQueue.global(qos: .background).async{
                    // Wait on the background thread
                    sleep(4)
                    DispatchQueue.main.async {
                        // Fullfill the promise in the main thread
                        promise.fulfill()
                    }
                }
            
                // Initialize the storyboard
                let storyboard = UIStoryboard(name: "Main", bundle: nil)
            
                // Get the view controller
                sut = storyboard.instantiateViewController(withIdentifier: String(describing: ViewController.self)) as? ViewController
                _ = sut.view
            
                waitForExpectations(timeout: 5) { (_) in
                    // Finish set up after the app is done running its code
                }
            
            }// End setUp() Method
            

            【讨论】:

              【解决方案8】:

              这个错误可能是因为测试目标类型错误,即ui test target

              UI 测试目标不能使用主目标的内部结构,即使是 @testable 导入也不行。 OTOH 可以使用内部单元测试目标。

              See more details in this answer.

              (我相信这在某些 XCode 版本中发生了变化,这会导致混淆。典型的方法是在 ui 测试目标中包含来自原始目标的大量文件。正确的方法是以这种方式设计 UI 测试他们不需要或使用来自主要目标的大量代码。)

              【讨论】:

                【解决方案9】:

                以下是我尝试在 Xcode 9 中添加单元测试目标时为解决该问题而执行的步骤:

                1. 转到“管理方案”。
                2. 点击底部的“+”按钮。
                3. 选择新添加的目标并选择“确定”。
                4. 确保为新添加的目标选择了“共享”选项。

                【讨论】:

                  【解决方案10】:

                  至少从 Xcode 7.3 开始,测试目标允许您选择“主机应用程序”。在测试目标(但目前不是 UI 测试目标)中,这会自动填充“测试主机”构建设置,而不是“捆绑加载器”,这会导致找不到类。

                  考虑到这一点,如果您将测试目标的“Bundle Loader”构建设置设置为$(TEST_HOST),即使您更改主机应用程序,它也将始终包含正确的值。

                  这实际上与@yuwen-yan 发布的链接中给出的建议相反,应该减少工作量。

                  【讨论】:

                  • 我发现 $(TEST_HOST) 是默认配置,但我的一个 pod 仍然没有找到。
                  • 在 Xcode9.2 中,它现在位于测试目标 > 构建设置 > 测试 > 测试主机下。添加 $(TEST_HOST) 仍然有效。不过,我也确实更新了我的 cocoapods。
                  【解决方案11】:

                  遇到了同样的问题。 为我解决的问题是将测试目标 Build Settings 中的 enable modules (c and objective-c) 设置为 YES

                  【讨论】:

                    【解决方案12】:

                    根据这个link,我需要在unittest目标Build Settings中设置Bundle Loader的以下内容

                    $(BUILT_PRODUCTS_DIR)/MyExistingApp.app/MyExistingApp

                    【讨论】:

                    • 这个答案是救生员!!!我很高兴我偶然发现了它!!!非常感谢!!!
                    • 为什么会这样?为什么这在 XCode 中不能开箱即用?
                    • 这些线值金!!!非常感谢。帮助我解决了具有单元测试、ui-test 和不同部署目标的项目中无穷无尽的 Mach-O 链接器错误。
                    • 我不得不用 XCode 8.2 创建一个全新的项目。
                    • 补充说明 - 步骤 > 返回您的应用程序目标(不是测试目标),将 Symbols Hidden by Default 构建设置设置为 NO 此选项仅在您选择 BUILD 下的“全部”时可见设置
                    猜你喜欢
                    • 2021-06-27
                    • 2021-04-13
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2018-01-14
                    • 2015-03-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多