Προς το περιεχόμενο

Προτεινόμενες αναρτήσεις

Δημοσ.

Χαίρετε,

 

έχω δύο αρχεία Fortran[σε τελείως ξεχωριστούς φακέλους το ένα από το άλλο], ένα στο home/myname/Documents/test με όνομα mod1.f90 και ένα άλλο στο: /home/myname/Desktop/Project2 με όνομα main.f90

subroutine average (N, A, ave)
integer N
real A(N), ave
ave = 0.0
do i=1,N
ave = ave + A(i)
enddo
ave = ave/N

return
end 

και

program main
parameter (lon=14)
real data (lon), zaverage

write (*,*)' This is a program to find zonal average of a data'



open (1,file='inputdata.dat')
do i=1,lon
read (1,*) data(i)
enddo


call average (lon, data, zaverage)

write(*,10)'The zonal average of given data is ', zaverage
10 format(a40,f8.3)

end

Χρησιμοποιώ των παρακάτω κώδικα για να τρέξω τη main:

cd home/myname/Documents/test
gfortran -shared -fpic -o mod1.so mod1.f90
cd
cd Desktop/Project2
gfortran -L/home/myname/Documents/test/ -c main.f90 main.o -lmod1 -o myprog
./myprog

Το μήνυμα λάθους που μου δίνει είναι: gfortran: warning: main.o: linker input file unused because linking not done

 

Γιατί δεν κάνει σύνδεση η main με την mod1?

 

 

Thanks

 

Υ.Γ. Χρησιμοποιώ Ubuntu 13.04,   32-bit.

Δημοσ.

Χρησιμοποιώ των παρακάτω κώδικα για να τρέξω τη main:

cd home/myname/Documents/test
gfortran -shared -fpic -o mod1.so mod1.f90
cd
cd Desktop/Project2
gfortran -L/home/myname/Documents/test/ -c main.f90 main.o -lmod1 -o myprog
./myprog
Το μήνυμα λάθους που μου δίνει είναι: gfortran: warning: main.o: linker input file unused because linking not done

 

Γιατί δεν κάνει σύνδεση η main με την mod1?

 

Δεν έχω ασχοληθεί με τον gfortran αλλά στον gcc ισχύει

-c Compile or assemble the source files, but do not link. The linking stage simply is not done. The ultimate output is in the form of an object file for each source file.

Δοκίμασε χωρίς το -c. Για να βρει την mod1 λογικά θα χρειαστείς και -L/home/τάδε. Επίσης γιατί έχεις γράψει το main.o στη γραμμή ?

 

Ό,τι να ναι βλέπω. Έχεις ήδη βάλει -L.

Δημοσ.

Δεν έχω ασχοληθεί με τον gfortran αλλά στον gcc ισχύει

 

Δοκίμασε χωρίς το -c. Για να βρει την mod1 λογικά θα χρειαστείς και -L/home/τάδε. Επίσης γιατί έχεις γράψει το main.o στη γραμμή ?

 

Ό,τι να ναι βλέπω. Έχεις ήδη βάλει -L.

Αν δεν βάλω το -c δεν μπορεί να δημιουργήσει τη main.o

 

Χωρίς τη main.o πώς θα συνδεθούν;

Δημοσ.

Αν δεν βάλω το -c δεν μπορεί να δημιουργήσει τη main.o

 

Χωρίς τη main.o πώς θα συνδεθούν;

gfortran -L/home/myname/Documents/test/ -c main.f90 main.o -lmod1 -o myprog

Η -c κάνει compile και παράγει το object file. Όταν του βάζεις -o mypro, τότε το όνομά του θα είναι myprog και όχι main.o. Ή δεν έχεις καταλάβει πως λειτουργεί η compilation ή δεν έχω καταλάβει εγώ ποιο είναι το πρόβλημα. Η γραμμή σου πάντως δεν μου φαίνεται σωστή.

 

