0

gcc でライブラリとリンクがどのように機能するかを理解しようとしています。ファイルtest.cからサンプルの ncurses「Hello World」プログラムをコンパイルしようとしています:

#include <ncurses.h>

int main()
{
    initscr();                      /* Start curses mode              */
    printw("Hello World !!!");      /* Print Hello World              */
    refresh();                      /* Print it on to the real screen */
    getch();                        /* Wait for user input */
    endwin();                       /* End curses mode                */

    return 0;
}

最初に、次のコマンドを使用して (makefile なしで) コンパイルしました。

gcc test.c -o test.exe -lncurses

これにより、9kb のファイルが作成されました。スイッチが何をするのか理解できなかったので、リンクについて、次に静的と動的について少し読んで、ここで-lncurses静的にコンパイルしてみようと決めました。

gcc -static test.c -o test.exe -lncurses

しかし、何らかの理由でそれが機能せず、大量のld「x への未定義参照」エラーが発生しました。例:

/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libncurses.a(lib_echo.o): In function `echo':
(.text+0x3): undefined reference to `SP'

-L/usr/lib別の場所から、オプションを追加しました:

gcc -static test.c -o test.exe -L/usr/lib -lncurses

これにより、1103kb のより大きなファイルが作成されました。
なぜそれを大きくする必要があるのか​​ 理解できます。私が理解していないのは、-staticオプションだけを削除する理由です:

gcc test.c -o test.exe -L/usr/lib -lncurses

...ライブラリに静的にリンクされていないにもかかわらず、サイズが184kbのファイルを生成しますncurses

ここで -L/usr/lib オプションは何をしていますか? オンラインドキュメントによると、ディレクトリを「 -l で検索するディレクトリのリストに追加します」。/usr/lib ディレクトリにはlibncurses.a(とりわけ) ファイルがあり、/usr/include にはncurses.hへのシンボリック リンクcurses.hncurses_dll.h. おそらくlibncurses.aファイル動的ライブラリではありませんか? じゃあ何ncurses.h

4

1 に答える 1

3

これはおそらくあなたがそれを構築したい方法です:

gcc test.c -o test -lncurses

これは、「コンパイルしtest.c、出力ファイルに名前を付け、test呼び出されたライブラリ(または共有オブジェクト)を動的にリンクします(libncurses.soプレフィックスlibは自動的に追加されます)。

.exeサフィックスは Linux では使用されず、Windows のみで使用されることに注意してください (質問には がタグ付けされてlinuxいるため、ここで使用しているプラ​​ットフォームであると想定しています)。

次のように静的にリンクする場合:

gcc -static test.c -o test.exe -lncurses

次に、リンカーはライブラリの静的バージョン (つまり ) を探しますlibncurses.a。ライブラリ関数への参照を解決できないため、リンカー エラーが大量に発生します。これは、ライブラリの静的バージョンがないことを示唆しています。静的にリンクする十分な理由がない限り、通常は動的リンクを使用します。

次のコマンドは、いくつかの追加の (ただし冗長な) ライブラリ パスを指定するだけです。

gcc -static test.c -o test.exe -L/usr/lib -lncurses

/usr/libこれは、ライブラリを探すときに検索するようにリンカに指示するだけです。ただし、/usr/lib既にデフォルトのパスにあるため、通常は違いはありません。実行gcc -dumpspecsすると、ツールに「焼き付けられた」すべてのパスと定義が表示されるため、インクルード ファイル、ライブラリなどのデフォルトの検索パスが表示されます。

/usr/lib ディレクトリには libncurses.a ファイルがあり、/usr/include には curses.h にシンボリック リンクされた ncurses.h と ncurses_dll.h が含まれています。おそらくlibncurses.aファイルは動的ライブラリではありませんか? ncurses.h とは何ですか?

シンボリック リンクは下位互換性のために存在します。ライブラリ ( 「ncurses新しい curses」用) は元の に取って代わりますが、古いコードを引き続きビルドして実行できるようcursesに提供します。curses.hヘッダーには、ncurses_dll.hWindows での cygwin または MSVC でのコンパイルにのみ使用されるいくつかの定義が含まれているため、無視してかまいません。これncurses.hは、ライブラリの実際のプライマリ ヘッダーであり、新しいコードに使用する必要があります。

于 2013-10-28T21:47:11.583 に答える