gccの共有ライブラリ関数の静的リンク


137

共有ライブラリ関数をgccで静的にリンクするにはどうすればよいですか?


13
静的リンクとはどういう意味ですか?.soを必要とせずに実行可能ファイルを配布しますか?
エミリアーノ

回答:


108

参照する:

http://www.linuxquestions.org/questions/linux-newbie-8/forcing-static-linking-of-shared-libraries-696714/

http://linux.derkeiler.com/Newsgroups/comp.os.linux.development.apps/2004-05/0436.html

リンクするには、ライブラリの静的バージョンが必要です。

共有ライブラリは、実際には、エントリポイントが指定された(そしていくつかのスティッキーアドレッシングの問題が含まれた)特別な形式の実行可能ファイルです。静的にリンクするために必要なすべての情報が含まれているわけではありません。

共有ライブラリを静的にリンクする(または静的ライブラリを動的にリンクする)ことはできません。

このフラグ-staticにより、リンカーは共有(.so)ライブラリではなく静的ライブラリ(.a)を使用するようになります。ただし、静的ライブラリは常にデフォルトでインストールされるわけではないため、自分で静的ライブラリをインストールする必要がある場合があります。

別の考えられるアプローチは、スタティファイアまたはErmineを使用することです。両方のツールは、動的にリンクされた実行可能ファイルを入力として受け取り、出力として、すべての共有ライブラリが埋め込まれた自己完結型の実行可能ファイルを作成します。


11
静的ライブラリにはどのような情報があり、静的にリンクできるため、動的ライブラリにはありませんか?
kbolino 2018年

75

libapplejuiceを静的にリンクしたいが、たとえばliborangejuiceをリンクしたくない場合は、次のようにリンクできます。

gcc object1.o object2.o -Wl,-Bstatic -lapplejuice -Wl,-Bdynamic -lorangejuice -o binary

注意点があります-をliborangejuice使用する場合libapplejuicelibapplejuice動的にリンクされます。

あなたはリンクする必要がありますliborangejuiceと一緒に静的にlibapplejuice取得するためにlibapplejuice静的に。

そして、-Wl,-Bdynamic他のものを維持することを忘れないでください。libcこれは、すべてを静的にリンクすることになります(これは良いことではありません)。


2
静的にリンクするものをgccに直接指示し、彼をバイパスしてリンカーと対話しない方法はありませんか?
Elazar Leibovich、

1
@ElazarLeibovichでは、静的と動的の組み合わせをそのように取得することはできません。
Haozhun 2013年

@EugeneBujak:この警告は私のシステムには当てはまりません。例:gcc -o main main.cc -Wl,-rpath=. -Wl,-Bdynamic -lB -Wl,-Bstatic -lA -Wl,-Bdynamic -L. libBは使用していますLIBAは、それがリンクされ、ldd参照表示されませんLIBAを。実行可能ファイルは正常に動作します。g ++ 4.7.3でテスト済み。
基数

直接(動的)依存関係の間接(ネスト)静的依存関係自体は、動的にリンクされません。
Vinny

以下を考慮してください。binAはlibB.soに依存し、libB.soはlibC.aに依存します。他の人がすでに述べたように、.soはそれ自体が実行可能ファイルであるため、共有オブジェクトがリンクされると、静的ライブラリの依存関係はリンカーと同様に処理されます。実行可能ファイルがリンクされていました:.a静的ライブラリから取得された唯一のシンボルは、.soによって参照された(および未解決の)シンボルです。これは、binAがlibB.soのどこにも参照されていないlibC.aのシンボルを参照している場合、binAがlibB.soにリンクしていても、そのシンボルは未定義になります(リンク時に-Wl、-whole-archiveが使用されている場合を除く) libB.so)。
Vinny

18

共有ライブラリ(.so)の.aファイルがある場合は、次のように、オブジェクトファイルであるかのように、完全なパスを含めて単純に含めることができます。

これはコンパイルするだけでmain.oを生成します:

gcc -c main.c

これにより、そのオブジェクトファイルが対応する静的ライブラリにリンクされ、実行可能ファイル(「main」という名前)が作成されます。

gcc main.o mylibrary.a -o main

または単一のコマンドで:

gcc main.c mylibrary.a -o main

絶対パスまたは相対パスにすることもできます。

gcc main.c /usr/local/mylibs/mylibrary.a -o main

12

ええ、私はこれが8年前の質問であることを知っていますが、共有オブジェクトライブラリに対して静的にリンクすることが可能であると言われました。

共有オブジェクトライブラリを静的にリンクすることはldgccのリンカー)では不可能であることを実際に示すには-それは不可能だと主張する多くの人々とは対照的に-次のgccコマンドを使用します。

gcc -o executablename objectname.o -Wl,-Bstatic -l:libnamespec.so

(もちろん、あなたがコンパイルする必要がありますobjectname.oからsourcename.c、あなたはおそらくだけでなく、あなた自身の共有オブジェクト・ライブラリを構成する必要があります。その場合は、使用し-Wl,--library-path,.ているldはローカルディレクトリに、あなたのライブラリーを見つけることができるようにします。)

あなたが受け取る実際のエラーは:

/usr/bin/ld: attempted static link of dynamic object `libnamespec.so'
collect2: error: ld returned 1 exit status

お役に立てば幸いです。


10

少し遅くなりましたが...数年前に保存したリンクを見つけました。皆さんに役立つと思いました。

CDE:ポータブルLinuxアプリケーションを自動的に作成

http://www.pgbovine.net/cde.html

  • プログラムをダウンロードするだけ
  • 移植可能なバイナリの名前を引数として渡して、バイナリを実行します。例:nmap

    ./cde_2011-08-15_64bit nmap

プログラムは、nmapとその依存パッケージにリンクされているすべてのライブラリを読み取り、それらをすべてcde-package /(同じディレクトリにある)というフォルダに保存します。

  • 最後に、フォルダーを圧縮して、ポータブルバイナリを任意のシステムに展開できます。

ポータブルプログラムを起動するには、cde-package / nmap.cdeにあるバイナリを実行する必要があります。

宜しくお願いします


2
質問に対する答えを正確に提供しているわけではありませんが、問題に対する顕著な解決策です。
razong

0

gccでは、これはサポートされていません。実際、これは私が知っている既存のコンパイラ/リンカーではサポートされていません。


4
静的リンクが既存のコンパイラーでサポートされていない方法を説明できますか?
12

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