Fortran makefile circular dependency dropped - makefile

So I am trying to run a Fortran code from someone else with the Intel Fortran compiler on a mac. But when I try to run the corresponding makefile, I get the error messages "make[1]: Circular release.makefile out <- release.makefile dependency dropped." and so on.
I have little knowledge of Fortran, so I would appreciate any help. I already tested to run some simple helloworld.f90 files and makefiles, to rule out that it is a compiler problem, and those work. However, the code I am trying to run is downloaded from a reputable scientific journal, so I assume the code (makefiles and Fortran files) should be correct too, leaving me at loss. This is my first stackoverflow post, so if I forgot something please let me know.
The makefile is:
release:
# ENV = /opt/intel/oneapi/setvars.sh intel64
make -f release.makefile
debug:
# ENV = /opt/intel/oneapi/setvars.sh intel64
make -f debug.makefile
dsymutil $(OUT).out
hpcrelease:
make -f hpcrelease.makefile
pbs:
make -f pbs.makefile
compilesubmit:
make -f hpcrelease.makefile
make -f pbs.makefile
qsub $(OUT).pbs
.PHONY: clean
clean:
rm -f *.o *.mod *.MOD *genmod* *~
rm -fr *.dSYM
and the file release.makefile writes:
FC = ifort
FCFLAGS = -m64 -traceback -O3 -qopenmp -implicitnone -Wl,-stack_size,0x100000000 -L/Users/josie/Desktop/Uni/Economics/Moll/SuiteSparse-master/lib -lumfpack -lamd -lcholmod -lcolamd -lsuitesparseconfig -lblas
LDFLAFS = -m64 -traceback -O3 -qopenmp -implicitnone -Wl,-stack_size,0x100000000 -L/Users/josie/Desktop/Uni/Economics/Moll/SuiteSparse-master/lib -lumfpack -lamd -lcholmod -lcolamd -lsuitesparseconfig -lblas
# -O3
PROG = $(OUT)
MOD = Parameters.o Globals.o umfpack.o Procedures.o
SUBR = AllocateArrays.o SetParameters.o Grids.o IterateBellman.o HJBUpdate.o cumnor.o rtsec.o StationaryDistribution.o SaveSteadyStateOutput.o DistributionStatistics.o rtbis.o rtflsp.o InitialSteadyState.o FinalSteadyState.o SolveSteadyStateEqum.o Calibration.o MomentConditions.o dfovec.o newuoa-h.o newuob-h.o update.o trsapp-h.o biglag.o bigden.o mnbrak.o golden.o sort2.o CumulativeConsumption.o FnDiscountRate.o OptimalConsumption.o FnHoursBC.o ImpulseResponses.o IRFSequence.o Transition.o SaveIRFOutput.o IterateTransitionStickyRb.o IterateTransOneAssetStickyRb.o FnCapitalEquity.o CumulativeConsTransition.o DiscountedMPC.o DiscountedMPCTransition.o
OBJ = $(MOD) $(SUBR)
$(PROG).out: $(OBJ) Main.o
$(FC) $(FCFLAGS) -o $# $^ $(LDFLAGS)
Main.o: $(MOD)
%: %.o
$(FC) $(FCFLAGS) -o $# $^ $(LDFLAGS)
%.o: %.f90
$(FC) $(FCFLAGS) -c $<
the error I get is
Fortran % make -f makefile
# ENV = /opt/intel/oneapi/setvars.sh intel64
make -f release.makefile
make[1]: Circular release.makefile.out <- release.makefile dependency dropped.
make[1]: Circular Main.f90.out <- Main.f90 dependency dropped.
make[1]: Circular Parameters.f90.out <- Parameters.f90 dependency dropped.
make[1]: Circular Globals.f90.out <- Globals.f90 dependency dropped.
make[1]: Circular umfpack.f90.out <- umfpack.f90 dependency dropped.
make[1]: Circular Procedures.f90.out <- Procedures.f90 dependency dropped.
make[1]: `Main.o' is up to date.
Since the error already occurs with the release.makefile, I refer from giving the other files since I believe the error is the same for all scripts? Correct me if I am wrong and those are necessary.

Related

Can't use LAPACK in makefile

I have program (in fortran) where I'm using three custom modules, which make use of LAPACK. Until now I've compiled my program using the following shell script:
filestring="main"
gfortran -c mod_exp.f90 mod_genmat.f90 mod_print.f90 $filestring.f90
gfortran mod_exp.o mod_genmat.o mod_print.o $filestring.o -llapack -lblas
rm mod_exp.o mod_genmat.o mod_print.o $filestring.o exponentiate.mod genmat.mod printing.mod printing_subrtns.mod
mv a.out $filestring
Since I've been using more and more modules and different programs using them, I've decided to start using makefiles. Following a tutorial, I managed to write the following:
FC = gfortran
FFLAGS = -Wall -Wextra -llapack -lblas #-fopenmp
SOURCES = mod_print.f90 mod_genmat.f90 mod_exp.f90 main.f90
OBJ = ${SOURCES:.f90=.o} #substitute .f90 with .o
%.o : %.f90 #creation of all *.o files DEPENDS on *.f90
$(FC) $(FFLAGS) -c -O $< -o $#
main: $(OBJ)
$(FC) $(FFLAGS) -o $# $(OBJ)
clean:
#rm -f *.o *.mod main
However, when executing make, it says that the LAPACK functions are not recognized. One such mistake is the following:
/usr/bin/ld: mod_exp.o: in function `__exponentiate_MOD_diagun':
mod_exp.f90:(.text+0x37f): undefined reference to `zgees_'
...
collect2: error: ld returned 1 exit status
One possible mistake I've seen is that I need to specify the location of the libraries. However, it would seem strange since I didn't need to do it before; also, I don't know how to find it.
Please show the link command that make invoked, that caused the error to be generated.
I'm confident that if you cut and paste that exact command line to your shell prompt, you will get the same error you see when make runs it. So the problem is not make, but your link command.
The problem is that you have put the libraries before the objects in the link line. Libraries should come at the end, after the objects, else when the linker examines the libraries it doesn't know what symbols will need to be included (because no objects have been parsed yet to see what symbols are missing).
This is why LDLIBS is traditionally a separate variable:
FC = gfortran
FFLAGS = -Wall -Wextra #-fopenmp
LDLIBS = -llapack -lblas
SOURCES = mod_print.f90 mod_genmat.f90 mod_exp.f90 main.f90
OBJ = ${SOURCES:.f90=.o} #substitute .f90 with .o
%.o : %.f90 #creation of all *.o files DEPENDS on *.f90
$(FC) $(FFLAGS) -c -O $< -o $#
main: $(OBJ)
$(FC) $(FFLAGS) -o $# $(OBJ) $(LDLIBS)

Fortran Makefile - Circular dependency dropped and m2c

The following is a working make; it is a simplified version of a more complex one, but it manages to reproduce the problems when I try some changes. Files "myobj.f" and "mymod.f" are in folders "src1" and "src2" respectively and are almost empty (mymod is a module that has a variable declared and myobj is a subroutine that initializes and prints that variable).
I tried googling for this, but all circular dependency errors I found seemed more clear than this. Could you please help me identify what is wrong with my makefile?
all : mylib.so
makefiles := Makefile
FC = gfortran
FFLAGS = -I$(obj_path) -J$(obj_path) -fPIC
LFLAGS = -shared -fPIC
obj_path := obj
src_paths = src1 src2
vpath %.o $(obj_path)
vpath %.mod $(obj_path)
vpath %.f $(src_paths)
objects = myobj.o mymod.o
obj/myobj.o : obj/mymod.mod
mylib.so : $(objects:%.o=$(obj_path)/%.o)
$(FC) $(LFLAGS) $^ $(LIBS) -o $#
$(obj_path)/%.mod : %.o
#touch $#
$(obj_path)/%.o : %.f $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $#
$(obj_path) :
mkdir -p $#
.PHONY: clean
clean:
rm -rf mylib.so $(obj_path)
(1) I can't simplify the rules
Having the "$(obj_path)" explicitly in the rules for compiling objects seems unnecessary: I know vpath does not work with files that change during compile time and was designed only for sources, but I don't see why clarifying the path when I list the objects as dependencies of the library shouldn't suffice.
mylib.so : $(objects:%.o=$(obj_path)/%.o)
$(FC) $(LFLAGS) $^ $(LIBS) -o $#
%.mod : %.o
#touch $#
%.o : %.f $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $#
But this doesn't work; I get a circular dependency dropped warning and make tries to compile the modules using m2c. Just in case, commenting the vpaths for .o and .mod does not fix this. Output of make --debug:
Reading makefiles...
Updating goal targets....
File 'all' does not exist.
File 'mylib.so' does not exist.
File 'obj/myobj.o' does not exist.
make: Circular obj/myobj.mod <- obj/myobj.o dependency dropped.
File 'obj/mymod.mod' does not exist.
File 'obj/mymod.o' does not exist.
make: Circular obj/mymod.o <- obj/mymod.mod dependency dropped.
Must remake target 'obj/mymod.o'.
m2c -o obj/mymod.o
make: m2c: Command not found
<builtin>: recipe for target 'obj/mymod.o' failed
make: *** [obj/mymod.o] Error 127
(2) I can't add a rule for f90
Now I want to be able to incorporate f90 code to my library. Adding the rule seems not to affect the process if nothing else changes, but when I change the extension of mymod.f to mymod.f90, it returns a similar error that the other case. The modified section is:
$(obj_path)/%.mod : %.o
#touch $#
$(obj_path)/%.o : %.f $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $#
$(obj_path)/%.o : %.f90 $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $#
And the output of make --debug is this:
Reading makefiles...
Updating goal targets....
File 'all' does not exist.
File 'mylib.so' does not exist.
File 'obj/myobj.o' does not exist.
File 'obj' does not exist.
Must remake target 'obj'.
mkdir -p obj
Successfully remade target file 'obj'.
File 'obj/mymod.mod' does not exist.
File 'obj/mymod.o' does not exist.
make: Circular obj/mymod.o <- obj/mymod.mod dependency dropped.
Must remake target 'obj/mymod.o'.
m2c -o obj/mymod.o
make: m2c: Command not found
<builtin>: recipe for target 'obj/mymod.o' failed
make: *** [obj/mymod.o] Error 127
COMPILATION CONFIG 1:
Makefile:
all : mylib.so
makefiles := Makefile
FC = gfortran
FFLAGS = -I$(obj_path) -J$(obj_path) -fPIC
LFLAGS = -shared -fPIC
obj_path := obj
src_paths = src1 src2
#vpath %.o $(obj_path)
#vpath %.mod $(obj_path)
vpath %.f $(src_paths)
objects = myobj.o mymod.o
obj/myobj.o : obj/mymod.mod
mylib.so : $(objects:%.o=$(obj_path)/%.o)
$(FC) $(LFLAGS) $^ $(LIBS) -o $#
%.mod : %.o
#touch $#
%.o : %.f $(makefiles) | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $#
$(obj_path) :
mkdir -p $#
.PHONY: clean
clean:
rm -rf mylib.so $(obj_path)
src1/myobj.f:
subroutine myobj
use mymod
implicit none
mymodx=1
print*,'mymod was included', mymodx
return
end subroutine
src2/mymod.f:
module mymod
implicit none
integer :: mymodx
end module
Terminal output:
make --debug
GNU Make 4.1
Built for x86_64-unknown-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Updating goal targets....
File 'all' does not exist.
File 'mylib.so' does not exist.
File 'obj/myobj.o' does not exist.
make: Circular obj/myobj.mod <- obj/myobj.o dependency dropped.
File 'obj/mymod.mod' does not exist.
File 'obj/mymod.o' does not exist.
make: Circular obj/mymod.o <- obj/mymod.mod dependency dropped.
Must remake target 'obj/mymod.o'.
m2c -o obj/mymod.o
make: m2c: Command not found
<builtin>: recipe for target 'obj/mymod.o' failed
make: *** [obj/mymod.o] Error 127
There are a few issues with your approach. The vpath searching only applies to pre-requisites and not targets, so a rule like
%.o: %.f
will search the $(src_paths) for the source but it will not attempt to match targets in $(obj_path). This leads to the next issue, that due to putting objects into an intermediate directory, your rule needs to account for this since vpath won't help. Your main target to build the library depends on things like $(obj_path)/blah.f so you want to use a rule like:
$(obj_path)/%.o: %.f
to match the objects. There may be a cleaner way to do this, but I am not aware of them.
Likewise, the rule with the %.mod target was not matching the requirement in the object directory and it looks like a default implicit rule was being called to handle them, attempting to invoke m2c.
Specifically, make tries to compile the mod file as modula-2 source and its automatic rule to do this conflicted with your %.o:%.mod rule and produced the circular dependency.
By modifying that rule to properly match the mod files, this mess is avoided.
Also, dont forget to add a vpath for %.f90, so your rules can find those source files.
I can successfully build your test project with this slightly modified Makefile. I also used files named .f90 to show that it also solves your second issue.
FC = gfortran
FFLAGS = -I$(obj_path) -J$(obj_path) -fPIC
LFLAGS = -shared -fPIC
src_paths = src1 src2
obj_path := obj
vpath %.o $(obj_path)
vpath %.mod $(obj_path)
vpath %.f90 $(src_paths)
vpath %.f $(src_paths)
mylib_objects = myobj.o mymod.o
mylib_target = mylib.so
all: $(mylib_target)
$(mylib_target) : $(mylib_objects:%.o=$(obj_path)/%.o)
$(FC) $(LFLAGS) $^ $(LIBS) -o $#
$(obj_path)/myobj.o: myobj.f90 $(obj_path)/mymod.mod
$(obj_path) :
mkdir -p $#
$(obj_path)/%.mod : %.o $(obj_path)
#true
$(obj_path)/%.o: %.f | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $#
$(obj_path)/%.o: %.f90 | $(obj_path)
$(FC) $(FFLAGS) -c $< -o $#
clean:
rm -rf $(mylib_target) $(obj_path)
From a clean start, the output of make --debug is:
% make --debug
GNU Make 4.1
Built for x86_64-pc-linux-gnu
Copyright (C) 1988-2014 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Updating goal targets....
File 'all' does not exist.
File 'mylib.so' does not exist.
File 'obj/myobj.o' does not exist.
File 'obj' does not exist.
Must remake target 'obj'.
mkdir -p obj
Successfully remade target file 'obj'.
File 'obj/mymod.mod' does not exist.
File 'obj/mymod.o' does not exist.
Must remake target 'obj/mymod.o'.
gfortran -Iobj -Jobj -fPIC -c src2/mymod.f90 -o obj/mymod.o
Successfully remade target file 'obj/mymod.o'.
Must remake target 'obj/mymod.mod'.
Successfully remade target file 'obj/mymod.mod'.
Must remake target 'obj/myobj.o'.
gfortran -Iobj -Jobj -fPIC -c src1/myobj.f90 -o obj/myobj.o
Successfully remade target file 'obj/myobj.o'.
Must remake target 'mylib.so'.
gfortran -shared -fPIC obj/myobj.o obj/mymod.o -o mylib.so
Successfully remade target file 'mylib.so'.
Must remake target 'all'.
Successfully remade target file 'all'.
Also note that you can instead handle your module dependency by stipulating the object files in an other that guarantees necessary mod files will have been generated. For example, changing
objects = myobj.o mymod.o
to
objects = mymod.o myobj.o
makes the rules and pre-requisites involving the mod files un-necessary, as this will cause mymod.o (and the byproduct mymod.mod) to be built before myobj.o is attempted. It is possible that this solution would break in a parallel build, so I have maintained your object ordering and made sure the rules worked as intended.

Creating a FORTRAN makefile

I have a FORTRAN source code consisting of many different .F and .h files. I need to build an executable from it, but I'm having some problems. The makefile that I produced so far (which may have errors as I'm new to this) is:
# compiler
FC = /usr/bin/gfortran-4.5
# compile flags
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons
# link flags
FLFLAGS = -g -fbacktrace
# source files and objects
SRCS = $(patsubst %.F, %.o, $(wildcard *.F)) \
$(patsubst %.h, %.mod, $(wildcard *.h))
# program name
PROGRAM = blah
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FCFLAGS) $# $<
%.o: %.F
$(FC) $(FLFLAGS) -o $# $<
%.mod: %.h
$(FC) $(FLFLAGS) -o $# $<
clean:
rm -f *.o *.mod
When I try to make the program, however, I'm getting a slew of undefined reference errors. I mean, every function and subroutine call in the very first compiled .F file gives back an undefined reference error. I thought this was because gfortran was trying to link the files instead of just compiling them and then linking at the end, but I thought the '-c' option was supposed to prevent that.
UPDATE:
As commenters have pointed out, I mixed up the compile and link flags. Furthermore, you shouldn't compile *.h files. Here is the latest, corrected makefile:
# compiler
FC = /usr/bin/gfortran-4.4
# compile flags
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check -std=legacy
# link flags
FLFLAGS =
# source files and objects
SRCS = $(patsubst %.F, %.o, $(wildcard *.F))
# program name
PROGRAM = blah
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FLFLAGS) -o $# $<
%.o: %.F
$(FC) $(FCFLAGS) -o $# $<
clean:
rm -f *.o *.mod
Now when I run make, it will compile each *.F file in the code, but it fails at the linking stage. I get a bunch of undefined reference errors in the very first *.F file. The compiler seems to be going over each *.F file individually in the linking stage, which I'm not sure is correct. Then I get an error:
/usr/lib/gcc/x86_64-linux-gnu/4.4.5/libgfortranbegin.a(fmain.o): In function `main':
(.text+0x26): undefined reference to `MAIN__'
collect2: ld returned 1 exit status
However, if I type the command:
gfortran -o blah *.o
The executable will be built, so it seems like I did something wrong in the makefile for the linking stage.
UPDATE: 5/9/2011
Sverre pointed out the final problem with my makefile. In my first target that builds the program, I use the shortcut command for only the first dependency ($<), but I need to include all dependencies (i.e. all *.o files) using the ($^) shortcut. The final, working makefile is as follows:
# compiler
FC := /usr/bin/gfortran-4.5
# compile flags
FCFLAGS = -g -c -fdefault-real-8 -fbacktrace -fno-align-commons -fbounds-check
# link flags
FLFLAGS =
# source files and objects
SRCS = $(patsubst %.F, %.o, $(wildcard *.F))
# $(patsubst %.h, %.mod, $(wildcard *.h))
# program name
PROGRAM = vipre
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FLFLAGS) -o $# $^
%.o: %.F
$(FC) $(FCFLAGS) -o $# $<
# %.mod: %.h
# $(FC) $(FCFLAGS) -o $# $<
clean:
rm -f *.o *.mod
Are you using GNU make? If so,
$(FC) $(FLFLAGS) -o $# $<
may be the culprit. $< is the name of the first prerequisite, but you want all the *.o files. Try using $^ instead.

Makefile problems with gcc flags (file not recognized; shared libraries)

I'm a little confused now. I'm trying to get the Makefile work but it breaks. I Hope someone can help me with this bad and frustrating time-killer.
I've written a small and lightweight part of a Compiler.
The project has the following structure:
/Compiler.cpp
/Makefile
/Buffer/
/Buffer/Makefile
/Scanner/
/Scanner/Makefile
/SymTable/
/SymTable/Makefile
When I'm compiling Buffer, Scanner and SymTable manual (changing the directory and typing 'make mode=release' it's no problem and each shared-library is compiled). But when I run the Makefile from within where the 'Master Makefile' /Makefile is, it fails and the terminal prints something like:
Buffer/libBuffer.so: file not recognized: File format not recognized
collect2: ld returned 1 exit status
make: \*** [Compiler] Error 1
Here is the listing of the Makefile of /Buffer/Makefile (the same for Scanner and SymTable):
CXX = g++
ifeq ($(mode),release)
CXXFLAGS = -g -fPIC -O3 -ffunction-sections -march=native
else
mode = debug
CXXFLAGS = -g3
endif
MODUL = Buffer
COMPONENTS = Buffer.h
MK_LIBRARY = lib$(MODUL).so
all: $(MK_LIBRARY)
$(MK_LIBRARY): $(COMPONENTS)
$(CXX) $(CXXFLAGS) -shared -o $# $^
clean:
rm -f $(MK_LIBRARY)
.PHONY: all
.PHONY: clean
The 'Master Makefile' looks like:
CXX = g++
ifeq ($(mode),release)
CXXFLAGS = -g -O3 -ffunction-sections -fwhole-program -march=native
else
mode = debug
CXXFLAGS = -g3
endif
TARGET = Compiler
COMPONENTS = $(TARGET)
DIRS = Buffer Scanner SymTable
MAKE = make
MFLAGS = mode=$(mode)
all: $(COMPONENTS)
$(TARGET): Compiler.cpp libBuffer.so libScanner.so libSymTable.so
$(CXX) $(CXXFLAGS) -IBuffer -IScanner -ISymTable \
-LBuffer -LScanner -LSymTable \
-lBuffer -lScanner -lSymTable -o $# Compiler.cpp
libBuffer.so: force_look
cd Buffer; $(MAKE) $(MFLAGS)
libScanner.so: force_look
cd Scanner; $(MAKE) $(MFLAGS)
libSymTable.so: force_look
cd SymTable; $(MAKE) $(MFLAGS)
clean:
rm -f $(COMPONENTS)
#for d in $(DIRS); do (cd $$d; $(MAKE) clean ); done
check:
#for d in $(DIRS); do (cd $$d; $(MAKE) check ); done
force_look:
true
.PHONY: all
.PHONY: clean
.PHONY: check
I hope some has an answer for me! Thanks!
There's something very weird about this part:
MODUL = Buffer
COMPONENTS = Buffer.h
MK_LIBRARY = lib$(MODUL).so
$(MK_LIBRARY): $(COMPONENTS)
$(CXX) $(CXXFLAGS) -shared -o $# $^
This rule tries to build libBuffer.so out of Buffer.h, the header file. How can this possibly work, without the definitions of the things in Buffer.cc? I would do it this way:
lib%.so: %.o
$(CXX) $(CXXFLAGS) -shared -o $# $^
EDIT:
You have the definitions of Buffer in Buffer.h? All right, you have more than one problem, and the only way to solve them is to do what almost always works: retreat to a simpler problem and solve that first. Can you make Buffer.o? And can you then link that into your executable (bypassing libBuffer.so)? And if not, can you write a "HelloWorld" in Buffer/, and link Buffer.o into that?

Why is make complaining about circular dependencies?

I have built a make file for my project, and it works (everything compiles) but it gives these irritating error messages:
make: Circular zpr.c <- zpr.o dependency dropped.
gcc -Wall -c -o zpr.o zpr.c
make: Circular readjpeg.c <- readjpeg.o dependency dropped.
gcc -Wall -c -o readjpeg.o readjpeg.c
make: Circular readppm.c <- readppm.o dependency dropped.
gcc -Wall -c -o readppm.o readppm.c
make: Circular SceneNode.cpp <- SceneNode.o dependency dropped.
g++ -c -o SceneNode.o SceneNode.cpp
make: Circular BoundingBoxNode.cpp <- BoundingBoxNode.o dependency dropped.
g++ -c -o BoundingBoxNode.o BoundingBoxNode.cpp
make: Circular GeometryNode.cpp <- GeometryNode.o dependency dropped.
g++ -c -o GeometryNode.o GeometryNode.cpp
make: Circular SceneGraph.cpp <- SceneGraph.o dependency dropped.
g++ -c -o SceneGraph.o SceneGraph.cpp
make: Circular testgraph.cpp <- testgraph.o dependency dropped.
g++ -c -o testgraph.o testgraph.cpp
My makefile is not complicated at all so hopefully someone can spot the error.
GXX=g++
CC=gcc
CFLAGS=-Wall
LIBS=-lGL -lglut -ljpeg
OBJS=helpers.o loadobj.o zpr.o readjpeg.o readppm.o SceneNode.o BoundingBoxNode.o GeometryNode.o SceneGraph.o testgraph.o
OBJS2=testgraph.o SceneGraph.o GeometryNode.o BoundingBox.o SceneNode.o readppm.o readjpeg.o zpr.o loadobj.o helpers.o
SRCS=testgraph.cpp SceneGraph.cpp SceneNode.cpp
.o.cpp:
$(GXX) $(CFLAGS) -c $<
.o.c:
$(CC) $(CFLAGS) -c $<
testgraph: $(OBJS)
$(GXX) $(LIBS) $(OBJS) -o testgraph
clean:
rm *.o
Your implicit rules are the culprit. They have the extensions listed in the reverse order of how they are understood by make.
.o.c:
tells make that .c files are created from .o files. Since there is already a rule that says that .o files are created from .c files, you have a circular dependencies and therefore the errors.
The solution is (or should be, assuming a reasonably configured make) simple.
You don't (usually) need to specify your own rules for compilation in really common cases, such as C++ sources. It would be simpler to just specify something like:
CFLAGS=-Wall
LOADLIBES=-lGL -lglut -ljpeg
OBJS=helpers.o loadobj.o zpr.o readjpeg.o readppm.o SceneNode.o \
BoundingBoxNode.o GeometryNode.o SceneGraph.o testgraph.o
all: testgraph
testgraph: $(OBJS)
This is likely to also help you avoid two errors.
The rules you wrote say that .o files are created from .c files, which is backwards. But the correct rules already exist in nearly all versions of make.
You have listed the libraries ahead of the object files. This works by accident on some platforms that use ELF format objects. But it is still wrong. List libraries after objects because libraries are only loaded to satisfy undefined externals.

Resources