链接器错误:"链接器输入文件未使用,因为链接未完成",未定义引用该文件中的函数

Lyn*_*ite 38 c c++ gcc makefile linker-errors

我在链接文件时遇到问题.

基本上,我的计划包括:

  • 主程序,gen1.
  • gen1- 接收输入发送到str2value处理,输出结果str2value,使用"tokenizer"将输入分解为令牌,确定对每个令牌执行何种处理,并将它们传递给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
Run Code Online (Sandbox Code Playgroud)

这是我收到的所有输出:

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
Run Code Online (Sandbox Code Playgroud)

关于这是什么的任何建议?STR2VALUESFILES拥有我需要的所有目标文件,以定义缺少的功能.

Nik*_*sov 51

我认为你对编译器如何将事物放在一起感到困惑.当您使用-cflag时,即没有完成链接,输入是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)
Run Code Online (Sandbox Code Playgroud)

makedependX11附带的实用程序 - 对源代码依赖性有很大帮助.您可能还想查看-M gcc构建make规则的选项.

  • `.cpp.o`规则告诉`make`如何使用`.cpp`后缀从相应的文件中构建一个带有`.o`后缀的文件(比如,如何从`main.cpp`生成`main.o` `$ <`是规则的"输入",`$ @`是"输出"(再次,`$ <`将是`main.cpp`,`$ @`将是`main.o` )这些是'make`的*内置变量*. (2认同)