静态链接库到其他静态库静态链接库到其他静态库(Linking static libraries to

2019-05-09 00:47发布

我有一小块代码,取决于很多静态库(A_1-A_N)。 我想打包代码的静态库,并将其提供给其他人。

我的静态库,让我们把它叫做X,编译罚款。

我创建了一个使用来自X的功能一个简单的示例程序,但是当我尝试将其链接到X,我得到了许多错误有关从库中没有的符号A_1 - A_N。

有没有办法,我可以创造一个新的静态库,Y包含X,并用X所需的所有功能(从A_1选位 - A_N)的方式,这样我就可以只分发Y代表人们将自己的程序链接到?


更新:

我看不过才用AR倾销的一切,使一个大型LIB的是,最终包括了很多不需要的符号(所有.o文件是大约700 MB,不过,静态链接的可执行文件是7 MB)。 有没有一个很好的办法只有实际需要的要包括哪些内容?


这看起来密切相关, 如何几个C / C库合并++成一个? 。

Answer 1:

静态库不与其他静态库链接。 要做到这一点的唯一方法是使用你的图书管理员/归档工具(在Linux例如AR)通过连接多个库创建一个新的静态库。

编辑:针对您的更新,只有这样,我知道只选择所需是从包含它们的.o文件的子集手动创建库的符号。 这是困难,耗时且容易出错。 我不知道有任何工具来帮助做到这一点(不是说他们不存在),但它将使一个非常有趣的项目,产生一个。



Answer 2:

如果您在使用Visual Studio那么是的,你可以做到这一点。

随Visual Studio中的库构建工具允许你加入库一起在命令行上。 我不知道有什么办法做到这一点的可视化编辑器虽然。

lib.exe /OUT:compositelib.lib  lib1.lib lib2.lib


Answer 3:

在Linux或MingW平台,与GNU工具链:

ar -M <<EOM
    CREATE libab.a
    ADDLIB liba.a
    ADDLIB libb.a
    SAVE
    END
EOM
ranlib libab.a

如果你不删除liba.alibb.a ,你可以做一个“瘦档案”:

ar crsT libab.a liba.a libb.a

在Windows上,与MSVC工具链:

lib.exe /OUT:libab.lib liba.lib libb.lib


Answer 4:

静态库只是一个存档.o目标文件。 与提取它们ar (假设的Unix),并收拾他们回到一个很大的图书馆。



Answer 5:

另外,以Link Library Dependencies项目性质还有另一种方式在Visual Studio链接库。

  1. 打开要与其他库进行组合库(X)的项目。
  2. 添加要结合X的其他库(右键单击, Add Existing Item... )。
  3. 进入它们的属性,并确保Item TypeLibrary

这将包括其他图书馆在X,如果你跑了

lib /out:X.lib X.lib other1.lib other2.lib


Answer 6:

请注意,您在阅读前休息:此处显示的shell脚本肯定是不使用安全和行之有效的。 使用您自己的风险!

我写了一个bash脚本来完成这项任务。 假设你的库LIB1和一个你需要包含一些符号是从LIB2。 脚本现在运行在一个循环中,在那里从LIB1它首先检查该未定义的符号可以在LIB2找到。 然后,它从LIB2提取对应的目标文件与ar ,重命名他们一点,并把它们变成lib1内。 现在,可能会有更多的缺少的符号,因为你从LIB2包括东西需要从LIB2,我们还没有包括其他的东西,所以循环需要重新运行。 如果循环的一些传球后没有变化了,即从LIB2没有目标文件添加到LIB1,循环可以停止。

请注意,所包含的符号仍然报告为未定义nm ,所以我跟踪的目标文件,添加到LIB1,自己相信的,为了确定循环是否可以被停止。

#! /bin/bash

lib1="$1"
lib2="$2"

if [ ! -e $lib1.backup ]; then
    echo backing up
    cp $lib1 $lib1.backup
fi

remove_later=""

new_tmp_file() {
    file=$(mktemp)
    remove_later="$remove_later $file"
    eval $1=$file
}
remove_tmp_files() {
    rm $remove_later
}
trap remove_tmp_files EXIT

find_symbols() {
    nm $1 $2 | cut -c20- | sort | uniq 
}

new_tmp_file lib2symbols
new_tmp_file currsymbols

nm $lib2 -s --defined-only > $lib2symbols

prefix="xyz_import_"
pass=0
while true; do
    ((pass++))
    echo "Starting pass #$pass"
    curr=$lib1
    find_symbols $curr "--undefined-only" > $currsymbols
    changed=0
    for sym in $(cat $currsymbols); do
        for obj in $(egrep "^$sym in .*\.o" $lib2symbols | cut -d" " -f3); do
            echo "  Found $sym in $obj."
            if [ -e "$prefix$obj" ]; then continue; fi
            echo "    -> Adding $obj to $lib1"
            ar x $lib2 $obj
            mv $obj "$prefix$obj"
            ar -r -s $lib1 "$prefix$obj"
            remove_later="$remove_later $prefix$obj"
            ((changed=changed+1))
        done
    done
    echo "Found $changed changes in pass #$pass"

    if [[ $changed == 0 ]]; then break; fi
done

我命名的脚本libcomp ,所以你可以把它再例如用

./libcomp libmylib.a libwhatever.a

其中libwhatever是要包括符号。 但是,我认为这是最安全的一切先复制到一个单独的目录。 我不相信我的剧本这么多(但是,它为我工作,我可以包括libgsl.a到我NUMERICS库与和省去了-lgsl编译器开关)。



文章来源: Linking static libraries to other static libraries
标签: c++ linker ar .a