2016-04-02 7 views
1

ライブラリをコンパイルすると、ライブラリ(Crypto ++)の合計が約50MBになります。静的ライブラリにリンクされたプログラムVSソースコードコンパイルされたプログラムの巨大なサイズの違い

私はCrypto ++のソースコードを取得し、自分のアプリケーションで使用するアルゴリズムのソースファイルのみを追加しました。 私はアプリケーションを作成し、Crypto ++を静的ライブラリとしてコンパイルし、同じプロジェクトのクローン版にリンクすることにしました。

プロジェクト1:

は、だから今、私は2つのプロジェクトを持っている私は、AES、SHA256などを必要とするだけのアルゴリズムをコンパイルして使用するためにのみ必要なソースファイルを持っています。

プロジェクト2:ヘッダーファイルとCrypto ++リンクされた静的ライブラリだけがあります。

私は両方のプロジェクトをコンパイルすると、リンカはProject 2で使用しているソースのみをexeファイルにリンクするので、両方のexeが同じサイズになっていると思っていましたプロジェクト1で使用しているものと全く同じファイルをリンクします。 これはそうではありません。プロジェクト1とプロジェクト2の大きな違いがあります。 静的ライブラリを使用するプロジェクトは、ソースコードでコンパイルされたプロジェクト(どちらもリリースモードでコンパイル)

プロジェクト1(ソース)サイズ:210キロバイト プロジェクト2(静的libに)サイズ:1303キロバイト

これはなぜですか?私はいつもリンカが自分のコードで参照しているものだけを使用することになっていましたが。これは単なるリンカの非効率性ですか?

私を啓発できる人はいますか?

答えて

0

リンカーは、参照したものだけを使用します。あなたが観察している動作は、暗号ライブラリ全体が1つのオブジェクトとして構築されているという直接的な結果です。リンカーは、すべてを含める以外に選択肢はありません。リンカーは、ライブラリのソースコードを持っていて、プロジェクトの横にそれを構築していれば、あなたが期待していることを行うことができます。

0

ライブラリがコンパイルされたとき、私ははい、静的ライブラリは、周りのすべてのシンボルを運ぶ

....ライブラリ(暗号++)、合計でそのほとんど50メガバイトを持っています。必要な場合があるため、何も破棄することはできません。

-gを使用した場合は、デバッグ情報も表示されます。いくつかの最適化フラグもそれに影響します。たとえば、-Osはコードサイズを最小化します。


静的ライブラリを使用するプロジェクトは、ソースコードでコンパイルされたプロジェクトより6.2倍大きいです。どうしてこれなの?

何が起こっているのかをよりよく説明するために、プログラムとコンパイラとリンカースイッチを確認する必要があります。

プロジェクト1(ソース)サイズ:210キロバイトプロジェクト2(静的libに)サイズ:1303キロバイト

これらの数字に基づいて、私はいくつかのデッドコードストリッピングは、あなたが期待するな限り発生していないが、推測しています私はいつもリンカーは唯一、私は私のコードで参照してるものを使うことになっていたものの

。これは単なるリンカの非効率性ですか?

暗号化ライブラリをビルドするときは、make leanレシピを使用してください。関数セクション(-ffunction-sections)とデータセクション(-fdata-sections)を追加することで、リンカは未使用のコードとデータを破棄することができます。 Crypto ++ wikiのGNUmakefile | Makefile Targetsも参照してください。

アプリケーションをリンクするときは、適切なリンカースイッチを使用してください。 GCC/LDでは、-Wl,--gc-sectionsになります。 Apple/DYLDでは、それは-Wl,-dead_stripになります。


デバッグシンボルを削除することもできます。これにより、バイナリサイズがさらに縮小されます。あなたがシンボルで造られたのか、それとも後でそれが剥がれたのかはわかりません。

シンボルをすべて破棄して破棄すると、スタックトレースはほとんど役に立たなくなります。シンボルをオフラインファイルに保存すると、スタックトレースを理解できます。 Crypto ++ wikiのDebug Symbolsも参照してください。


ここではleanターゲットを調査した結果を示します。 Crypto ++ユーザーグループの'make lean' target?も参照してください。

テストプログラム

int main(int, char**) { 

    Integer j("100000000000000000000000000000000"); 
    j %= 1999; 

    cout << "j: " << j << endl; 

    return 0; 
} 

リーンmake leanで構築されたライブラリー、-Wl,--gc-sectionsとリンクプログラム):

$ ls -l integer.exe 
-rwx------ 1 jwalton staff 162012 Jan 4 13:00 integer.exe 

ノーマルmakeで構築されたライブラリー、特別なリンカ・スイッチ):

$ ls -l integer.exe 
-rwx------ 1 jwalton staff 2636952 Jan 4 13:02 integer.exe 

暗号++ 5.6.3がリリースされた後leanターゲットが追加されました。あなたは、あなたがそれをしたい場合は、マスターからコードを取得する必要があります。

git clone https://github.com/weidai11/cryptopp.git cryptopp 

それとも、あなたはCommit 9696b9e5e79ff18aから手でたGNUmakefileに以下のパッチを適用することができます。

+# Dead code stripping. Issue 'make lean'. 
+ifeq ($(findstring lean,$(MAKECMDGOALS)),lean) 
+ifeq ($(findstring -ffunction-sections,$(CXXFLAGS)),) 
+CXXFLAGS += -ffunction-sections 
+endif # CXXFLAGS 
+ifeq ($(findstring -fdata-sections,$(CXXFLAGS)),) 
+CXXFLAGS += -fdata-sections 
+endif # CXXFLAGS 
+ifneq ($(IS_DARWIN),0) 
+ifeq ($(findstring -Wl,-dead_strip,$(LDFLAGS)),) 
+LDFLAGS += -Wl,-dead_strip 
+endif # CXXFLAGS 
+else # BSD, Linux and Unix 
+ifeq ($(findstring -Wl,--gc-sections,$(LDFLAGS)),) 
+LDFLAGS += -Wl,--gc-sections 
+endif # LDFLAGS 
+endif # MAKECMDGOALS 
+endif # Dead code stripping 

とレシピがどこにあるか、以下:

+.PHONY: lean 
+lean: libcryptopp.a cryptest.exe 
+ 
ライン270かそこらの周りにそれを追加します。
関連する問題