/tmp% gfortran -shared -fPIC -o libmod1.so mod1.f90
/tmp% gfortran -L/tmp main.f90 -o myprog -lmod1
/tmp% gfortran -c -L/tmp main.f90 -o mytest -lmod1
Δεν βγαίνει κανένα μήνυμα λάθους και η compilation γίνεται κανονικά.

 

/tmp% file my*
myprog: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
mytest: ELF 64-bit LSB  relocatable, x86-64, version 1 (SYSV), not stripped
Όπως βλέπεις, το mytest στο οποίο χρησιμοποίησα την -c είναι "relocatable" και όχι το τελικό εκτελέσιμο.

 

1ος τρόπος:
gfortran -c main.f90 -o main.o
gfortran -L/tmp -lmod1 -o myprog main.o
2ος τρόπος:
gfortran -L/tmp -lmod1 -o myprog main.f90
Με τον 1ο τρόπο στο ένα βήμα κάνεις compile και παράγεις το object file main.o (είσοδος είναι το main.f90 και έξοδος το main.o) για αυτό και βλέπεις να μην έχω βάλει καθόλου παραμέτρους για τον linker και στο άλλο βήμα παίρνεις αυτό το object file και το κάνεις link μαζί με την βιβλιοθήκη και παράγεις το τελικό εκτελέσιμο (είσοδος είναι το main.o και έξοδος το εκτελέσιμο myprog). Ο 2ος τρόπος σου επιτρέπει να ενώσεις τα δύο βήματα σε ένα και να παράγεις κατευθείαν το τελικό εκτελέσιμο (είσοδος είναι το main.f90 και έξοδος το myprog) χωρίς ενδιάμεσα βήματα με object files (Ο compiler θα παράξει μεν όσα object files χρειάζονται αλλά θα τα σβήσει αφού γίνει το link)

 

Στη δική σου γραμμή έμπλεξες και τους δύο τρόπους. Αν εννοείς κάτι άλλο και δεν κατάλαβα, γράψε ακριβώς το μήνυμα λάθους που έβγαλε ο compiler.

Δημοσ.

Η -c κάνει compile και παράγει το object file. Όταν του βάζεις -o mypro, τότε το όνομά του θα είναι myprog και όχι main.o. Ή δεν έχεις καταλάβει πως λειτουργεί η compilation ή δεν έχω καταλάβει εγώ ποιο είναι το πρόβλημα. Η γραμμή σου πάντως δεν μου φαίνεται σωστή.

 

/tmp% gfortran -shared -fPIC -o libmod1.so mod1.f90
/tmp% gfortran -L/tmp main.f90 -o myprog -lmod1
/tmp% gfortran -c -L/tmp main.f90 -o mytest -lmod1
Δεν βγαίνει κανένα μήνυμα λάθους και η compilation γίνεται κανονικά.

 

/tmp% file my*
myprog: ELF 64-bit LSB  executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped
mytest: ELF 64-bit LSB  relocatable, x86-64, version 1 (SYSV), not stripped
Όπως βλέπεις, το mytest στο οποίο χρησιμοποίησα την -c είναι "relocatable" και όχι το τελικό εκτελέσιμο.

 

1ος τρόπος:
gfortran -c main.f90 -o main.o
gfortran -L/tmp -lmod1 -o myprog main.o
2ος τρόπος:
gfortran -L/tmp -lmod1 -o myprog main.f90
Με τον 1ο τρόπο στο ένα βήμα κάνεις compile και παράγεις το object file main.o (είσοδος είναι το main.f90 και έξοδος το main.o) για αυτό και βλέπεις να μην έχω βάλει καθόλου παραμέτρους για τον linker και στο άλλο βήμα παίρνεις αυτό το object file και το κάνεις link μαζί με την βιβλιοθήκη και παράγεις το τελικό εκτελέσιμο (είσοδος είναι το main.o και έξοδος το εκτελέσιμο myprog). Ο 2ος τρόπος σου επιτρέπει να ενώσεις τα δύο βήματα σε ένα και να παράγεις κατευθείαν το τελικό εκτελέσιμο (είσοδος είναι το main.f90 και έξοδος το myprog) χωρίς ενδιάμεσα βήματα με object files (Ο compiler θα παράξει μεν όσα object files χρειάζονται αλλά θα τα σβήσει αφού γίνει το link)

 

