2つの「ar」静的ライブラリを1つにマージする方法は?


90

私はによって作成された2静的Linuxのライブラリを、持っているar crlibabc.alibxyz.a
それらを1つの静的ライブラリにマージしたいと思いますlibaz.a
これどうやってするの。

アプリケーションの最終リンクに両方のライブラリを提供するのではなく、マージされた静的ライブラリを作成したいと思います。


7
参照:libtoolベースのソリューションlibtool -static -o new.a old1.a old2.a
osgx 2014年

2
それは完璧に機能しますが、それらのライブラリに共通のfile.oがあるかどうかは少し疑問です(ただし、機能的には異なります)。それでも機能しますか?
bindingofisaac 2015

libtool -static -o new.a old1.a old2.aはLinux(centos 7)
では機能しません

回答:


60

両方の.aファイルからオブジェクトを.a抽出し、抽出された.osを使用してファイルを作成できます。

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o

63
危険、ウィル・ロビンソン!これは、作品だけlibabc.a内のメンバーとlibxyz.aの名前が重複していない場合。そうしないと、1つを上書きして、失われます。
デビッドギブン2013年

6
さらに、libabc.a同じ名前のオブジェクトが含まれている可能性があります(異なるディレクトリから発信されたもの)-その場合、再アセンブルは機能しません!
Igor R.

16
ar -c私にはうまくいきませんでした(Ubuntu14.04)。私は得たar: no operation specified。私はar -qc代わりにやった、そしてそれはうまくいった。
最大

ar t lib.aを使用すると、実際にファイルを抽出しなくても、ライブラリ内のファイルを表示できます。
raj_gt1 2015年

automakeでそれを行うにはどうすればよいですか?
shuva 2016年

120

これをネイティブに行うには、少なくとも3つの方法があります。最初で最も移植性の高い方法は、libtoolを使用することです。他のライブラリもlibtoolでビルドした後、.laライブラリをautomake libaz_la_LIBADD変数に追加するか、Makefileから次のように直接追加するだけでそれらを組み合わせることができます。

libtool --mode=link cc -static -o libaz.la libabc.la libxyz.la

他の2つは、GNUarを使用するときに少なくとも利用できます。次のようなMRIスクリプト(たとえばlibaz.mriという名前)を使用できます。

create libaz.a
addlib libabc.a
addlib libxyz.a
save
end

次に、arを次のように実行します。

ar -M <libaz.mri

または、シンアーカイブ(オプション-T)を使用することもできます。これにより、他のアーカイブをネストせずに追加できますが、静的ライブラリを配布する場合、デタッチされたオブジェクトが失われるという欠点があります。

ar -rcT libaz.a libabc.a libxyz.a

上記のすべてのメソッドは、元のアーカイブから重複するメンバー名を適切に処理します。

それ以外の場合は、重複するメンバー名が置き換えられないように、別のディレクトリに解凍してから再度パックする必要があります。

mkdir abc; cd abc; ar -x ../libabc.a
mkdir xyz; cd xyz; ar -x ../libxyz.a
ar -qc libaz.a abc xyz

19
通常のアーカイブ(シンではない)が必要な場合、実行できる簡単なことの1つは、シンアーカイブを作成し、それを通常のアーカイブに変換することです。次のようなもの:ar cqT libaz.a libabc.a libxyz.a && echo -e 'create libaz.a\naddlib libaz.a\nsave\nend' | ar -M。これにより、一時的なシンが作成libaz.aされ、シンアーカイブが通常のアーカイブに変換されます(移動/配布できるようになります)。これは、ライブラリ名に特殊文字(スペース、プラス、またはコンマ)が含まれている場合にも適切に処理されます(つまりar cqT libbundle.a libfoo++.a 'libbar baz.a')。しかし、私から+1!
Cornstalks 2014年

与えられた最初のMRIスクリプトの例の欠点は何ですか?
jb 2014年

いい答えだ!抽出して再達成する必要のないいくつかのオプションを見るのは良いことです。また、@ Cornstalksのアイデアは良いと思います。多分答えに追加する必要がありますか?
lightbulb1 2015

コマンドを使おうとすると、libtoolこれらのエラーが発生libtool: link: unable to infer tagged configuration libtool: error: specify a tag with '--tag' します。これを修正する方法はありますか?
ラースニールセン

@ Guillem @ Cornstalksすばらしい答えです。--Wl,-whole-archive複数のlib * .aの元のリンクコマンドでオプションが必要であり、すべてのlib * .aをに結合する必要がある場合はどうなりますかone.a。再度リンクすると、で--Wl,-whole-archive動作しませんone.a。あなたの提案は何ですか?stackoverflow.com/questions/56323197/...
thinkdeep

10

あなたが単にそれをするならば:

ar x a.a
ar x b.a
ar c c.a  *.o 

aaとbaの両方に同じ名前のメンバーがある場合、いくつかのオブジェクトファイルが失われるため、異なるアーカイブのメンバーを異なるフォルダーに抽出する必要があります。

ar x a.a && mv *.o a_objs
ar x b.a && mv *.o b_objs
ar c c.a a_objs/*.o b_objs/*.o

あなたが実行した場合、さらにより多くの、それは同じ名前の複数のメンバーが1つのアーカイブ(AAで言う)であることがかのうで、ARのx AAを、あなただけの同じ名前のメンバーのための1つを取得します。

1つのアーカイブで同じ名前のすべてのメンバーを抽出する唯一の方法は、オプション「N」でメンバー番号を指定することです。

ar xN 1 a.a  xxx.c.o && mv xxx.c.o xxx.c.1.o
ar xN 2 b.a  xxx.c.o && mv xxx.c.o xxx.c.2.o
...

これは面倒な作業になるため、その作業を行うには、より洗練されたスクリプトを作成する必要があります。

オプションのソリューションの1つは、複数のアーカイブを1つの共有ライブラリに結合できることです。

g++ -shared -o c.so -Wl,--whole-archive a.a b.a 

このようにして、リンカーがすべてを処理します。


1
サミュエル、ありがとう。ただし、共有ライブラリに結合する場合は、すべてのオブジェクトをでコンパイルする必要があり-fPICます。
osgx 2014年

0

さらに良いことに、各ライブラリで部分的なリンクを実行すると、結果として得られる2つのオブジェクトファイルのアーカイブが作成されます。そうすれば、共有ライブラリのように動作します

あなたは部分的なリンクをします

gcc -r --nostdlib

したがって、中間アーカイブを作成する代わりに、または再抽出した後、実行します。

gcc -r --nostdlib $CFLAGS $OBJECTS_A -o $LIBNAME_A.o
gcc -r --nostdlib $CFLAGS $OBJECTS_B -o $LIBNAME_B.o

その後

ar -cr $LIBNAME_JOINED.a $LIBNAME_A.o $LIBNAME_B.o

彼が図書館を求めたので、それは実際に尋ねられた質問に答えていません。多くの場合、ライブラリのソースが提供されていないか、他の理由でライブラリを事前に構築したままにしておきたいと考えています。
pholat

0
ar -x libx264.a
mkdir sub && cd sub
ar -m ../libx264.a `ar -t ../libx264.a |sort|uniq|grep "\.o"`
ar -x ../libx264.a

これで、「macroblock-10.o」の2つのバージョンができました。


0
ar crsT libaz.a libabc.a libxyz.a

ここでは、アーカイブのアーカイブを作成してから、Tフラグを使用して結果を「フラット化」(間引き)します。中に含まれている可能性のある同じ名前の.oファイルでどのように機能するかわからない。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.