Linker fails when I try to use obj files

(I’m using mac OS X ppc)
I want to use a makefile as I develop some software using root. I find make to be a bit of a hard nut to crack, specifically regarding the difference between object files and normal executables. If I make my little tester program (this is just the standalone example for making a gui, in the root manual) compiling straight from source to executable, everything works just fine. But if I try to use object files (or object file, there’s only one), then the linker can’t find the functions declared in the source file, or more specifically, /usr/bin/ld complains of undefined symbols. The symbols happen to be the constructor, and the only member function the class. It’s like the declarations in the header are never incorporated into the stage when it makes the obj file into an executable.

My makefile:

# For compiling a standalone app, using root libs.

CC = g++

CFLAGS 		= -Wall -O

ROOTCFLAGS    	= $(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS      	= $(shell $(ROOTSYS)/bin/root-config --libs)
ROOTGLIBS     	= $(shell $(ROOTSYS)/bin/root-config --glibs)
CFLAGS 	       += $(ROOTCFLAGS)

#MYLIBPATH 	= /Users/michael/usr/lib
#MYINCLUDEPATH	= /Users/michael/usr/include
SOURCEPATH	= /Users/michael/Documents/RUN/MC/BOLTZ/src/boltzMain
BINPATH		= /Users/michael/Documents/RUN/MC/BOLTZ/bin
OBJPATH		= /Users/michael/Documents/RUN/MC/BOLTZ/obj
SOURCES		= $(addprefix $(SOURCEPATH)/, boltzGUI.cpp) 
HEADERS		= $(addprefix $(SOURCEPATH)/, boltzGUI.h)
OBJECTS		= $(OBJPATH)/boltzGUI.o 




#--------------------------------------------------------------------------
#--------- TRY TO USE OBJ FILE-WHY WON"T IT LINK?--------------------------
#---- it's like it never reads it's header file ---------------------------

boltzGUI: $(OBJECTS)
	$(CC) $(CFLAGS) $(ROOTGLIBS) -I$(SOURCEPATH) -o $(BINPATH)/boltzGUI $(OBJECTS)

$(OBJPATH)/boltzGUI.o: $(SOURCEPATH)/boltzGUIDict.cpp
	$(CC) $(CFLAGS) -I$(SOURCEPATH) -o $@ -c $(SOURCES) $(SOURCEPATH)/boltzGUIDict.cpp

#--------------------------------------------------------------------------
#-------- DON"T USE OBJ FILE: IT LINKS JUST FINE --------------------------

#boltzGUI: $(SOURCES) $(HEADERS) $(SOURCEPATH)/boltzGUIDict.cpp 
#	$(CC) $(CFLAGS) $(ROOTGLIBS) -o $(BINPATH)/boltzGUI\
#	$(SOURCES) $(SOURCEPATH)/boltzGUIDict.cpp

$(SOURCEPATH)/boltzGUIDict.cpp: $(SOURCES) $(HEADERS)
	$(ROOTSYS)/bin/rootcint -f $(SOURCEPATH)/boltzGUIDict.cpp -c\
	$(SOURCEPATH)/boltzGUI.h $(SOURCEPATH)/boltzGUI_LinkDef.h

clean:
	rm $(OBJECTS)

What’s going on here?

Here’s the error that ld gives me:

How do I need to treat this differently from simply compiling straight from source? I tried linking when I build the obj file, but g++ just tells me that the linker input files are unused because linking is not done. The way I understand it anyway, is that the build-time linking is done when you stitch the obj files together (thought there is only one obj file in this case). I’m pretty much at a loss at this point. I’ve wasted a lot of hours chasing this problem around, I just want to get started developing my package. Is there some source of non-vague documentation about object files and make/gcc? This doesn’t really look like a root-specific problem.

Hi,

you can only compile one source into one object file at a time. So you will need one compiler invocation for each .cpp file, instead of trying to compile the two “-c $(SOURCES) $(SOURCEPATH)/boltzGUIDict.cpp” into one object file “-o $@”.

Cheers, Axel.

Ok, I didn’t realize that about one source per object file, but it does make sense.

New make file:

# For compiling a standalone app, using root libs.

CC = g++

CFLAGS 		= -Wall 
#DYFLAGS 	= -dynamiclib 
#LIBTOOLNAME 	= -install_name 

ROOTCFLAGS    	= $(shell $(ROOTSYS)/bin/root-config --cflags)
ROOTLIBS      	= $(shell $(ROOTSYS)/bin/root-config --libs)
ROOTGLIBS     	= $(shell $(ROOTSYS)/bin/root-config --glibs)
CFLAGS 	       += $(ROOTCFLAGS)

#MYLIBPATH 	= /Users/michael/usr/lib
#MYINCLUDEPATH	= /Users/michael/usr/include

SOURCEPATH	= .
BINPATH		= ../../bin
OBJPATH		= ../../obj
SOURCES		= $(addprefix $(SOURCEPATH)/, BOLTZMainFrame.cpp boltzGUI.cpp BOLTZMainFrameDict.cpp) 
HEADERS		= $(addprefix $(SOURCEPATH)/, BOLTZMainFrame.h BOLTZMainFrame_LinkDef.h)
OBJECTS		= $(addprefix $(OBJPATH)/,BOLTZMainFrame.o BOLTZMainFrameDict.o boltzGUI.o)

$(addprefix ../../obj/,%.o) : %.cpp
	$(CC) $(CFLAGS) -c $< -o $@

boltzGUI: $(OBJECTS)
	$(CC) $(CFLAGS) $(ROOTGLIBS) -o $(BINPATH)/boltzGUI $(OBJECTS) 


$(SOURCEPATH)/boltzGUIDict.cpp: $(HEADERS)
	$(ROOTSYS)/bin/rootcint -f $(SOURCEPATH)/BOLTZMainFrameDict.cpp -c\
	$(SOURCEPATH)/BOLTZMainFrame.h $(SOURCEPATH)/BOLTZMainFrame_LinkDef.h

clean:
	rm $(OBJECTS)

Everything works now, thanks for your help,
Michael