Στη δική σου γραμμή έμπλεξες και τους δύο τρόπους. Αν εννοείς κάτι άλλο και δεν κατάλαβα, γράψε ακριβώς το μήνυμα λάθους που έβγαλε ο compiler.

 

 

 

Χρησιμοποιω τον εξης κωδικα:

cd Documents/test
gfortran -shared -fpic -o mod1.so mod1.f90
cd
cd Desktop/Project2
gfortran -L/home/pantelis/Documents/test/  main.f90 -o myprog  -lmod1

Disclaimer: Ειμαι πολυ νεος στο αθλημα για τουτο ζητώ να ειστε λιγο επιεικείς :P

 

Με την πρώτη εντολή πηγαίνω στην υπορουτίνα

Με τη δευτερη φτιάχνω το .so αρχειο που χρειάζεται για να κανω το shared object

Με την τριτη και τεταρτη εντολη πάω στο φάκελο που έχει τον κυριο κωδικά μου. Αυτος ο κωδικας δεν μπορεί να λειτουργήσει χωρις το .so αρχείο που είναι όμως σε άλλο φάκελο.

 

Με την τελευταία εντολή του λέω να τρέξει τη main, χρησιμοποιώντας το mod1.so που βρίσκεται:   

home/myname/Documents/test/

 

Την ίδια στιγμή φτιάχνω το εκτελέσιμο με όνομα myprog κάνοντας χρήση του -o.

 

Το μήνυμα λάθους που εμφανίζεται είναι:

 

/usr/bin/ld: cannot find -lmod1

collect2: error: ld returned 1 exit status

 

Το πρόγραμμα δεν καταλαβαίνει οτι δεν ψάχνω το αρχείο στο  /usr/bin/ld, αλλά στο /home/myname/Documents/test/

 

Όταν βάζω όλα τα αρχεία στον ίδιο φάκελο δουλεύει (εκεί βάζεις -L.), οπότε δεν καταλαβαίνει που να ψάξει, παρά το γεγονός ότι του λέω που. Γιατί δεν με "ακούει";   

Δημοσ.

 

gfortran -shared -fpic -o mod1.so mod1.f90
gfortran -L/home/pantelis/Documents/test/  main.f90 -o myprog  -lmod1
Με τη δευτερη φτιάχνω το .so αρχειο που χρειάζεται για να κανω το shared object

Με την τριτη και τεταρτη εντολη πάω στο φάκελο που έχει τον κυριο κωδικά μου. Αυτος ο κωδικας δεν μπορεί να λειτουργήσει χωρις το .so αρχείο που είναι όμως σε άλλο φάκελο.

 

Ωραία. Αυτή η γραμμή δεν έχει ούτε main.o ούτε -c και είναι σωστή. Χρησιμοποιείς τον 2ο τρόπο που περιέγραψα και κάνεις compile χωρίς ενδιάμεσα αρχεία.

 

Το μήνυμα λάθους που εμφανίζεται είναι:

 

/usr/bin/ld: cannot find -lmod1

collect2: error: ld returned 1 exit status

 

Το πρόγραμμα δεν καταλαβαίνει οτι δεν ψάχνω το αρχείο στο  /usr/bin/ld, αλλά στο /home/myname/Documents/test/

 

Όταν βάζω όλα τα αρχεία στον ίδιο φάκελο δουλεύει (εκεί βάζεις -L.), οπότε δεν καταλαβαίνει που να ψάξει, παρά το γεγονός ότι του λέω που. Γιατί δεν με "ακούει";

Όπου /usr/bin/ld εννοείς /usr/lib (και /lib) αλλά καταλαβαίνω τι λες.

 

