web-dev-qa-db-ja.com

(.text + 0x20):「main」への未定義の参照および関数への未定義の参照

Makefileをエラーなく動作させるのに問題があります。私が持っている最初の問題は、メインへの未定義の参照に関するものです。 producer.cファイルに関数としてmainがあります。 2番目の問題は、SearchCustomer()への未定義の参照です。

エラー:

bash-4.1$ make
gcc -Wall -c producer.c shared.h
gcc -Wall -c consumer.c shared.h
gcc -Wall -c AddRemove.c shared.h
gcc -pthread -Wall -o producer.o consumer.o AddRemove.o
/usr/lib/gcc/x86_64-redhat-linux/4.4.7/../../../../lib64/crt1.o: In function `_start':
(.text+0x20): undefined reference to `main'
AddRemove.o: In function `AddRemove':
AddRemove.c:(.text+0xb1): undefined reference to `SearchCustomer'
AddRemove.c:(.text+0x1e9): undefined reference to `SearchCustomer'
AddRemove.c:(.text+0x351): undefined reference to `SearchCustomer'
collect2: ld returned 1 exit status
make: *** [producer] Error 1

メイクファイル:

COMPILER = gcc
CCFLAGS = -Wall
all: main

debug:
    make DEBUG=TRUE


main: producer.o consumer.o AddRemove.o
    $(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o
producer.o: producer.c shared.h
    $(COMPILER) $(CCFLAGS) -c producer.c shared.h
consumer.o: consumer.c shared.h
    $(COMPILER) $(CCFLAGS) -c consumer.c shared.h
AddRemove.o: AddRemove.c shared.h
    $(COMPILER) $(CCFLAGS) -c AddRemove.c shared.h


ifeq ($(DEBUG), TRUE)
    CCFLAGS += -g
endif

clean:
    rm -f *.o
13
user2644819

このルール

main: producer.o consumer.o AddRemove.o
   $(COMPILER) -pthread $(CCFLAGS) -o producer.o consumer.o AddRemove.o

間違っている。 producer.oという名前のファイルを作成します(-o producer.o)が、mainという名前のファイルを作成したい。叫びを許してください、しかし常にターゲットを参照するには$ @を使用してください

main: producer.o consumer.o AddRemove.o
   $(COMPILER) -pthread $(CCFLAGS) -o $@ producer.o consumer.o AddRemove.o

Shabazが正しく指摘しているように、gmakeの専門家は$^これは、ルール内のすべての前提条件に展開されます。一般に、文字列または名前を繰り返していることに気付いた場合は、間違っているため、組み込みのいずれかまたは作成した変数を使用する必要があります。

main: producer.o consumer.o AddRemove.o
   $(COMPILER) -pthread $(CCFLAGS) -o $@ $^
15
Jens

このエラーは、リンク中に、コンパイラがmain()関数の定義をどこにも見つけられないことを意味します。

メイクファイルでは、mainルールは次のように展開されます。

main: producer.o consumer.o AddRemove.o
   gcc -pthread -Wall -o producer.o consumer.o AddRemove.o

gccマニュアルページ に従って、-oスイッチの使用は以下のとおりです。

-ofile出力をファイルfileに配置します。これは、実行可能ファイル、オブジェクトファイル、アセンブラファイル、または前処理されたCコードなど、生成される出力の種類に関係なく適用されます。 -oが指定されていない場合、デフォルトでは、実行可能ファイルがa.outに置かれます。

つまり、gccは-oスイッチのすぐ隣に指定されたファイル名に出力を配置します。そのため、ここではすべての.oファイルをリンクしてバイナリ[main、あなたの場合]を作成する代わりに、バイナリをproducer.oとして作成し、他の.oファイルをリンクします。修正してください。

7
Sourav Ghosh