【问题标题】:Static library having object files with same name (ar)具有同名目标文件的静态库 (ar)
【发布时间】:2011-06-21 21:12:05
【问题描述】:

一点上下文。假设我有源文件,需要在静态库中结束。假设有两个 cpp 文件 a.cppa.cpp 位于两个不同的子目录中。像这样的:

foo/a.h
foo/a.cpp
bar/a.h
bar/a.cpp

它们的内容没有冲突,完全不同。文件名是一样的。

现在,在编译时,我当然会得到两个 a.o 文件。

gcc -c foo/a.cpp -o foo/a.o
gcc -c bar/a.cpp -o bar/a.o

如果我现在用

创建一个静态库
ar rcs libfoobar.a foo/a.o bar/a.o

我可以看到运行nm libfoobar.a 的静态库中的两个文件。看起来不错。

问题

我可以看到的问题是,如果我为 foo/a.obar/a.o 单独运行 ar 命令,将它们放在同一个静态库中。现在后一个对象文件将覆盖前者,所以在运行nm libfoobar.a 时,我只在库中看到后一个对象。我猜这是由于相同的目标文件名造成的。

当使用ar 创建一个静态库时,我应该总是一次性合并所有对象,还是可以多次运行ar 一次收集一部分对象,最终都在同一个静态库中?对于这个例子,我可以看到前者的作品,但不是后者。

a.cpp 发生更改并且静态库需要更改时,事情将如何运作? ar 会在图书馆找到合适的a.cpp 进行更改吗?

这只是一个小例子,但考虑一个包含许多文件并且一些具有相同名称的大型项目。如果您现在想创建一个库,您也可能会遇到这种情况。

总的来说,这只是库的组成方式、文件命名方式的糟糕组织,还是有其他东西可以使事情正常进行?

【问题讨论】:

  • 我认为文件组织不佳..不确定..等待专家 cmets :)

标签: c++ linker static-libraries unix-ar


【解决方案1】:

您必须将ar 视为非常古老的文件存档器。它甚至对归档目录一无所知。 (ar 档案是扁平的)

(人):ar - create, modify, and extract from archives

man ar,选项r

r 将文件成员...插入存档(带替换)。此操作与 q 的不同之处在于,如果 他们的名称与正在添加的成员匹配,则删除任何先前存在的成员。

尝试运行ar t libfoobar.a,您将只看到a.o 文件,因为ar 没有在存档中存储目录名称。

因此,如果您想使用 ar 更新库中的某些对象文件,则必须以不同的方式命名所有放入 ar 存档 (UPD) 的对象文件

ar rcs lib.a foo/a.o bar/a.o 会替换 lib.a 中的 a.o,但不会检查添加的文件是否存在名称冲突。

其他情况:ar rcs lib.a foo/a.oar rcs lib.a bar/a.o 将在存档中存储第一个 a.o,然后第二个 ar 将在存档中找到较旧的 a.o 并替换旧文件。

【讨论】:

  • @osgx:不确定这会如何改变事情。如果我使用一个ar 命令创建一个静态库,我发现它可以在一个静态库中拥有相同命名的对象,而不是如果我执行两次,每个对象文件一个。当然,与对象文件的名称有冲突。所以,我试图找出这里出了什么问题以及为什么它适用于一种情况。
  • 我并不是说按照我的描述去做是个好主意,我只是想知道当我看到运行 ar rcs libfoobar.a foo/a.o bar/a.o 时可能发生的事情时发生了什么,但不是什么时候我运行ar 两次,每个目标文件运行一次。我觉得这很奇怪。
  • "r" 选项与一个文件执行按名称查找和替换。如果您在一个命令中创建整个存档,则所有文件都将放入存档而不比较您添加的所有文件的名称。在我们的大型 unix 项目中,如果其中任何成员发生更改,我们将使用 .a 存档的完整重建。
  • @osgx:谢谢。我不知道。如果在一个命令中添加类似命名的目标文件,该库是否会以某种方式损坏?我的意思是,还有什么其他的东西会成为问题吗?
  • 如果库有多个相同的文件名,则库不会损坏(gcc 和 ld 会将其链接好)。问题是用ar r 替换任何此类文件
【解决方案2】:

库只是函数和/或数据的集合,这些函数和/或数据恰好按库中的目标文件分组,并且这些目标文件有一个名称。这些名称除了更新/提取/删除之外没有任何作用。

因此,两个或多个目标文件有两个相同的名称是完全合法的。 更新库时,图书馆员将第一个对象替换为您要替换的名称,并且不再查看。

但这并不是一件聪明的事情。

【讨论】:

  • @osgx:我们谈论的是库(它们是由 ar 组成的,这不是问题)
  • @osgr:我就是这么说的(我有没有在任何地方提到路径?)
  • 问题作者与ar有问题
  • @osgr: 是的,我告诉他“问题”是什么,这实际上不是问题,而是对具有副作用的库的不寻常使用。
  • @murrekatt:不,这并不奇怪。一旦 ar 找到要替换的名称,它就无需进一步查找即可完成工作。
【解决方案3】:

我只能解决您的部分问题。从 Makefile 语法中我们看到它曾经是一种正常的方式——只更新一个对象。但是例如 automake 的方法是从头开始重建库,即使一个文件被更改。现在问题不大了……

抱歉,目前手头没有unix,所以还是等高手解答吧:)

根据我自己的经验,我不建议在静态库中包含两个同名文件。

【讨论】:

    【解决方案4】:

    GNU 解决了这个问题。手册页解释得很好:

    $ man ar | sed -n '/^       P /,/^       \w/p' | head -n -1;
           P   Use the full path name when matching or storing names in the
               archive.  Archives created with full path names are not POSIX
               compliant, and thus may not work with tools other than up to date
               GNU tools.  Modifying such archives with GNU ar without using P
               will remove the full path names unless the archive is a thin
               archive.  Note that P may be useful when adding files to a thin
               archive since r without P ignores the path when choosing which
               element to replace.  Thus
    
                       ar rcST archive.a subdir/file1 subdir/file2 file1
    
               will result in the first "subdir/file1" being replaced with "file1"
               from the current directory.  Adding P will prevent this
               replacement.
    
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-28
      • 1970-01-01
      • 2011-02-18
      • 1970-01-01
      • 2011-09-04
      相关资源
      最近更新 更多