Solving Makefile Confusion for Fortran Code

  • Thread starter Matterwave
  • Start date
  • Tags
    Confusion
In summary, the conversation is about trying to modify and run a complex code written in Fortran. The speaker wants to add a new module to the code but is having trouble modifying the makefile to run the code with the new module. They ask for recommendations on a tutorial for creating makefiles and discuss the use of modules in the code.
  • #1
Matterwave
Science Advisor
Gold Member
3,971
328
Hello guys, I am trying to run a pretty substantial piece of code, coded in Fortran. There are many many modules (~10) and the dependencies of one module/piece of code on another is quite complex. As I am not the original author of the code, I am still not intimately familiar with every single part of this code. However, I do understand what the code is supposed to do, and how it basically works in general. What I want to do is to modify a portion of the code and tag on another module in order to allow the code to do some extra stuff that I need it to do. I have made the modifications to the code, and have written my new module.

Now I am onto the part where I want to actually run the modified code. And here I run into a problem. In order to run the code originally, all I had to do was type in on my command line in a terminal was "make bulb-new" and then "auto.run", and the code will start running in that terminal. But since I have written a new module, and I need to use a different linear-algebra pack for finding eigen-values and eigen-vectors, I need to modify what the terminal is doing so that it will run the modified code. I think that in order to do this I have to modify the "makefile" file so that the terminal makes all the object files correctly. Sadly, I have never before had to modify a "makefile" so I don't understand very much what is going on.

Here is the makefile:

Code:
MACH =  gfortran
include makefile.$(MACH)

.DUMMY   : init
 
.DEFAULT   : bulb-new

zheev3   :
   cd zheevh3-F-1.0; $(MAKE) all F77='$(F77)' F77COMP='$(F77COMP)' FFLAGS='$(FFLAGS)' FOPT='$(FOPT)'

init   :
     make zheev3

