9

make を使用してコードをコンパイルしようとしています。通常、私は次のようにコードをコンパイルします。

mipsisa32r2el-timesys-linux-gnu-g++ -o testing -I/usr/include/libxml2 -L/develop/xc4/rootfs/parsecpp/lib -L/develop/xc4/rootfs/parsecpp/sqlite-mips2/lib -I/develop/xc4/rootfs/parsecpp/sqlite-mips2/include db.cpp main.cpp networkinterfacemodule.cpp network.cpp multiplex.cpp program.cpp service.cpp -lsqlite3 -lxml2

この長いコマンドを取り除くために、makefile を作成しようとしました。

CC= mipsisa32r2el-timesys-linux-gnu-g++

export LD_LIBRARY_PATH=:/parsecpp/sqlite-mips2/lib:/parsecpp/lib:/tmp/vixs_temp/DirectFB/single_core/lib


CFLAGS=-I/usr/include/libxml2 -I/develop/xc4/rootfs/parsecpp/sqlite-mips2/include

LDFLAGS=-L/develop/xc4/rootfs/parsecpp/lib -L/develop/xc4/rootfs/parsecpp/sqlite-mips2/lib

LIBS = -lsqlite3 -lxml2

PROG=testing

all: main.o db.o mod.o multiplex.o network.o networkinterfacemodule.o program.o service.o
    $(CC) -o $(PROG) $(CFLAGS) $(LDFLAGS)  main.o db.o mod.o multiplex.o network.o networkinterfacemodule.o program.o service.o $(LIBS) 

main.o: main.cpp 
    $(CC) $(CFLAGS) $(LDFLAGS) main.cpp db.cpp networkinterfacemodule.cpp mod.cpp multiplex.cpp network.cpp program.cpp service.cpp $(LIBS)

db.o: db.cpp 
    $(CC) $(CFLAGS) $(LDFLAGS) db.cpp $(LIBS)


mod.o: mod.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) mod.cpp $(LIBS)

multiplex.o: multiplex.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) multiplex.cpp $(LIBS)

network.o: network.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) network.cpp $(LIBS)

networkmoduleinterface.o: networkinterfacemodule.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) networkinterfacemodule.cpp $(LIBS)

program.o: program.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) program.cpp $(LIBS)

service.o: service.cpp
    $(CC) $(CFLAGS) $(LDFLAGS) service.cpp $(LIBS)

clean:
    rm -rf *o testing

次に、次のエラーが表示されます。

/opt/timesys/linux-gnu/toolchain/bin/../../toolchain/lib/crt1.o: In function `__start':
(.text+0xc): undefined reference to `main'
/opt/timesys/linux-gnu/toolchain/bin/../../toolchain/lib/crt1.o: In function `__start':
(.text+0x10): undefined reference to `main'
collect2: ld returned 1 exit status
make: *** [db.o] Error 1

誰でも私を助けることができますか?

4

3 に答える 3

25

ファイルをコンパイルするだけでリンクしない場合は常に、「-c」フラグを使用してください。

例えば ​​:-

db.o: db.cpp 
$(CC) -c $(CFLAGS) $(LDFLAGS) db.cpp $(LIBS)

また、コンパイル中に「$(LIBS)」をコンパイラに提供する必要はありません。リンク時にのみ提供してください。「-c」フラグを使用するとリンカーが呼び出されないため、リンカーフラグも必要ありません。

だからあなたは書くことができます、

 db.o: db.cpp 
 $(CC) -c $(CFLAGS) db.cpp

更新 (コメントに基づく):-

ファイルをリンクするとき、リンカはただ 1 つのmain関数しか期待しません。上記の場合、メイン関数が定義されていないdb.cppため、コンパイルは成功しますが、関数が見つからないため、リンカーはエラーをスローしますmain

于 2012-06-27T11:30:20.373 に答える
3

-c フラグを指定せずにコンパイルすると、gcc はプログラムをリンクしようとします。メイン関数はほとんどの場合、db.c ではなく main.c にあるため、リンカは db.c でメイン関数を検索すると失敗します。これは、まだリンクされていないが、オブジェクト ファイルに変換された出力が必要であることをコンパイラに伝える必要があることを意味します。これはまさに -c フラグが行うことです。

これは、rajatkhandujaが言ったことになります:

db.o: db.cpp 
$(CC) -c $(CFLAGS) db.cpp
于 2012-06-27T11:38:06.363 に答える
0

リンクのルールを逃したと思います。

リンク方法をmakeに伝える最初のルールが必要です。

testing_OBJECTS = main.o db.o mod.o multiplex.o network.o networkinterfacemodule.o program.o service.o

testing$(EXEEXT): $(testing_OBJECTS)
    ld $(testing_OBJECTS) $(LDFLAGS) $(LIBS)

そして、このルールは次の前提条件でなければなりませんall:

all: testing$(EXEEXT)

さらに、「*.o: *.cpp」ルールはすべて同一であるため、単一のルールを指定しmakeてファイル名を置き換えることができます。さらに詳細が必要かどうか尋ねてください。

于 2012-06-27T11:41:40.420 に答える