【问题标题】:How can I extract static libs containing repeated object files?如何提取包含重复目标文件的静态库?
【发布时间】:2012-02-08 19:07:55
【问题描述】:

我正在尝试构建一个合并两个静态库的大型静态库。现在我正在使用“ar”命令,例如从“a.a”和“b.a”中提取对象,然后再次使用“ar”重新组装这些对象:

$ ar x a.a
$ ar x b.a
$ ar r merged.a *.o

不幸的是,它不适用于我的目的,因为 a.a 在内部具有相同名称的不同对象。 'ar' 命令提取重复的对象并用相同的名称替换已经提取的对象。即使名称相同,这些对象也有不同的符号,所以我得到未定义的引用,因为某些符号与被替换的文件一起丢失。

我无法访问原始对象,并且已经尝试过“ar xP”和“ar xv”以及许多“ar stuff”。有谁可以帮我展示如何合并这些库?

提前致谢。

【问题讨论】:

    标签: linux static-libraries libraries unix-ar


    【解决方案1】:

    我尝试了“ar p”,但与朋友交谈后决定以下 python 解决方案可能会更好。现在可以提取重复的目标文件了。

    def extract_archive(pathtoarchive, destfolder) :
    
        archive = open(pathtoarchive, 'rb')
    
        global_header = archive.read(8)
        if global_header != '!<arch>\n' :
            print "Oops!, " + pathtoarchive + " seems not to be an archive file!"
            exit()
    
        if destfolder[-1] != '/' :
            destfolder = destfolder + '/'
    
        print 'Trying to extract object files from ' + pathtoarchive
    
        # We don't need the first and second chunk
        # they're just symbol and name tables
    
        content_descriptor = archive.readline()
        chunk_size = int(content_descriptor[48:57])
        archive.read(chunk_size)
    
        content_descriptor = archive.readline()
        chunk_size = int(content_descriptor[48:57])
        archive.read(chunk_size)
    
        unique_key = 0;
    
        while True :
    
            content_descriptor = archive.readline()
    
            if len(content_descriptor) < 60 :
                break
    
            chunk_size = int(content_descriptor[48:57])
    
            output_obj = open(destfolder + pathtoarchive.split('/')[-1] + '.' + str(unique_key) + '.o', 'wb')
            output_obj.write(archive.read(chunk_size))
    
            if chunk_size%2 == 1 :
                archive.read(1)
    
            output_obj.close()
    
            unique_key = unique_key + 1
    
        archive.close()
    
        print 'Object files extracted to ' + destfolder + '.'
    

    【讨论】:

    • 太好了,我遇到了同样的问题,这个脚本解决了这个问题。但我相信你应该写 content_descripter[48:58] 而不是 48:57。根据Wikipedia,文件大小字段是 10 个字节而不是 9 个字节。
    • 此外,如果您处理 .a 文件格式的 BSD 变体(例如,在 Mac 上),文件名可以是正文部分的一部分,如 Wikipedia 中所述。所以你还需要一个逻辑来把它去掉。
    • 由于这个问题在 2022 年仍未解决。处理受上述脚本启发的 macOS 变体:github.com/tapthaker/extract-archive
    【解决方案2】:
    1. 您必须从静态库(包含重复对象的库)中提取对象
    2. 然后您必须从提取的对象构建一个新库。
    3. 新库将仅包含重复对象的一个​​实例。
    4. 您必须使用 art 命令生成两个库中的对象列表(原始库 - 有重复的一个,新的 - 没有重复的)。
    5. 然后使用例如 vimdiff 检查两个列表之间的差异。
    6. 写下所有差异。
    7. 然后使用命令 ar x my_original_lib.a object.o 从原始库中仅提取那些对象(步骤 6)对象
    8. 然后将生成的提取对象重命名为您喜欢的任何名称
    9. 然后使用命令 arm my_original_lib.a object.o 重新排列 object.o
    10. 然后使用与步骤 7 相同的命令,您将提取第二个 object.o
    11. 为新提取的对象指定不同的名称
    12. 使用它们来构建新库。
    13. 该方法适用于静态库中任意数量的重复对象。只需重复使用第 9 步和第 7 步即可提取所有重复项

    【讨论】:

    【解决方案3】:

    您可以重命名对象——它们的名称在链接期间没有任何意义。这应该有效:

     mkdir merge-objs &&
     cd merge-objs &&
     ar x ../a.a &&
     for j in *.o; do mv $j a-$j; done &&
     ar x ../b.a &&
     ar r ../merged.a *.o &&
     cd .. && rm -rf merge-objs
    

    【讨论】:

    • 问题不在于它们在档案之间重复,而是对象在同一个库中重复,在同一个档案中!当 'ar' 提取它们时,来自同一存档的具有相同名称的对象将被覆盖。但是感谢您的帮助:)
    【解决方案4】:

    将许多库合并为一个新库而不覆盖可能的重复对象的 C++ 代码如下:http://bazaar.launchpad.net/~paulsepolia/+junk/arbet/files/head:/0025_arbet_FINAL/

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-29
      • 2023-03-21
      • 1970-01-01
      • 1970-01-01
      • 2011-02-28
      相关资源
      最近更新 更多