bulb-new   :  params.o parallel.o helectron.o keep_clocks.o bulb-new.o  rannyu.o spline.o splint.o
   $(F90PAR) $(LDFLGS) $(FOPT) -o bulb-new bulb-new.o params.o helectron.o  keep_clocks.o parallel.o rannyu.o spline.o splint.o zheevh3-F-1.0/*.o $(FLIBS)
bulb-new3   :  params.o parallel.o keep_clocks.o bulb-new3.o  rannyu.o
   $(F90PAR) $(LDFLGS) $(FOPT) -o bulb-new3 bulb-new3.o params.o helectron.o  keep_clocks.o parallel.o rannyu.o $(FLIBS)
keep_clocks.o  : keep_clocks.F90 params.o
   $(F90) $(FFLAGS) $(FOPT) -c keep_clocks.F90
params_numeric.o  : params_numeric.F90
   $(F90) $(FFLAGS) $(FOPT) -c params_numeric.F90
params.o  : params.F90
   $(F90) $(FFLAGS) $(FOPT) -c params.F90
helectron.o  : helectron.F90
   $(F90) $(FFLAGS) $(FOPT) -c helectron.F90
parallel.o  : params.o parallel.F90
   $(F90) $(FFLAGS) $(FOPT) -c parallel.F90
cdfsave.o  : params_numeric.o  cdfsave.F90
   $(F90) $(FFLAGS) $(FOPT) $(INCNETCDF) -c cdfsave.F90
bulb-new.o  : params.o parallel.o keep_clocks.o bulb-new.F90
   $(F90) $(FFLAGS) $(FOPT) -c bulb-new.F90
bulb-new3.o  : params.o parallel.o keep_clocks.o bulb-new3.F90
   $(F90) $(FFLAGS) $(FOPT) -c bulb-new3.F90
rannyu.o  : rannyu.f
   $(F77) $(F77FLGS) $(FOPT) -c rannyu.f
spline.o   : spline.f
   $(F77) $(F77FLGS) $(FOPT) -c spline.f
splint.o   : splint.f
   $(F77) $(F77FLGS) $(FOPT) -c splint.f
plotit   : plotit.F90
   $(F90) $(FFLAGS) $(FOPT) -o plotit plotit.F90 $(LIBGRACE)
plotdens   :  params_numeric.o plotdens.F90
   $(F90) $(FFLAGS) $(FOPT) -o plotdens plotdens.F90 params_numeric.o  $(LIBGRACE) $(LIBCDF)
#  needed cdfsave.o in above two lines also for cdf data file
printhvv   : params.o printhvv.F90
   $(F90) $(FFLAGS) $(FOPT) -o printhvv printhvv.F90 params.o
printhe   : params.o printhe.F90
   $(F90) $(FFLAGS) $(FOPT) -o printhe printhe.F90 params.o
tar   :
   tar -cvf laptop.tar cdfsave.F90 keep_clocks.F90 params.F90 bulb-new.F90 rannyu.f plotit.F90 printhvv.F90 printhe.F90 parallel.F90 params_numeric.F90 plotdens.F90 params_numeric.F90 cdfsave.F90 helectron.F90 splint.f spline.f Makefile makefile* bulb*in* *run* zheevh3-F-1.0
clean   :
   \rm *.o bulb-new

Anyone know of a good tutorial on make-files and how to write them, and the syntax in them, etc?

It's hard for me to parse what is happening in this document. Essentially what I need to do is incorporate the new linear algebra pack zheev since I am running a different linear-algebra pack for parts of the code (but zheev3 will still be used in parts of the code as well), and then create and include my new module "spincohere.f90", which is only used by the main program "bulb.new" and not any other modules. That should be a pretty quick fix to this makefile right?
 
Last edited:
Technology news on Phys.org
  • #2
I have added the line:

Code:
spincohere.o :   spincohere.F90 params.o parallel.o helectron.o keepclocks.o
   $(F90) $(FFLAGS) $(FOPT) -c spincohere.F90

After the bulb-new3 line.

However, this made me realize something. The main program is bulb-new. In this main file bulb-new.f90 there are 2 modules and several subroutines. I need to use these 2 modules "angles" and "parallel" in my new module "spincohere", but nowhere in this makefile are these two modules mentioned...am I to assume that these modules would not be accessible to my "spincohere" module then? If I need them to be accessible, can I compile them as separate object files even though their code is written in bulb-new.f90?
 
  • #3
MAKEFILES ! AAAEEEIIIII *sign of the cross* --- makefiles are evil. I didn't even know people still USED makefiles. I haven't used on it probably 20 years

circle and bar.jpg


Sorry, I know this wasn't helpful but I couldn't resist.
 
  • #4
It is not clear what you did. Naming code files is one thing. The names of functions are more important. The order in which you link the object files determines whether a given object is "picked up" and it's symbols used as entry points. In plain English - use distinct function names everywhere.
What error do you get?
 
  • #5
@phinds: And. makefiles are not evil. You just program so high above the machine code that it does not matter. Fortran and C applications are normally built that way. As you well know.
 
  • #6
Yes, Matterwave, if you are going to use modules in more than place, I would take them out of the main file and place them in their own file; I put one module per file.

You can find tutorials on line on how to put together make files; they are very convenient, powerful, intelligent...but it is best if you understand what you are doing and put together your own file.

One thing you need to keep in mind is that those indented lines that you see actually start with a tab character and not a series of blank spaces...just make sure you do that...many of us have configured our editors to automatically emulate tabs by replacing them with blank spaces...but when typing make files, one needs to let the tab be at the beginning of those command lines.
 
  • #7
A fairly standard reference for makefiles is the O'Rilley book "Managing Projects with GNU Make" by Robert Mecklenburg (or the earlier book "Managing Projects with Make"). But a lot of information is available by Googling.

A quick thing to try:
If you put the new module in a separate file, mimic how a file like spline.f is treated. Also insert your new .o file where spline.o appears. Everywhere you see those, add something similar for your new code file. Use the correct Fortran version for your additions. Is that something you were attempting with bulb-new3 or was that already there?

P.S. Be very careful to mimic (or not change) any whitespace at the beginning and end of lines (tabs, spaces). Make can be sensitive to that.
 
Last edited:
  • #8
phinds said:
I didn't even know people still USED makefiles. I haven't used on it probably 20 years
There are a great many tools in the Unix/Linux world that are just a GUI front-end to a makefile generator. Makefiles are still the main way to build programs there. And Windows still has nmake.
 
  • #9
jim mcnamara said:
@phinds: And. makefiles are not evil. You just program so high above the machine code that it does not matter. Fortran and C applications are normally built that way. As you well know.

Yeah, you're right on all counts. I DO know, but I HATE the damned things and always did. GUI's are SO much easier and I love easy :D
 
  • #10
phinds said:
GUI's are SO much easier and I love easy :D
My specialty is automating long, tedious (or complicated) processes with scripts. In that world, the GUIs are evil whereas being able to modify and run makefiles with scripts is great.
 
  • #11
FactChecker said:
A fairly standard reference for makefiles is the O'Rilley book "Managing Projects with GNU Make" by Robert Mecklenburg (or the earlier book "Managing Projects with Make"). But a lot of information is available by Googling.

A quick thing to try:
If you put the new module in a separate file, mimic how a file like spline.f is treated. Also insert your new .o file where spline.o appears. Everywhere you see those, add something similar for your new code file. Use the correct Fortran version for your additions. Is that something you were attempting with bulb-new3 or was that already there?

P.S. Be very careful to mimic (or not change) any whitespace at the beginning and end of lines (tabs, spaces). Make can be sensitive to that.

The code as I wrote in the OP is the original code, I did not modify it what so ever. I have emulated the other parts of the makefile code by inserting the off-set text:

Code:
MACH =  gfortran
include makefile.$(MACH)

.DUMMY   : init

.DEFAULT   : bulb-new

zheev3   :
   cd zheevh3-F-1.0; $(MAKE) all F77='$(F77)' F77COMP='$(F77COMP)' FFLAGS='$(FFLAGS)' FOPT='$(FOPT)'

init   :
     make zheev3

bulb-new   :  params.o parallel.o helectron.o keep_clocks.o bulb-new.o  rannyu.o spline.o splint.o
   $(F90PAR) $(LDFLGS) $(FOPT) -o bulb-new bulb-new.o params.o helectron.o  keep_clocks.o parallel.o rannyu.o spline.o splint.o zheevh3-F-1.0/*.o $(FLIBS)
bulb-new3   :  params.o parallel.o keep_clocks.o bulb-new3.o  rannyu.o
   $(F90PAR) $(LDFLGS) $(FOPT) -o bulb-new3 bulb-new3.o params.o helectron.o  keep_clocks.o parallel.o rannyu.o $(FLIBS)spincohere.o :   spincohere.F90 params.o parallel.o helectron.o keepclocks.o
   $(F90) $(FFLAGS) $(FOPT) -c spincohere.F90keep_clocks.o  : keep_clocks.F90 params.o
   $(F90) $(FFLAGS) $(FOPT) -c keep_clocks.F90
params_numeric.o  : params_numeric.F90
   $(F90) $(FFLAGS) $(FOPT) -c params_numeric.F90
params.o  : params.F90
   $(F90) $(FFLAGS) $(FOPT) -c params.F90
helectron.o  : helectron.F90
   $(F90) $(FFLAGS) $(FOPT) -c helectron.F90
parallel.o  : params.o parallel.F90
   $(F90) $(FFLAGS) $(FOPT) -c parallel.F90
cdfsave.o  : params_numeric.o  cdfsave.F90
   $(F90) $(FFLAGS) $(FOPT) $(INCNETCDF) -c cdfsave.F90
bulb-new.o  : params.o parallel.o keep_clocks.o bulb-new.F90
   $(F90) $(FFLAGS) $(FOPT) -c bulb-new.F90
bulb-new3.o  : params.o parallel.o keep_clocks.o bulb-new3.F90
   $(F90) $(FFLAGS) $(FOPT) -c bulb-new3.F90
rannyu.o  : rannyu.f
   $(F77) $(F77FLGS) $(FOPT) -c rannyu.f
spline.o   : spline.f
   $(F77) $(F77FLGS) $(FOPT) -c spline.f
splint.o   : splint.f
   $(F77) $(F77FLGS) $(FOPT) -c splint.f
plotit   : plotit.F90
   $(F90) $(FFLAGS) $(FOPT) -o plotit plotit.F90 $(LIBGRACE)
plotdens   :  params_numeric.o plotdens.F90
   $(F90) $(FFLAGS) $(FOPT) -o plotdens plotdens.F90 params_numeric.o  $(LIBGRACE) $(LIBCDF)
#  needed cdfsave.o in above two lines also for cdf data file
printhvv   : params.o printhvv.F90
   $(F90) $(FFLAGS) $(FOPT) -o printhvv printhvv.F90 params.o
printhe   : params.o printhe.F90
   $(F90) $(FFLAGS) $(FOPT) -o printhe printhe.F90 params.o
tar   :
   tar -cvf laptop.tar cdfsave.F90 keep_clocks.F90 params.F90 bulb-new.F90 rannyu.f plotit.F90 printhvv.F90 printhe.F90 parallel.F90 params_numeric.F90 plotdens.F90 params_numeric.F90 cdfsave.F90 helectron.F90 splint.f spline.f Makefile makefile* bulb*in* *run* zheevh3-F-1.0
clean   :
   \rm *.o bulb-new

I don't know if this will work, and since I don't yet know how to incorporate the other modules and the linear algebra pack, I have not attempted to actually run the code...

I have looked up some makefile tutorials online, but I am still really confused by this. For example, this makefile has a bulb-new.o compile command, but the prerequisites is clearly missing the module helectron.o ... looking at the code, there is definitely a "use helectron" command.

So...I don't get why sometimes prerequisites are there and sometimes not?

Also does the ordering matter in how the objects are created? The tutorial I read said the order doesn't matter as long as the executable is the first one.
 
Last edited:
  • #12
Matterwave said:
I don't know if this will work, and since I don't yet know how to incorporate the other modules and the linear algebra pack, I have not attempted to actually run the code...
You will need to add instructions to compile zheev and link to it when compiling bulb-new.

Matterwave said:
I have looked up some makefile tutorials online, but I am still really confused by this. For example, this makefile has a bulb-new.o compile command, but the prerequisites is clearly missing the module helectron.o ... looking at the code, there is definitely a "use helectron" command.
Since bulb-new.o is being compiled as an object, it is only when the bulb-new executable is being compiled that the compiler/linker must access helectron.o. In the current state of the Makefile, a problem would appear if the module conatined in helectron.F90 was modified in such a way that an already existing bulb-new.o would be incompatible with the module definition inside helectron.F90, as bulb-new.o would not be recompiled. What you wrote for spincohere.o will ensure that any modifications to params.F90, parallel.F90, helectron.F90, or keepclocks.F90 will force a recompilation of spincohere.o.

Matterwave said:
So...I don't get why sometimes prerequisites are there and sometimes not?
Bad programming? :p

Matterwave said:
Also does the ordering matter in how the objects are created? The tutorial I read said the order doesn't matter as long as the executable is the first one.
Can you give a link for that? I always thought that the order was not important, that make would find the rules whatever the order they are in in the makefile.
 
  • #13
DrClaude said:
Can you give a link for that? I always thought that the order was not important, that make would find the rules whatever the order they are in in the makefile.

Yes, in here: http://kiwi.atmos.colostate.edu/fortran/docs/fortran90-mar30.pdf page 7, it says that the first target should be the one that is built, and all subsequent target's orders do not matter.

I have modified the makefile in the following manner:

Code:
MACH =  gfortran
include makefile.$(MACH)

.DUMMY   : init
   
.DEFAULT   : bulb-new

zheev3   :
   cd zheevh3-F-1.0; $(MAKE) all F77='$(F77)' F77COMP='$(F77COMP)' FFLAGS='$(FFLAGS)' FOPT='$(FOPT)'

init   :
     make zheev3

bulb-new   :  params.o parallel.o helectron.o keep_clocks.o spincohere.o bulb-new.o rannyu.o spline.o splint.o
   $(F90PAR) $(LDFLGS) $(FOPT) -o bulb-new bulb-new.o params.o helectron.o spincohere.o keep_clocks.o parallel.o rannyu.o spline.o splint.o zheevh3-F-1.0/*.o $(FLIBS)
bulb-new3   :  params.o parallel.o keep_clocks.o bulb-new3.o  rannyu.o
   $(F90PAR) $(LDFLGS) $(FOPT) -o bulb-new3 bulb-new3.o params.o helectron.o  keep_clocks.o parallel.o rannyu.o $(FLIBS)
keep_clocks.o  : keep_clocks.F90 params.o
   $(F90) $(FFLAGS) $(FOPT) -c keep_clocks.F90
params_numeric.o  : params_numeric.F90
   $(F90) $(FFLAGS) $(FOPT) -c params_numeric.F90
params.o  : params.F90
   $(F90) $(FFLAGS) $(FOPT) -c params.F90
helectron.o  : helectron.F90
   $(F90) $(FFLAGS) $(FOPT) -c helectron.F90angles.o  :   angles.F90 params.o helectron.o
   $(F90) $(FFLAGS) $(FOPT) -c angles.F90
neutrinodist.o : neutrinodist.F90 params.o helectron.o
   $(F90) $(FFLAGS) $(FOPT) -c neutrinodist.F90parallel.o  : parallel.F90 params.o
   $(F90) $(FFLAGS) $(FOPT) -c parallel.F90
cdfsave.o  :  cdfsave.F90 params_numeric.o  
   $(F90) $(FFLAGS) $(FOPT) $(INCNETCDF) -c cdfsave.F90spincohere.o :   spincohere.F90 params.o parallel.o helectron.o keepclocks.o angles.o neutrinodist.o
   $(F90) $(FFLAGS) $(FOPT) -c spincohere.F90     bulb-new.o  : bulb-new.F90 params.o parallel.o keep_clocks.o helectron.o angles.o neutrinodist.o spincohere.o
   $(F90) $(FFLAGS) $(FOPT) -c bulb-new.F90
bulb-new3.o  : bulb-new3.F90 params.o parallel.o keep_clocks.o  
   $(F90) $(FFLAGS) $(FOPT) -c bulb-new3.F90
rannyu.o  : rannyu.f
   $(F77) $(F77FLGS) $(FOPT) -c rannyu.f
spline.o   : spline.f
   $(F77) $(F77FLGS) $(FOPT) -c spline.f
splint.o   : splint.f
   $(F77) $(F77FLGS) $(FOPT) -c splint.f
plotit   : plotit.F90
   $(F90) $(FFLAGS) $(FOPT) -o plotit plotit.F90 $(LIBGRACE)
plotdens   :  params_numeric.o plotdens.F90
   $(F90) $(FFLAGS) $(FOPT) -o plotdens plotdens.F90 params_numeric.o  $(LIBGRACE) $(LIBCDF)
#  needed cdfsave.o in above two lines also for cdf data file
printhvv   : params.o printhvv.F90
   $(F90) $(FFLAGS) $(FOPT) -o printhvv printhvv.F90 params.o
printhe   : params.o printhe.F90
   $(F90) $(FFLAGS) $(FOPT) -o printhe printhe.F90 params.o
tar   :
   tar -cvf laptop.tar cdfsave.F90 keep_clocks.F90 params.F90 bulb-new.F90 rannyu.f plotit.F90 printhvv.F90 printhe.F90 parallel.F90 params_numeric.F90 plotdens.F90 params_numeric.F90 cdfsave.F90 helectron.F90 splint.f spline.f Makefile makefile* bulb*in* *run* zheevh3-F-1.0
clean   :
   \rm *.o bulb-new

I think I should have at least made the spincohere module correctly. I have moved the modules "angles" and "neutrinodist" to outside of the bulb-new.F90 file and created them separately. Also, I added "helectron.o" to the prerequisites for compiling bulb-new.o. I couldn't quite understand your comment on that, will this somehow make compiling bulb-new.o worse or not work? Because I don't really see any difference between this module "helectron.o" that was missing from the prerequisites and any of the other 3 modules that were there...

I am now at a loss as to how to incorporate zheev. Are you familiar at all in implementing these linear algebra packs? I downloaded the whole LAPACK version 3.5 and there are a TON of files which I'm sure are not all used by zheev. There are also a bunch of different makefile's in a bunch of different directories, and I can't understand the documentation...like...at all...T_T
 
  • #14
Matterwave said:
Yes, in here: http://kiwi.atmos.colostate.edu/fortran/docs/fortran90-mar30.pdf page 7, it says that the first target should be the one that is built, and all subsequent target's orders do not matter.
Ok, I see. This is just in order to make the executable the default build. But this is not mandatory.

Matterwave said:
I think I should have at least made the spincohere module correctly. I have moved the modules "angles" and "neutrinodist" to outside of the bulb-new.F90 file and created them separately. Also, I added "helectron.o" to the prerequisites for compiling bulb-new.o. I couldn't quite understand your comment on that, will this somehow make compiling bulb-new.o worse or not work? Because I don't really see any difference between this module "helectron.o" that was missing from the prerequisites and any of the other 3 modules that were there...
It is better to have it as a prerequisite.

Matterwave said:
I am now at a loss as to how to incorporate zheev. Are you familiar at all in implementing these linear algebra packs? I downloaded the whole LAPACK version 3.5 and there are a TON of files which I'm sure are not all used by zheev. There are also a bunch of different makefile's in a bunch of different directories, and I can't understand the documentation...like...at all...T_T
Yes, I am familiar! You basically have two options. The first is to compile and install the full LAPACK and BLAS libraries. This may actually have already been done. Check /usr/lib or /usr/local/lib (or some other appropriate directory with library files) to see if there is anything with "lapack" or "blas" in the name. If this is not the case, then you can compile the libraries yourself. Usually, you simply need to go into the main directory, issue the command "./configure", then "make", and finally, "make install" (you may need to be root to do that).

If all that sounds too complicated (although do check first if LAPACK is installed), go to http://www.netlib.org/cgi-bin/search.pl and search for zheev. The fisrt result you should get should be a link to the zheev code, and you will notice a link next to it called "plus dependencies". If you click that link, it will allow you to download only zheev and all the other subroutines zheev needs, but nothing more. You can then either put them in a directory and use something similar to what is in your makefile for zheev3, or put the content of all the files in one big .f file and compile into a .o object that as you would any Fortran file.
 
  • #15
DrClaude said:
Yes, I am familiar! You basically have two options. The first is to compile and install the full LAPACK and BLAS libraries. This may actually have already been done. Check /usr/lib or /usr/local/lib (or some other appropriate directory with library files) to see if there is anything with "lapack" or "blas" in the name. If this is not the case, then you can compile the libraries yourself. Usually, you simply need to go into the main directory, issue the command "./configure", then "make", and finally, "make install" (you may need to be root to do that).

If all that sounds too complicated (although do check first if LAPACK is installed), go to http://www.netlib.org/cgi-bin/search.pl and search for zheev. The fisrt result you should get should be a link to the zheev code, and you will notice a link next to it called "plus dependencies". If you click that link, it will allow you to download only zheev and all the other subroutines zheev needs, but nothing more. You can then either put them in a directory and use something similar to what is in your makefile for zheev3, or put the content of all the files in one big .f file and compile into a .o object that as you would any Fortran file.

Ah, this is where my lack of computing prowess really shows! So if I actually "installed LAPACK" on my computer (that's the first option right?), then I can use its functions, like zheev, while running my fortran code in my terminal without having to link this function zheev in my code's executable? In other words, if I have "installed LAPACK", do I need something like a "-o zheev.o" in my executable line in my makefile for my bulb-new code?

For the second option, I assume that I do have to create an object zheev.o and then link it?

I think eventually I will have to run this code on a supercomputer...so...probably the second option will be better for me in the long run since I don't know if the supercomputer has LAPACK installed? Maybe it does...o.o
 
  • #16
Matterwave said:
Ah, this is where my lack of computing prowess really shows! So if I actually "installed LAPACK" on my computer (that's the first option right?), then I can use its functions, like zheev, while running my fortran code in my terminal without having to link this function zheev in my code's executable? In other words, if I have "installed LAPACK", do I need something like a "-o zheev.o" in my executable line in my makefile for my bulb-new code?
When object files are made part of a library, they are not individually accessible. In the linking stage (where the executable is produced), you have to add the library itself, using "-llapack" (that's -l followed by the name of the library).

Matterwave said:
For the second option, I assume that I do have to create an object zheev.o and then link it?
Right.

Matterwave said:
I think eventually I will have to run this code on a supercomputer...so...probably the second option will be better for me in the long run since I don't know if the supercomputer has LAPACK installed? Maybe it does...o.o
I would be surprised if a supercomputer doesn't have LAPACK already installed. Usually, these libraries (meaning LAPACK but especially BLAS, on which LAPACK relies) are finely tuned to be optimal on such systems. It is always preferable to use the precompiled libraries instead of compiling the LAPACK code as part of your program.
 
  • #17
DrClaude said:
When object files are made part of a library, they are not individually accessible. In the linking stage (where the executable is produced), you have to add the library itself, using "-llapack" (that's -l followed by the name of the library).Right.I would be surprised if a supercomputer doesn't have LAPACK already installed. Usually, these libraries (meaning LAPACK but especially BLAS, on which LAPACK relies) are finely tuned to be optimal on such systems. It is always preferable to use the precompiled libraries instead of compiling the LAPACK code as part of your program.

Thanks for the information!
Ok, so say I install lapack in some directory (don't know what yet), all I have to add to my makefile is a line -llapack and that's it? Do I have to tell my code were to find lapack, in which directory, etc?

Also, the part of my code which actually uses zheev (i.e. which actually has the line "call zheev(___)" is the module spincohere (which will of course be used by the main code). Do I have to type -llapack in the prerequisites for compiling spincohere?

EDIT: I think I should mention that trying to compile my code now with all the modifications I've made, everything works (i.e. I see all the pieces compiling) until it gets to creating the executable, at which point I'm getting some errors which I assume is because I have not installed lapack...(i hope), so this is indeed where I'm at in trying to run this code lol.
 
Last edited:
  • #18
Follow up question: is there a way to install lapack in ubuntu just from the terminal? I tried sudo apt-get install lapack and sudo apt-get install liblapack and both times the terminal said it couldn't find it. :(

EDIT: I tried sudo apt-get install liblapack-dev and something actually happened, like it was trying to install it, except I get an error saying there are certain archives not found...I'm not sure...what's up...I seem to be just bumbling around here. It seems to be trying to install version 3.4 instead of the newest version 3.5...

Trying to build my code anyways, without even downloading lapack, I'm getting this error:

Code:
gfortran  -O3  -o bulb-new bulb-new.o params.o helectron.o spincohere.o keep_clocks.o parallel.o rannyu.o spline.o splint.o zheevh3-F-1.0/*.o -llapack
zheevh3-F-1.0/sqrabs.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status

I am so confused because zheevh3 was never a problem before, when I ran the old code! In fact, I reverted to the old version of the code, and I'm getting this same error now, and I can't even run the non-modified code! I am really really confused...:(
 
Last edited:
  • #19
Matterwave said:
Ok, so say I install lapack in some directory (don't know what yet), all I have to add to my makefile is a line -llapack and that's it? Do I have to tell my code were to find lapack, in which directory, etc?
That depends. Usually, environment variables are such that if it is in /use/lib or /use/local/lib, the compiler will find it by itself. Otherwise, you can sepecity the directory using -L, as in "-L/usr/local/lib".

Matterwave said:
Also, the part of my code which actually uses zheev (i.e. which actually has the line "call zheev(___)" is the module spincohere (which will of course be used by the main code). Do I have to type -llapack in the prerequisites for compiling spincohere?
No, the compiler only needs to access the library when merging the object files into an executable, so it only needs to be specified when building the executable.
Matterwave said:
Follow up question: is there a way to install lapack in ubuntu just from the terminal? I tried sudo apt-get install lapack and sudo apt-get install liblapack and both times the terminal said it couldn't find it. :(

EDIT: I tried sudo apt-get install liblapack-dev and something actually happened, like it was trying to install it, except I get an error saying there are certain archives not found...I'm not sure...what's up...I seem to be just bumbling around here. It seems to be trying to install version 3.4 instead of the newest version 3.5...
Not sure I can help you here. Maybe you should try installing liblapack3.

Matterwave said:
Trying to build my code anyways, without even downloading lapack, I'm getting this error:

Code:
gfortran  -O3  -o bulb-new bulb-new.o params.o helectron.o spincohere.o keep_clocks.o parallel.o rannyu.o spline.o splint.o zheevh3-F-1.0/*.o -llapack
zheevh3-F-1.0/sqrabs.o: file not recognized: File format not recognized
collect2: error: ld returned 1 exit status

I am so confused because zheevh3 was never a problem before, when I ran the old code! In fact, I reverted to the old version of the code, and I'm getting this same error now, and I can't even run the non-modified code! I am really really confused...:(
Could the compiler have been modified when you tried those installs? I suggest you remove all objects files from that directory and try recompiing:
Code:
rm zheevh3-F-1.0/*.o
make
 
  • #20
DrClaude said:
That depends. Usually, environment variables are such that if it is in /use/lib or /use/local/lib, the compiler will find it by itself. Otherwise, you can sepecity the directory using -L, as in "-L/usr/local/lib".No, the compiler only needs to access the library when merging the object files into an executable, so it only needs to be specified when building the executable.
Not sure I can help you here. Maybe you should try installing liblapack3.Could the compiler have been modified when you tried those installs? I suggest you remove all objects files from that directory and try recompiing:
Code:
rm zheevh3-F-1.0/*.o
make

Thanks for the continued help!

I have actually tried to remove the object files and recompile zheevh3...however it was written in F77 and the makefile for zheevh3 requires f77 which I don't have. Can I change it to gfortran? Will that work?
 
  • #21
Matterwave said:
I have actually tried to remove the object files and recompile zheevh3...however it was written in F77 and the makefile for zheevh3 requires f77 which I don't have. Can I change it to gfortran? Will that work?
Yes, gfortran handles Fortran 77 without problems (it will automatically recognize the .f extension).
 
  • #22
DrClaude said:
Yes, gfortran handles Fortran 77 without problems (it will automatically recognize the .f extension).

Ok thanks! I'm in the long and arduous process of updating my ubuntu to version 14.04 now...before which I have to back up my hard drive...before which I have to run disk check utilities to fix the errors on my hard drive. This may take a while, but once I am able to get it all set up, I'll try out your suggestions! Thanks. :)
 
  • #23
Ok, so I have updated Ubuntu, and I have also fixed the problem with zheevh3 by remaking the object files.

Now, I have installed lapack via the command: "sudo apt-get install liblapack3"

And the terminal appears to have installed the package. When I try to compile my code, everything compiles fine until the very last step and I get an error:
Code:
/usr/bin/ld: cannot find -llapack
collect2: error: ld returned 1 exit status

So I'm guessing lapack did not install in the right place, or I did not name it correctly in my makefile?

I have also tried -llapack3 and -liblapack3 and just -lapack3 in the makefile, and I get the same error on each try.
 
Last edited:
  • #24
As a desperation move, you can use the command "sudo find / -name '*lapack*'".

Finding something from / will take a while.
 
  • #25
D H said:
As a desperation move, you can use the command "sudo find / -name '*lapack*'".

Finding something from / will take a while.

The first output is usr/lib/lapack

So I guess make is trying to find it in usr/bin/ld but It should look in usr/lib...?

EDIT:
I have edited the makefile to read -L/usr/lib/lapack and now it goes past that part in compiling...and now I have a ton of other compile errors to deal with... I guess I expected this...

So, now I have follow up questions on these compile time errors. Would it be good to start a new thread since we've now moved quite far from "makefile confusion" or just continue here?
 
Last edited:
  • #26
Sorry for all these useless updates, I have a tendency to keep posting before I figure out the problem (sometimes it helps me to "talk" through my problems lol). My compile time errors stated above came from me forgetting to link the .o files for 2 modules in my makefile. After fixing that I just have one error left which is:

Code:
spincohere.o: In function `__spincohere_MOD_exphcalsp':
spincohere.F90:(.text+0xbb): undefined reference to `zheev_'
collect2: error: ld returned 1 exit status
make: *** [bulb-new] Error 1

So, even though now the compiler is not worried about being unable to find "lapack" after I changed the "-llapack" line to "-L/usr/lib/lapack", it still doesn't understand what the function "zheev" is...what's up with that?

I even tried adding "-L/usr/lib/blas3" so that bulb-new has access to BLAS but I get the same error...
 
Last edited:
  • #27
Matterwave said:
Code:
spincohere.o: In function `__spincohere_MOD_exphcalsp':
spincohere.F90:(.text+0xbb): undefined reference to `zheev_'
collect2: error: ld returned 1 exit status
make: *** [bulb-new] Error 1

So, even though now the compiler is not worried about being unable to find "lapack" after I changed the "-llapack" line to "-L/usr/lib/lapack", it still doesn't understand what the function "zheev" is...what's up with that?
Did you forget the "call", as in "call zheev(...)"?
 
  • #28
DrClaude said:
Did you forget the "call", as in "call zheev(...)"?

Nope, I double checked that the code there looks like this:
Code:
elseif((nflavor.eq.2).or.(nflavor.eq.3)) then
   call zheev('v','u',nflavor2,eigvec,nflavor2,eigval,work,lwork,rwork,info)
 
  • #29
That's strange. If you send me the code, I'll have a look at it.
 
  • #30
DrClaude said:
That's strange. If you send me the code, I'll have a look at it.

Do you mean the whole code, or just the module spincohere?

The whole code is VERY long! I'd imagine it would take quite a while to actually go through. I never even went through it all in its entirety...@_@
 
  • #31
Matterwave said:
Do you mean the whole code, or just the module spincohere?

The whole code is VERY long! I'd imagine it would take quite a while to actually go through. I never even went through it all in its entirety...@_@
Just spincohere.
 
  • #32
DrClaude said:
Just spincohere.

I have messaged it to you. Thanks. :D
 
  • #33
Matterwave said:
I have messaged it to you. Thanks. :D
I had a look, and there is no problem there. I now realize that I misread something in the error message you posted, and it should've been clear to me that the error was not in your code.

I'll get back to you tomorrow.
 
  • #34
DrClaude said:
I had a look, and there is no problem there. I now realize that I misread something in the error message you posted, and it should've been clear to me that the error was not in your code.

I'll get back to you tomorrow.

Ok thanks!
 
  • #35
DrClaude said:
I had a look, and there is no problem there. I now realize that I misread something in the error message you posted, and it should've been clear to me that the error was not in your code.

I'll get back to you tomorrow.

I have figured it out! I needed to install liblapack-dev instead of just liblapack3 as well. Now my code runs! But now I have more questions, which, since it has nothing to do with this make file, I will now post in a separate thread.
 

1. What is a Makefile and why is it used for Fortran code?

A Makefile is a file that contains a set of instructions for compiling and linking source code into an executable file. It is commonly used for Fortran code because it allows for efficient and automated compilation of multiple source files and dependencies.

2. How do I create a Makefile for Fortran code?

To create a Makefile for Fortran code, you will need to specify the source files, compiler options, and dependencies. You can use a text editor to manually create the Makefile or use a build automation tool like CMake or GNU Make.

3. How do I troubleshoot errors in a Makefile?

If you encounter errors while using a Makefile for Fortran code, you can use the make command with the -n option to perform a dry run and see the commands that will be executed. Additionally, you can use the make -d option to get more detailed debugging information.

4. Can I use a Makefile for parallel compilation of Fortran code?

Yes, you can use a Makefile to enable parallel compilation of Fortran code by specifying the -j option with the number of parallel jobs to run. This can significantly reduce the compilation time for large projects.

5. How do I update a Makefile when I add new source files to my Fortran project?

If you add new source files to your Fortran project, you will need to update the Makefile to include these files as dependencies. You can do this manually or use a build automation tool like CMake to automatically detect and include new source files in the Makefile.

Back
Top