Πρόσεξες κάποια διαφορά στη δική μου εντολή που δημιούργησε την βιβλιοθήκη και στη δική σου ? Ας δούμε τι λέει η manpage του linker

-l namespec

.... ld will search a directory for a library called

libnamespec.so ....

Αν λοιπόν αλλάξεις την εντολή σου από

gfortran -shared -fpic -o mod1.so mod1.f90
σε

gfortran -shared -fpic -o libmod1.so mod1.f90
θα την βρει ?
Δημοσ. (επεξεργασμένο)

Ωραία. Αυτή η γραμμή δεν έχει ούτε main.o ούτε -c και είναι σωστή. Χρησιμοποιείς τον 2ο τρόπο που περιέγραψα και κάνεις compile χωρίς ενδιάμεσα αρχεία.

 

Όπου /usr/bin/ld εννοείς /usr/lib (και /lib) αλλά καταλαβαίνω τι λες.

 

Πρόσεξες κάποια διαφορά στη δική μου εντολή που δημιούργησε την βιβλιοθήκη και στη δική σου ? Ας δούμε τι λέει η manpage του linker

Αν λοιπόν αλλάξεις την εντολή σου από

gfortran -shared -fpic -o mod1.so mod1.f90
σε

gfortran -shared -fpic -o libmod1.so mod1.f90
θα την βρει ?

 

 

Αδερφε, κυλισαν δακρυα συγκινησης στο προσωπο μου (ειλικρινα σου λεω). Εχω που ψαχνω τοσες ωρες !!!

Ναι το libmod1.so εκανε ολη τη διαφορα.

 

Μια τελευταια συμβουλη αν ειναι δυνατον.

Ενας φιλος μου εχει 12 αρχεια Fortran. 6 απο αυτα αποτελουν βασικη βιβλιοθηκη (σκοπευουμε να τα κανουμε call και με αλλα scripts), οποτε τα εχουμε σε ενα φακελο πχ /home/foo/Documents/Fortran_library. Εχουμε κι εναν αλλο φακελο με τo main code. Εστω αυτος ο φακελος ειναι στο /home/foo/Desktop/Krusell_algorithm. Στον τελευταιο φακελο εχουμε τα υπολοιπα 6 arxeia. Ενα απο αυτα ειναι το βασικο και κανει call στα υπολοιπα (οπως καταλαβαινεις υπαρχει διασυνδεση ολων των αρχειων).

 

Κανουμε ολη αυτη τη διαδικασια γιατι μπορεσα να κατεβασω την ιντελ φορτραν διχως να πληρωσω (ειναι free για Λινουξ, και ξερουμε οτι ειναι γρηγοροτερη απο τη gfortran). O φιλος δεν εχει δουλεψει με Λινουξ στο παρελθον. Οποτε αν καταφερουμε να κανουμε το προγραμμα να τρεξει με ιντελ φορτραν θα ειναι μεγαλο επιτευγμα.

 

Με βαση το απλο παραδειγμα σκεφτομαι να γραψω τον εξης κωδικα:

cd /home/foo/Documents/Fortran_library
gfortran -shared -fpic -o libinterpol.so  Interpol.f90
gfortran -shared -fpic -o libnumerical.so numerical.f90
gfortran -shared -fpic -o libtauchen.so tauchen.f90
gfortran -shared -fpic -o libmatrix.so matrix.f90
gfortran -shared -fpic -o libdistribution.so distribution.f90
gfortran -shared -fpic -o libnormalcdf.so normalcdf.f90

cd
cd /home/foo/Desktop/Krusell_algorithm

gfortran -I/home/foo/Documents/Fortran_library -L/home/foo/Documents/Fortran_library KS.f90 Value.f90 valuemul.f90 Ols.f90 updating.f90 outerloop.f90 -linterpol -lnumerical -ltauchen -lmatrix -ldistribution -lnormalcd -o Krusell_algo

export LD_LIBRARY_PATH=/home/foo/Documents/Fortran_library:$LD_LIBRARY_PATH

./Krusell_algo

