【问题标题】:Duplicate symbol error with GoogleCast.frameworkGoogleCast.framework 出现重复符号错误
【发布时间】:2015-07-03 12:58:30
【问题描述】:

我刚刚开始将一个 Android 应用程序移植到 iOS,并且遇到了一个重大障碍,尽管我搜索了许多类似的问题,但我还是无法弄清楚。

我正在尝试遵循CastVideos sample 中实现的模式,其中GoogleCast API 被封装在我称之为CastManager 的单例类中。要使用我的单例类,我在 AppDelegate.m 中 #import "CastManager.h"。然后在 CastManager.h 中,我 #import <GoogleCast/GoogleCast.h> 以便我可以使用其中的类和协议作为 CastManager 的公共接口的一部分。但是,因为我在 CastManager.m 和 AppDelegate.m 中都导入 CastManager.h,所以链接器会从 GoogleCast 框架中查找重复的符号。

这是我的 CastManager.h:

#import <GoogleCast/GoogleCast.h>
#import <Foundation/Foundation.h>

@interface CastManager : NSObject

@property(nonatomic, strong) GCKDeviceScanner *deviceScanner;

+ (instancetype)sharedCastManager;

@end

以及对应的CastManager.m:

#import "CastManager.h"

@implementation CastManager

+ (instancetype)sharedCastManager {
    NSLog(@"sharedCastManager");
    static CastManager *singleton = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        singleton = [[self alloc] init];
    });
    return singleton;
}

- (instancetype)init {
    NSLog(@"init()");
    if (self = [super init]) {
        self.deviceScanner = [[GCKDeviceScanner alloc] init];
    }
    return self;
}

@end

这是我的 AppDelegate.m 的主要部分:

#import "AppDelegate.h"
#import "CastManager.h"

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    CastManager *castManager = [CastManager sharedCastManager];
    return YES;
}

但是,在尝试构建项目时,这会导致链接器出现以下错误:

duplicate symbol _kGCKDeviceCapabilityVideoOut in:
    /Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/AppDelegate.o
    /Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/CastManager.o
... many similar errors ommitted for brevity ...
duplicate symbol _kGCKDeviceCapabilityAudioIn in:
    /Users/nate/Library/Developer/Xcode/DerivedData/MyCastApp-ezrgxdnlvywpanerezulnarzknno/Build/Intermediates/MyCastApp.build/Debug-iphonesimulator/MyCastApp.build/Objects-normal/x86_64/AppDelegate.o
    /Users/nate/Projects/MyCastApp/GoogleCast.framework/GoogleCast(GCKDevice.o)
ld: 8 duplicate symbols for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

据我所知,这完全复制了 CastVideos 示例中定义的模式,但是该示例编译得很好,而我的却没有,我已经浏览了这两个项目,试图找出不同之处,但是我只是没看到。此外,我认为这样做并没有什么真正的问题,并且希望它能够正常工作。真的,我想不出任何其他方法。

以下是 CastVideos 示例中的相关文件以供比较:

其他问题指向不适用或无法解决的解决方案:

  • 我没有意外导入.m 文件。
  • 我没有对项目中任何文件的重复引用。
  • “构建阶段”项目设置的“编译源代码”部分不包含任何重复项。
  • 我添加了 GoogleCast API 文档中描述的“-ObjC”链接器标志,尽管无论有没有它都会出现相同的错误。
  • 我已尝试删除委托数据并在构建之前进行清理。
  • 这是在 OS X Yosemite 10.10.3 上运行的 Xcode 6.3.1 和来自the SDK documentation page 的 GoogleCastSDK-2.6.0 包

我已在 https://github.com/nshafer/MyCastApp 处签入了我的示例项目,有问题

非常感谢任何帮助!

编辑:副本有些相关,它肯定是相同的符号,但那里的答案没有帮助,因为我没有使用 Object-C++,而只是使用了 Objective-C。我没有 .mm 文件,只有 .m 文件。

【问题讨论】:

标签: ios objective-c xcode google-cast mach-o


【解决方案1】:

对我来说,将“No Common Blocks”编译器设置切换为 NO:

似乎很有道理,这里解释了设置:What is GCC_NO_COMMON_BLOCKS used for?

【讨论】:

  • 这正是我的问题。谢谢。
  • 这解决了,非常感谢!我回顾了 CastVideos 示例,那里的“No Common Blocks”也设置为 No,但它没有突出显示为非默认,所以我错过了。
  • 最近对 XCode (6.4) 的更新使新目标默认此选项为 YES,这让我发疯了,直到找到这个答案,谢谢。
【解决方案2】:

链接器告诉您在两个文件 AppDelegate.m 和 CastManager.m 中有一个名为 kGCKDeviceCapabilityVideoOut 的变量。由于它不在您的源代码中,因此很可能在您包含的 GoogleCast 代码中。

要么更改 GoogleCast.h 文件,要么确保它仅包含在一个 .m 文件中。从 CastManager.h 中包含它意味着它间接包含在每个包含 CastManager.h 的文件中,所以我会避免这种情况,只从 CastManager.m 中包含它。您可能必须添加

@class GCKDeviceScanner;

在您的 CastManager.h 文件中。

【讨论】:

  • 这适用于 GCKDeviceScanner 之类的类,但不适用于 GCKDeviceScannerListener 之类的接口,我的类需要对其进行抽象,这就是我接受其他答案的原因。不过,感谢您的帮助。
【解决方案3】:

我找到了另一个修复方法,即在 GoogleCast.framework/Headers 文件夹中编辑 GCKDevice.h。将文件顶部附近的 4 个常量从 GCK_EXPORT 更改为 GCK_EXTERN

/** Device capability flag for video out. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityVideoOut;
/** Device capability flag for video in. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityVideoIn;
/** Device capability flag for audio out. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityAudioOut;
/** Device capability flag for audio in. */
GCK_EXTERN const NSInteger kGCKDeviceCapabilityAudioIn;

我在bug report 中详细说明了这一点,我向 Google 的问题跟踪器提交了文件,但它被标记为与另一个有些相关的问题重复。无论哪种方式,它可能会在下一个版本中得到修复。在此之前,我建议您更改 Joobik'com 的答案中详述的“No Common Blocks”设置,因为这不涉及更改第 3 方代码。

【讨论】:

    猜你喜欢
    • 2011-02-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-03
    • 2015-04-12
    • 1970-01-01
    相关资源
    最近更新 更多