0

I have program writing on fortran which uses library. For compiling I use my simple shell script and everything is fine:

gfortran -c mod_input.f90 mod_cpp.f90 mod_data.f90 main.f90 b_coils.f

gfortran -o main mod_input.o mod_cpp.o mod_data.o main.o b_coils.o libspline.a -lstdc++

(libspline.a - library writing on c++)

Now I want to use makefile instead of shell script, but don't know how to write it properly.

Makefile:

target = main srcdir = src/ objdir = obj/ targetdir = run/ FORT = gfortran mflag = module FORTFLAGS = LDFLAGS = -lstdc++ MKLPATH =/home/gatto/Desktop/ray_u3/src LIBDIR =-L$(MKLPATH) LIBS = -lspline MODDIR = obj/ # Ray sources sources = mod_input.f90 mod_cpp.f90 mod_data.f90 main.f90 b_coils.f # objects objects = $(patsubst %.for,%.o,$(filter %for,$(sources)) ) objects += $(patsubst %.f90,%.o,$(filter %f90,$(sources)) ) # main target build:$(targetdir)$(target) # build rules $(targetdir)$(target):$(addprefix $(objdir),$(objects)) @echo === build $@ === $(FORT) $(FORTFLAGS) $(LDFLAGS) $(LIBDIR) -o $@ $(LIBS) $^ #compilation target compile :$(addprefix $(objdir),$(objects)) # compilation rules $(objdir)%.o : $(srcdir)%.f90 @echo === compile $< === $(FORT) -c $(objdir) $(FORTFLAGS) -o $@ $< $(objdir)%.o : $(srcdir)%.f @echo === compile $< === $(FORT) -c $(objdir) $(FORTFLAGS) -o $@ $< # cleaning rules cleanobj: -rm $(objdir)*.o $(objdir)*.mod cleantarget: -rm $(targetdir)$(target) cleanall:cleanobj cleantarget .PHONY: compile build cleanall cleanobj cleantarget 

Output:

gfortran -lstdc++ -L/home/gatto/Desktop/ray_u3/src -o run/main -lspline obj/mod_input.o obj/mod_cpp.o obj/mod_data.o obj/main.o obj/mod_data.o: In function `__global_data_MOD_modbfield': mod_data.f90:(.text+0x3e2): undefined reference to `gbcoil_' obj/mod_data.o: In function `__global_data_MOD_moddensity': mod_data.f90:(.text+0x5d4): undefined reference to `GetSplineValue' mod_data.f90:(.text+0x64f): undefined reference to `GetSplineValue' mod_data.f90:(.text+0x6ca): undefined reference to `GetSplineValue' mod_data.f90:(.text+0x745): undefined reference to `GetSplineValue' obj/mod_data.o: In function `__global_data_MOD_inpfile': mod_data.f90:(.text+0xa66): undefined reference to `Approx_input' mod_data.f90:(.text+0xa75): undefined reference to `SetSpline' collect2: error: ld returned 1 exit status make: *** [run/main] Error 1 
5
  • 3
    Lets start with indentation, the commands for a rule needs to be indented by a single tab. When you fixed that come back and update the question to include the actual problem you have with the makefile. Like for example tell us what happens you try to use it. Include all output, complete and unedited. Commented Dec 10, 2015 at 13:45
  • You have a makefile snippet here which uses a large number of variables that aren't defined anywhere we can see. You need to show us a complete example and, as Joachim indicated, the commands you are running and the exact output/results you are getting. Commented Dec 10, 2015 at 13:59
  • I've edited my post. Commented Dec 10, 2015 at 14:27
  • Have you tried moving your $^ before the $(LIBS)? Order matters when linking, so it may be as simple as that. Commented Dec 10, 2015 at 16:46
  • 1
    Why don't you follow a makefile tutorial if you are new to makefiles? for example cs.colby.edu/maxwell/courses/tutorials/maketutor or cs.usask.ca/staff/oster/makefiles.html or google for more convenient tutorial. Commented Dec 10, 2015 at 19:47

1 Answer 1

1

I would suggest you to use automake (and autoconf). It do have a large number of metatags, but for simple programs, its faster to write, and in most of the cases, you may find yourself get going with minimal changes (like filename).

Here is my autoconf and automake's input for a similar project, which just uses lapack, instead of mkl.

configure.ac

#AC_PREREQ(2.69) AC_INIT([src], [0.1], [], [mftc], []) AC_CONFIG_AUX_DIR([build-aux]) AC_CONFIG_HEADERS([config.h]) AC_CONFIG_MACRO_DIR([m4]) AM_INIT_AUTOMAKE([1.9.6 dist-bzip2 subdir-objects foreign]) AC_SEARCH_LIBS([dsyev_], [lapack], ,AC_MSG_ERROR([No LAPACK library])) AC_OPENMP FCFLAGS="$OPENMP_FFLAGS " AC_PROG_FC([gfortran, ifort]) AC_CHECK_PROG([DEPF90_CHECK],[makedepf90],[yes],[no]) AM_CONDITIONAL([FOUND_MAKEDEPF90], [test "x$DEPF90_CHECK" = xyes]) AC_CONFIG_FILES([ Makefile ]) AC_OUTPUT 

Makefile.am

bin_PROGRAMS = mftc mftc_SOURCES = src/mftc.f90 src/parse.f90 src/sort.f90 depend depend.mk: makedepf90 $(mftc_SOURCES) >depend.mk @am__include@ @[email protected]@am__quote@ mftc_LDADD = EXTRA_DIST=depend.mk autogen.sh Makefile.am CLEANFILES =*.mod *.log 

The depend depend.mk depends on makedepf90 program, which is available on most linux platform. This program take care of the dependencies (that is modules are compiled first before the program).

Usage If you are ok with LAPACK, I don't see anything for you to change in the configure.ac. Change _SOURCES line for proper filename. Now, its 3 command in terminal:

 $autoconf $./configure $make 

Off course, you also need to have automake and autoconf installed.

Hope, this helps

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.