私はによって作成された2静的Linuxのライブラリを、持っているar cr
、libabc.a
とlibxyz.a
。
それらを1つの静的ライブラリにマージしたいと思いますlibaz.a
。
これどうやってするの。
アプリケーションの最終リンクに両方のライブラリを提供するのではなく、マージされた静的ライブラリを作成したいと思います。
私はによって作成された2静的Linuxのライブラリを、持っているar cr
、libabc.a
とlibxyz.a
。
それらを1つの静的ライブラリにマージしたいと思いますlibaz.a
。
これどうやってするの。
アプリケーションの最終リンクに両方のライブラリを提供するのではなく、マージされた静的ライブラリを作成したいと思います。
回答:
両方の.a
ファイルからオブジェクトを.a
抽出し、抽出された.o
sを使用してファイルを作成できます。
ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a *.o
libabc.a
同じ名前のオブジェクトが含まれている可能性があります(異なるディレクトリから発信されたもの)-その場合、再アセンブルは機能しません!
ar -c
私にはうまくいきませんでした(Ubuntu14.04)。私は得たar: no operation specified
。私はar -qc
代わりにやった、そしてそれはうまくいった。
これをネイティブに行うには、少なくとも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
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!
libtool
これらのエラーが発生libtool: link: unable to infer tagged configuration libtool: error: specify a tag with '--tag'
します。これを修正する方法はありますか?
--Wl,-whole-archive
複数のlib * .aの元のリンクコマンドでオプションが必要であり、すべてのlib * .aをに結合する必要がある場合はどうなりますかone.a
。再度リンクすると、で--Wl,-whole-archive
動作しませんone.a
。あなたの提案は何ですか?stackoverflow.com/questions/56323197/...
あなたが単にそれをするならば:
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
このようにして、リンカーがすべてを処理します。
-fPIC
ます。
さらに良いことに、各ライブラリで部分的なリンクを実行すると、結果として得られる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
libtool
ベースのソリューション:libtool -static -o new.a old1.a old2.a