3

GCC で静的ライブラリを作成しました。ライブラリの構築はOKでした。

私がそれを使用すると、リンカーは一部の関数で未定義の参照エラーをスローします。ただしnm、関数は静的ライブラリ (T でマーク) で定義およびエクスポートされます。ライブラリを必要とするモジュールの後にライブラリを配置する必要があるリンク順序については知っているので、これは問題になりません。

スタティック ライブラリは、3 つの C ファイルから構築されました。Ac Bc と Dc D モジュールは A と B に依存します (それらのヘッダーを含みます)。

A と B の関数を使用する場合は問題ありませんが、DI の関数を使用しようとすると、未定義の参照エラーが発生します。

これらの機能を A または B に移動すると機能します。しかし、それらが D モジュールにある場合はそうではありません。

何が起こっているのか、何が見落とされているのか、完全に考えが尽きてしまいました。

私は Code::Blocks を使用しており、プレーンな C ファイルで作業しています。

4

4 に答える 4

3

何度も機能する古いトリック:リンクフェーズで各静的ライブラリを2回リストします。

つまり、makefile(または使用しているもの)に次のように入力します。

gcc -o <outfile> <liba> <libb> <libc> <liba> <libb> <libc>

とにかく、私はあなたがアイデアを得ることを願っています。

于 2010-07-10T17:09:56.457 に答える
1

プロジェクトに .cpp ファイルを追加したことがわかり、名前を .c に変更しました。プロジェクトを作成するときに、C++ ではなく C 言語を選択しました。これが問題になるとは思わなかった

IDEがgccとg ++のどちらを選択するかは、ファイル拡張子によって決まると思いました。だがしかし。Code::Blocks で、拡張子が .cpp のファイルを追加すると、g++ が使用されます。拡張子が .c のファイルを追加すると、gcc が使用されます。ただし、ファイルの名前を変更すると、同じコンパイラが使用されます。プロジェクト オプションで明示的に変更する必要があります。

その D モジュールは、gcc の代わりに g++ を使用してビルドされました。

「foo.cのコンパイル」だけでなく、ビルド時にコマンドライン全体を表示するようにIDEを設定したときに、これに気付きました。

于 2010-07-12T18:14:14.987 に答える
1

アプリケーション/ライブラリのビルドを簡素化するために作成したマスター make ファイルで使用した解決策は、リンク ステップを 2 回実行することでした。-u リンカー オプションを使用して、2 番目のリンクで未定義のシンボルを指定します。

私のメイクファイルには、次のようなターゲットがあります。

undefined.txt:
    @$(generate-undefined-syms)

このマクロを呼び出す...最初のリンクの試み...

define generate-undefined-syms
    $(PRINTF) "$(this_makefile): Generating undefined symbols ... \n"
    $(CC) -o rubbish $(LDFLAGS) $(objects) $(LDLIBS) 2>&1 | $(GREP) 'undefined reference' > tmp.txt; \
    $(SED) 's/^.*`/-Wl,-u/g' < tmp.txt > undefined.txt; \
    rm -f tmp.txt rubbish
endef

私のsed/regexpスキルは良くないので(そして私は急いでこれを書きました)、次を含むundefined.txtになってしまいます:

-uSomeSym'
-uSomeOtherSym'

つまり、末尾に '

次に、この make 構文を使用して を削除し、重複を削除します

undefined_references = $(filter-out follow, $(sort $(subst ',,$(shell cat undefined.txt))))

'follow' フィルタは、未定義のシンボルが何度も参照された場合、出力に "more references to XXX follow" というメッセージが表示され、undefined.txt ファイルに誤った 'follow' が含まれるためです。

-Wl, uXXXX' follow

最後に、2 回目のリンクを行います (undefined.txt への依存関係に注意してください)。

$(application): $(library_dependencies) $(objects) undefined.txt
    $(CC) -o $@ $(LDFLAGS) $(undefined_references) $(objects) $(LDLIBS)

ちなみに、私は数日で簡単なビルドシステムをゼロから書くことができたので、次の本を完全にお勧めしました.

GNU Make を使用したプロジェクトの管理、第 3 版 By: Robert Mecklenburg

于 2012-05-18T16:16:18.820 に答える
0

おそらくranlib、または適切なarオプションを使用して、.a ファイルにインデックスを提供する必要があります。

于 2010-07-10T11:06:38.037 に答える