Oxinabox Oxinabox - 29 days ago 5
C Question

Linker error: "linker input file unused because linking not done", undefined reference to a function in that file

I'm having trouble with the linking of my files.

Basically, my program consists of:

  • The main program,

  • gen1
    - receives input sends to
    processing, outputs results
    , breaks input into tokens
    using "tokenizer" determines what sort of processing to do to each
    token, and passes them off to
    , or
    . It then returns an
    array of the results.

  • str2num
    - does some processing

  • str2cmd
    - ditto

  • author.py
    - a python script that generates
    from a header

I'm pretty sure I have my includes right, I've checked a couple of times. I've also checked that there are no conditions
wrong in the headers.

Here is my Makefile:

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

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


str2value.o : $(STR2VALUEFILES)
# echo "str2value"

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
rm *.o

.PHONEY: all
make clean

Here is the output I recieve from 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[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

Any suggestions about what this is about?
has all the object files I need, to define the missing functions.


I think you are confused about how the compiler puts things together. When you use -c flag, i.e. no linking is done, the input is C++ code, and the output is object code. The .o files thus don't mix with -c, and compiler warns you about that. Symbols from object file are not moved to other object files like that.

All object files should be on the final linker invocation, which is not the case here, so linker (called via g++ front-end) complains about missing symbols.

Here's a small example (calling g++ explicitly for clarity):

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

all: $(PROG)

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

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

There's also makedepend utility that comes with X11 - helps a lot with source code dependencies. You might also want to look at the -M gcc option for building make rules.