imp903 imp903 - 1 year ago 72
C++ Question

Multiple Function Definition Error Makefile?

So this shouldn't be giving nearly as much trouble as it is, but I'm trying to create a more efficient makefile using wildcard operators as opposed to the tedious method I used to employ where you go through and make each individual object file and then link them together. But, for whatever reason, Whenever I try to run 'make' it gives me this:

multiple definition of 'ScreenMgr::ScreenMgr()'
/path/to/ScrenMgr.cpp:4: first defined here

then it also gives me another error immediately after this one that says:

undefined reference to main
collect2: error: ld returned 1 exit status

Though before these errors, my .o are produced and placed in the proper directory, so the error must be with the linker. I can include the c++ source if somebody thinks it'll help, but the files are practically empty as it is (Though I still put header guards in), because I just wanted to ensure that everything links properly first, so I can deal with problems like this without having to worry about the code as well. The directory structure looks like:

| |--main.cpp
| |--ScreenMgr.cpp
| |--ScreenMgr.h
|--build #empty directory

and here's the makefile:



FILES:=ScreenMgr main
SRCS:=$(patsubst %,$(SRCDIR)/%.cpp,$(FILES))
OBJS:=$(patsubst %,$(BUILDDIR)/%.o,$(FILES))

#create executable and link
$(CC) $(LFLAGS) $(INCLUDES) $(LIBS) $(OBJS) -o $@

#Compile objs
$(BUILDIR)/%.o: $(SRCS)
$(CC) $(CFLAGS) -c $< -o $@

rm -f $(BUILDDIR)/*.o $(BINDIR)/*.o $(INCDIR)/*.swp $(SRCDIR)/*.swp

Answer Source
$(BUILDIR)/%.o: $(SRCS)

This line tells make that it can build any .o file from all of the source files.

    $(CC) $(CFLAGS) -c $< -o $@

And in this line, $< means the first dependency, i.e. the first source file in $(SRCS), i.e. src/ScreenMgr.cpp.

So Make will essentially do this to build the object files:

$(CC) $(CCFLAGS) -c src/ScreenMgr.cpp -o build/ScreenMgr.o
$(CC) $(CCFLAGS) -c src/ScreenMgr.cpp -o build/main.o
$(CC) $(LFLAGS) $(INCLUDES) $(LIBS) build/ScreenMgr.o build/main.o -o bin/mssolver

Based on the names of the .o files you might think it's working correctly... but it's not, it's actually linking two "copies" of ScreenMgr.cpp, and not linking main.cpp!

Change it to:

$(BUILDDIR)/%.o: $(SRCDIR)/%.cpp


Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download