重复的符号(工作空间中的两个项目使用相同的代码)

时间:2013-10-02 16:12:43

标签: objective-c xcode macos static-libraries duplicate-symbol

A是一个模块项目。有一些测试目标,相关的可重用代码在一个单独的(静态库)目标中编译。 A使用第三方Lumberjack日志记录库。 Lumberjack代码被简单地放入了项目中。

B是一个不同的模块项目,但是它具有与A相同的属性。

C是主要项目。这取决于AB。它链接了AB的库。

编译C将导致重复的Lumberjack符号。

如何才能拥有多个单独的模块项目......

  1. 他们不认识对方,
  2. 使用相同的第三方代码,
  3. 可以自行编译和测试,
  4. 包含在主项目中,没有重复的问题?

7 个答案:

答案 0 :(得分:2)

因此,为了详细说明sergio的answer,我能够成功地构建如下的测试设置。

  1. 我将Lumberjack代码包含在一个单独的项目中,该项目将Lumberjack构建为静态库。
  2. 我创建了一个新项目 ProjectA ,其中包含静态库目标 ModuleA 和测试应用目标 DemoA 。我将Lumberjack项目文件夹复制到 ProjectA 的项目文件夹中,然后将其添加为子项目。我没有让 ModuleA 依赖于Lumberjack或链接 ModuleA 中的Lumberjack。相反,我使 DemoA 依赖于两者并链接两个库。这样,我就可以编译测试目标,但库目标不包括Lumberjack。
  3. 我创建了第二个项目 ProjectB ,模拟设置为 ProjectA
  4. 在主项目中,我将 ProjectA ProjectB 和Lumberjack作为子项目包含在内。不幸的是,这将使Lumberjack在主项目中包括3次,这有点不方便和丑陋(例如,当选择依赖目标时,你无法确定哪一个是哪个)。
  5. 最后,我让主要项目的目标依赖于Lumberjack, ModuleA ModuleB 并链接所有三个库。现在,主项目可以编译而没有重复的符号错误,子模块也可以自己编译和测试。

答案 1 :(得分:1)

我讨厌引用现有的答案,但这里有一个很麻烦但有效的解决方案:What is the best way to solve an Objective-C namespace collision?

我有同样的问题,但我正在研究一个更好的解决方案。另一个可能有用的想法,但我还不确定如何实现它我在这里问:Selectively loading classes in Objective-C

由于某人在我的问题上所说的话,我得到的第三个想法是将一个库包装在一个框架中并创建引用所需函数的函数。然后使用#import <myFramework/MFMyAliases.h>

之类的东西加载

答案 2 :(得分:1)

您是否尝试使用ar查看图书馆?如果你很幸运,那就跑步吧

ar -t libA.a

为您提供了

等文件列表
__.SYMDEF SORTED
Afile1.o
Afile2.o
Lumberjack1.o
Lumberjack2.o
Afile3.o
SomeOtherLibrary.o

其中Lumberjack文件与其他文件明显不同。然后,你可以踢它们 与

a -d Lumberjack1.o Lumberjack2.o

并在单独测试C时使用完整库时,将A链接到此剪裁的库。

答案 3 :(得分:1)

由于您的目标是OSX,因此您的问题的解决方案是将Lumberjack构建为框架(而不是链接A和B模块中的源代码),然后在任何需要的地方使用该框架(即,在任何项目中)使用A或B模块)。

事实上,Lumberjack已经包含了一个将构建Lumberjack.framework的项目,请查看:CocoaLumberjack/Xcode/LumberjackFramework/Desktop/Lumberjack.xcodeproj

详细说明,您可以像现在一样定义A和B模块,但不要在其中删除Lumberjack源代码。 相反,只要您想在可执行文件(例如,您的测试目标)中使用A静态库,您就可以将库添加到目标以及伐木工程框架(就像您使用OSX SDK框架一样)。 / p>

如果你愿意,添加动态框架只是“放弃源代码”的另一种方式,但是做得不错。

如果要在C项目中使用两者 A和B,可以将静态库和Lumberjack框架添加到C中。

正如您所看到的,这种做法将符合您的所有四项要求,代价是引入一个依赖:您需要在静态库文档中明确说明它们依赖于伐木工人框架。这实际上不是一个大问题,因为后者可以在自己的项目中使用,任何人都可以自己构建它。

如果你想改进对这种依赖关系的处理,可以采用cocoapods(cocoapod是一个与你的库关联的文件,它描述了它的依赖关系,所以当你安装你的库时,cocoapods系统也会自动安装依赖)。但这是高度可选的。单个依赖关系不是记录或遵守的大问题。

希望这能回答你的问题。

答案 4 :(得分:1)

我试图在几个月之前达到同样的目的,“Easy, Modular Code Sharing Across iPhone Apps: Static Libraries and Cross-Project References”文章得到了我所需要的一切。请查看它是否有用。

答案 5 :(得分:0)

AB二进制文件?

如果不是,您只需取消选中其中一个项目的所有*.m文件的编译复选框,以避免构建重复的对象。

此外,如果您可以使用AB彻底Cocoapods,那将是最好的。

答案 6 :(得分:0)

尝试this

它在不同项目之间共享库/模块。