Με ανησυχεί το τελευταίο βήμα επειδή όπως βλέπεις υπάρχουν πολλά αρχεία. Δεν ξέρω καν αν αυτό που γράφω έχει λογική. Πολύ φοβάμαι δε ότι η σειρά που βάζω τα αρχεία παίζει καθοριστικό χαρακτήρα.

 

Update: Η παραπάνω διαδικασία λειτουργεί για τη gfortran, αλλά δημιουργεί μια πλειάδα προβλημάτων όταν χρησιμοποιώ ifort αντι για gfortran.

Επεξ/σία από Eru Iluvatar
Δημοσ.

Μπορείς να διαβάσεις το manpage του intel compiler για να δεις αν χειρίζεται κάτι διαφορετικά. Δεν τον έχω χρησιμοποιήσει ποτέ. Ο κώδικας με τον gfortran πάντως μπορεί να απλοποιηθεί όπως φαίνεται παρακάτω (να δημιουργηθεί μόνο μία βιβλιοθήκη).

 

cd /home/foo/Documents/Fortran_library
gfortran -shared -fpic -o libmyfl.so  Interpol.f90 numerical.f90 tauchen.f90 matrix.f90 distribution.f90 normalcdf.f90
cd /home/foo/Desktop/Krusell_algorithm
gfortran -I/home/foo/Documents/Fortran_library -L/home/foo/Documents/Fortran_library KS.f90 Value.f90 valuemul.f90 Ols.f90 updating.f90 outerloop.f90 -lmyfl -o Krusell_algo
./Krusell_algo
Δημοσ.

Μπορείς να διαβάσεις το manpage του intel compiler για να δεις αν χειρίζεται κάτι διαφορετικά. Δεν τον έχω χρησιμοποιήσει ποτέ. Ο κώδικας με τον gfortran πάντως μπορεί να απλοποιηθεί όπως φαίνεται παρακάτω (να δημιουργηθεί μόνο μία βιβλιοθήκη).

 

cd /home/foo/Documents/Fortran_library
gfortran -shared -fpic -o libmyfl.so  Interpol.f90 numerical.f90 tauchen.f90 matrix.f90 distribution.f90 normalcdf.f90
cd /home/foo/Desktop/Krusell_algorithm
gfortran -I/home/foo/Documents/Fortran_library -L/home/foo/Documents/Fortran_library KS.f90 Value.f90 valuemul.f90 Ols.f90 updating.f90 outerloop.f90 -lmyfl -o Krusell_algo
./Krusell_algo

 

 

Ευχαριστω πολυ!!! Πραγματικα ηθελα να το ρωτησω αυτο, πως δηλαδη να το βαλω σε μια μονο shared βιβλιοθηκη.

 

Καναμε προοδο με την intel fortran. Στο τελευταιο βημα ομως βγαζει αυτο το λαθος:

forrtl: severe (174): SIGSEGV, segmentation fault occurred
Image              PC        Routine            Line        Source             
Krusell_algo       08052091  Unknown               Unknown  Unknown
Krusell_algo       0804998D  Unknown               Unknown  Unknown
Krusell_algo       08048D04  Unknown               Unknown  Unknown
libc.so.6          404C8935  Unknown               Unknown  Unknown

Δοκίμασα επίσης ulimit -s unlimited με sudo και ακόμα στο bashcr, αλλά τίποτα. Τι λες να συμβαίνει. Λες να χρειάζεται να αλλάξει τον κωδικά του;

Δημιουργήστε ένα λογαριασμό ή συνδεθείτε για να σχολιάσετε

Πρέπει να είστε μέλος για να αφήσετε σχόλιο

Δημιουργία λογαριασμού

Εγγραφείτε με νέο λογαριασμό στην κοινότητα μας. Είναι πανεύκολο!

Δημιουργία νέου λογαριασμού

Σύνδεση

Έχετε ήδη λογαριασμό; Συνδεθείτε εδώ.

Συνδεθείτε τώρα
  • Δημιουργία νέου...