web-dev-qa-db-ja.com

ライブラリを含めようとしているが、「未定義の参照」メッセージを取得し続けている

Libtommathライブラリを使用しようとしています。私は、Ubuntu linuxでのプロジェクトにNetBeans IDEを使用しています。ライブラリをダウンロードしてビルドしました。 lib /および.hファイルを/ usr/includeに

適切にファイルを見つけているようです(/ usrディレクトリにインストールする前に行っていたエラーが表示されなくなったため)。

ただし、mp_init(ライブラリ内にあります)を呼び出す単純なメインを作成すると、プロジェクトを作成しようとすると次のエラーが発生します。

mkdir -p build/Debug/GNU-Linux-x86
rm -f build/Debug/GNU-Linux-x86/main.o.d
gcc -c -g -MMD -MP -MF build/Debug/GNU-Linux-x86/main.o.d -o build/Debug/GNU-Linux-x86/main.o main.c
mkdir -p dist/Debug/GNU-Linux-x86
gcc -o dist/Debug/GNU-Linux-x86/cproj1 build/Debug/GNU-Linux-x86/main.o
build/Debug/GNU-Linux-x86/main.o: In function 'main':
/home/[[myusername]]/NetBeansProjects/CProj1/main.c:18: undefined reference to `mp_init'
collect2: ld returned 1 exit status
make[2]: *** [dist/Debug/GNU-Linux-x86/cproj1] Error 1

したがって、リンカはライブラリ内で関数を見つけることができないように見えますが、ISがあるため、これが何を引き起こしているのかわかりません。

Gccコマンドを直接入力してmakefileをスキップすると、同じエラーが発生します。また、静的ライブラリもgccでコンパイルされていることを確認しました。

追加して編集:

コンパイルを直接行い、-lまたは-Lでライブラリを追加すると、これらの同じエラーが発生します。

$ gcc -l /usr/lib/libtommath.a main.c 
/usr/bin/ld: cannot find -l/usr/lib/libtommath.a
collect2: ld returned 1 exit status

$ gcc -llibtommath.a main.c 
/usr/bin/ld: cannot find -llibtommath.a
collect2: ld returned 1 exit status

$ gcc -Llibtommath.a main.c 
/tmp/ccOxzclw.o: In function `main':
main.c:(.text+0x18): undefined reference to `mp_init'
collect2: ld returned 1 exit status

$ gcc -Llibtommath.a main.c 
/tmp/ccOxzclw.o: In function `main':
main.c:(.text+0x18): undefined reference to `mp_init'
collect2: ld returned 1 exit status

私はこのようなものに非常にさびているので、ここで正しいコマンドを使用しているかどうかはわかりません。-Lの例ではライブラリが見つかりますか?ライブラリが見つからない場合、どうやってライブラリを見つけることができますか?/usr/libにあります。現在のディレクトリにある.aファイルなどで試しました。設定する必要がある環境変数はありますか?もしそうなら、どのように、など.

私はまったく別のライブラリ(GMP)を試しましたが、まったく同じ問題がありました。これはある種のUbuntu環境の問題になっていますか?誰もこれを修正する方法を知っていますか?

57
KU1

ここでのコツは、コンパイルするモジュールの後にライブラリを配置することです。問題は参考になります。リンカは参照を順番に解決するため、ライブラリがコンパイルされるモジュールの前にある場合、リンカは混乱し、ライブラリ内の関数が必要であるとは考えません。ライブラリをモジュールの後に置くことにより、モジュール内のライブラリへの参照はリンカによって解決されます。

135
David Wheeler

はい、ソースファイル/オブジェクトファイルの後にライブラリを追加する必要があります。このコマンドは問題を解決します:

gcc -static -L/usr/lib -I/usr/lib main.c -ltommath
40
Amol Dalavi

.cソースファイルが.cppに変換される場合(parsecなど)、externの後に「C」が続く必要があります。

extern "C" void foo();
5
user3342227