2016-12-03 3 views
2

私は実際に別の関数b(libb.aに保管されています)からa(liba.aに保管されている)関数を呼び出しようとしていますが、リンケージエラーがあります。2つの静的ライブラリにプログラムをリンクすると、それぞれが別の関数に依存する関数を含んでいますか?

私のファイルがあります。

a.c

#include <stdio.h> 
void a() 
{ 
    printf("a\n"); 
} 

b.c

void a(); 
void b() 
{ 
    a(); 
} 

main.cの

void b(); 
int main(int argc, char const* argv[]) 
{ 
    b(); 
    return (0); 
} 

そして、どのように私は

をコンパイル
gcc -c a.c 
gcc -c b.c 
ar rc liba.a a.o 
ar rc libb.a b.o 
ranlib liba.a 
ranlib libb.a 
gcc main.c liba.a libb.a 

(正確なメッセージ・エラー)

b.c:(.text+0xa): undefined reference to `a' 

は、私が何をしようとしている実行する方法はありますか? お返事ありがとうございます

EDIT: コマンドラインのライブラリの順序が重要になるようです。 しかし、私の実際の問題ではlibAはlibBに依存しており、libBはlibA(MCVEコードでは説明していません)に依存しています。

+3

注文を交換すると何か変わりますか? 'gcc main.c libb.a liba.a' – melpomene

+3

コマンドラインでのライブラリの順序は重要です。ライブラリBがライブラリAに依存する場合、BはコマンドラインでAの前に来なければなりません。 –

+0

http://c-faq.com/lib/libsearch.html – melpomene

答えて

1

EDITをきれいにします:それは、コマンドラインの問題でそのライブラリの順序を表示されます。しかし、私の実際の問題では、libAはlibBに依存し、libBはlibAに依存しています(MCVEコードでは示されません)。

あなたの本当の問題は、あなた自身をコーナーに描いたことですか?適切なことは、一方が完全に他のライブラリと独立しているように、2つのライブラリを並べて、リンクコマンドでそれを入れていくことです。

その変更を加えることなく、あなたが二回最初のライブラリを言及して逃げるかもしれませんが、

gcc main.c liba.a libb.a liba.a 

それが名前解決に来るとき、リンカはかなりシンプル志向です。未解決の名前のリストから始まり、ライブラリのリストを通って名前が見つかると解決します。それはあなたがliba.aを二度与えたことに気付かないでしょう。 bによって提供されたaの名前と、aによって指定されたbの名前が解決されます。

しかし、そのトリックはあなたにいつか噛み付く可能性があります(それがまったく動作する場合)。私が言ったように、あなたの依存関係を整理して、自分自身やあなたに従う人のために、簡単にすることです。

-1

すでにa.cb.cmain.cを持っている同じディレクトリに、次のMakefile作成:基本的には、あなたの質問にした場合C.

  • で複数のファイルの展開の一例である

    #!/usr/bin/make 
    
    ar: 
         gcc -o a.o -c a.c 
         gcc -o b.o -c b.c 
         gcc -o m.o -c main.c 
         ar rc liba.a a.o 
         ar rc libb.a b.o 
         ar rc libm.a m.o 
         ranlib liba.a 
         ranlib libb.a 
         ranlib libm.a 
         gcc -o main m.o a.o b.o 
    
    install: 
         gcc -o a.o -c a.c 
         gcc -o b.o -c b.c 
         gcc -o m.o -c main.c 
         gcc -o main m.o a.o b.o 
    
    clean: 
         rm -f *.o 
         rm -f *.a 
         rm -f main 
    

    make installコマンドを発行すると、Makefileは標準のgccコンパイルプロセスを使用してプログラムをコンパイルします。

  • make arを発行すると、コンパイルはarになります。
  • あなたがmake cleanを発行する場合、Makefileはあなたの前のビルド
+1

メインと一緒にa.oとb.oオブジェクトをリンクする場合、最初にライブラリを作成する点は何でしょうか? 'gccの-c a.c'で – FredK

+0

は、GCCのオブジェクトスイッチを使用せずに、gccが自動的にa.oオブジェクトを作成します。私の答えの場合は、 'gcc -o a.o -c a.c'を使ってオブジェクト名をgccに渡します。基本的に、これらのコマンドは両方とも同じ出力を生成します。 – hmofrad

関連する問題