imp903 imp903 - 1 month ago 8
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:

-MsSolver
|--src
| |--main.cpp
| |--ScreenMgr.cpp
|--include
| |--ScreenMgr.h
|--build #empty directory
|
|--Makefile
|:
|--bin


and here's the makefile:

CC:=g++
DEBUG:=-g
CFLAGS:=-Wall $(DEBUG)
LDFLAGS:=-Wall $(DEBUG)

SRCDIR:=$(PWD)/src
BUILDDIR:=$(PWD)/build
INCDIR:=$(PWD)/include
BINDIR:=$(PWD)/bin


FILES:=ScreenMgr main
INCLUDES:=-I$(INCDIR)
SRCS:=$(patsubst %,$(SRCDIR)/%.cpp,$(FILES))
OBJS:=$(patsubst %,$(BUILDDIR)/%.o,$(FILES))
LIBS:=-lX11
TARGET:=mssolver

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

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

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

Answer
$(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

instead.

Comments