masalah makefile gfortran

Saya memiliki program penulisan di fortran yang menggunakan perpustakaan. Untuk kompilasi saya menggunakan skrip shell sederhana dan semuanya baik-baik saja:

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 - penulisan perpustakaan di c++)

Sekarang saya ingin menggunakan makefile daripada skrip shell, tetapi tidak tahu cara menulisnya dengan benar.

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

Keluaran:

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

person Gatto Nou    schedule 10.12.2015    source sumber
comment
Mari kita mulai dengan indentasi, perintah untuk suatu aturan perlu diindentasi oleh satu tab. Ketika Anda memperbaikinya, kembalilah dan perbarui pertanyaan untuk memasukkan masalah sebenarnya yang Anda alami dengan makefile. Misalnya, beri tahu kami apa yang terjadi saat Anda mencoba menggunakannya. Sertakan semua keluaran, lengkap dan belum diedit.   -  person Some programmer dude    schedule 10.12.2015
comment
Anda memiliki cuplikan makefile di sini yang menggunakan sejumlah besar variabel yang tidak ditentukan di mana pun yang dapat kita lihat. Anda perlu menunjukkan kepada kami contoh lengkap dan, seperti yang ditunjukkan Joachim, perintah yang Anda jalankan dan keluaran/hasil persis yang Anda peroleh.   -  person Etan Reisner    schedule 10.12.2015
comment
Saya telah mengedit posting saya.   -  person Gatto Nou    schedule 10.12.2015
comment
Sudahkah Anda mencoba memindahkan $^ sebelum $(LIBS)? Urutan penting saat menautkan, jadi mungkin sesederhana itu.   -  person jefflarkin    schedule 10.12.2015
comment
Mengapa Anda tidak mengikuti tutorial makefile jika Anda baru mengenal makefile? misalnya cs.colby.edu/maxwell/courses/tutorials/maketutor atau cs.usask.ca/staff/oster/makefiles.html atau google untuk tutorial yang lebih nyaman.   -  person innoSPG    schedule 10.12.2015


Jawaban (1)


Saya menyarankan Anda untuk menggunakan automake (dan autoconf). Jumlah metatagnya memang banyak, namun untuk program sederhana, penulisannya akan lebih cepat, dan di sebagian besar kasus, Anda mungkin akan memulai dengan sedikit perubahan (seperti filename).

Ini masukan autoconf dan automake saya untuk proyek serupa, yang hanya menggunakan lapack, bukan 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

depend depend.mk bergantung pada program makedepf90, yang tersedia di sebagian besar platform linux. Program ini menangani dependensi (yaitu modul dikompilasi terlebih dahulu sebelum program).

Penggunaan Jika Anda setuju dengan LAPACK, saya tidak melihat apa pun yang dapat Anda ubah di konfigurasi.ac. Ubah baris _SOURCES untuk nama file yang tepat. Sekarang, 3 perintahnya di terminal:

 $autoconf 
 $./configure 
 $make

Tentu saja, Anda juga perlu menginstal automake dan autoconf.

Semoga ini membantu

person BaRud    schedule 11.12.2015