1. ホーム
  2. c++

[解決済み】リンカーエラーです。"リンカ入力ファイルはリンクが行われていないため未使用"、そのファイル内の関数への未定義参照

2022-01-24 16:49:05

質問

ファイルのリンクに問題があるのですが。

基本的に、私のプログラムは以下のような構成になっています。

  • メインプログラムです。 gen1 .
  • gen1 - 入力を受け取り、次のように送信します。 str2value のために 処理し、結果を出力する str2value 入力はトークンに分割されます。 トークナイザーを使って、各トークナイザーにどのような処理を行うかを決定します。 に渡す。 str2num または str2cmd . そして の配列になります。
  • str2num - 何らかの処理を行う
  • str2cmd - 同上
  • author.py - を生成する python スクリプトです。 str2cmd.cstr2cmd.h ヘッダーから cmdTable.h .

インクルードが正しいかどうか、何度か確認しました。また、次のような条件がないことも確認しました。 #ifndef がヘッダーで間違っている。

以下は私のMakefileです。

#CPP = g++ -lserial
CPP = g++ -DTESTMODE
C= gcc
DEFINES = LURC
CFLAGS = -Wall -fshort-enums -D$(DEFINES)
PROJECTFILES = gen1.cpp str2value.o

STR2VALUEFILES = str2value.cpp str2cmd.o str2num.o tokenizer.o str2value.h

gen1 : $(PROJECTFILES)
        $(CPP) $(CFLAGS) -o gen1 $(PROJECTFILES)



str2value.o : $(STR2VALUEFILES)
#       echo "str2value"
        $(CPP) $(CFLAGS) -c $(STR2VALUEFILES)

str2num.o: str2num.cpp  str2value.h str2num.hpp
         $(C) $(CFLAGS) -c $^


tokenizer.o: tokenizer.cpp tokenizer.hpp
        $(CPP) $(CFLAGS) -c $^

str2cmd.o : authorCMDs.py cmdTable.h
        python authorCMDs.py cmdTable.h str2cmd #this uses the gcc -E cmdTable.h -DLURC
        $(C) $(CFLAGS) -c str2cmd.c str2cmd.h

#TODO: add a thing that checks str2cmd.h/.c has not been modified by hand



.PHONEY: clean
clean:
        rm *.o

.PHONEY: all
all:
        clear
        make clean
        make

以下は、make allの出力です。

make clean
make[1]: Entering directory `/home/frames/LURC/gen1/gen1Source'
rm *.o
make[1]: Leaving directory `/home/frames/LURC/gen1/gen1Source'
make
make[1]: Entering directory `/home/frames/LURC/gen1/gen1Source'
python authorCMDs.py cmdTable.h str2cmd #this uses the gcc -E cmdTable.h -DLURC
str2cmd.c and str2cmd.h, generated from cmdTable.h

gcc  -Wall -fshort-enums -DLURC -c str2cmd.c str2cmd.h
gcc  -Wall -fshort-enums -DLURC -c str2num.cpp str2value.h str2num.hpp
g++ -DTESTMODE -Wall -fshort-enums -DLURC -c tokenizer.cpp tokenizer.hpp
g++ -DTESTMODE -Wall -fshort-enums -DLURC -c str2value.cpp str2cmd.o str2num.o tokenizer.o str2value.h
g++: str2cmd.o: linker input file unused because linking not done
g++: str2num.o: linker input file unused because linking not done
g++: tokenizer.o: linker input file unused because linking not done
g++ -DTESTMODE -Wall -fshort-enums -DLURC -o gen1 gen1.cpp str2value.o
str2value.o: In function `getValue(char*)':
str2value.cpp:(.text+0xbd): undefined reference to `str2cmd(char*)'
str2value.cpp:(.text+0x102): undefined reference to `str2num(char*)'
str2value.o: In function `getAllValues(char*)':
str2value.cpp:(.text+0x164): undefined reference to `tokenizer::tokenizer(char*)'
str2value.cpp:(.text+0x177): undefined reference to `tokenizer::getNumTokens(char const*)'
str2value.cpp:(.text+0x1a9): undefined reference to `tokenizer::getNextToken(char const*)'
str2value.cpp:(.text+0x1e9): undefined reference to `tokenizer::getNumTokens(char const*)'
str2value.cpp:(.text+0x201): undefined reference to `tokenizer::~tokenizer()'
str2value.cpp:(.text+0x25b): undefined reference to `tokenizer::~tokenizer()'
collect2: ld returned 1 exit status
make[1]: *** [gen1] Error 1
make[1]: Leaving directory `/home/frames/LURC/gen1/gen1Source'
make: *** [all] Error 2

これが何であるかについて、何かご意見はありますか? STR2VALUESFILES には、不足している関数を定義するために必要なオブジェクトファイルがすべてあります。

どのように解決するのですか?

コンパイラがどのように物事をまとめるかについて、あなたは混乱しているのだと思います。あなたが -c フラグ、すなわちリンクが行われない場合、入力はC++コード、出力はオブジェクトコードとなります。このとき .o とは混ざらない。 -c とコンパイラが警告を出します。オブジェクトファイルからのシンボルは ではなく のように他のオブジェクトファイルに移動させることができます。

すべてのオブジェクト・ファイルは最終的なリンカー呼び出しにあるべきですが、ここではそうではないので、リンカー (経由して呼び出されます。 g++ フロントエンド)は、シンボルの欠落について文句を言います。

以下は、小さな例です (呼び出し g++ を明示することで、わかりやすくしています。)

PROG ?= myprog
OBJS = worker.o main.o

all: $(PROG)

.cpp.o:
        g++ -Wall -pedantic -ggdb -O2 -c -o $@ $<

$(PROG): $(OBJS)
        g++ -Wall -pedantic -ggdb -O2 -o $@ $(OBJS)

また makedepend ユーティリティは、ソースコードの依存関係を解決するのにとても役に立ちます。また -M gcc を構築するためのオプションです。 make のルールで定義されています。