Prev: Do Loops
Next: Usage of iso_c_binding
From: Jason Blevins on 9 Apr 2010 00:33 On 2010-04-09, Uno <merrilljensen(a)q.com> wrote: > I've been working through unix material since the beginning of the year. > Until now, I hadn't found a role with fortran in doing so, but that > was before I read Jason Blevins' post on posix fortran. I'm trying to > replicate this material and so far have a huge mess. I'm certain > there's a component of user error here, but that doesn't seem to be the > whole story. > > ... > > So I download the tarball, extract, and put it in a place that makes sense. > > http://savannah.nongnu.org/projects/posix90/ I'm assuming you downloaded the latest tarball marked version 0.4. I actually wasn't able to get that version to build correctly either. I was working with the CVS version which you can obtain as so: $ cvs -z3 -d:pserver:anonymous(a)cvs.savannah.nongnu.org:/sources/posix90 \ co posix90 (I've put in a continuation since it would wrap, but that should all be on one line.) Try installing that version instead. > Neither make nor make install come off cleanly: > > $ make > ... > cc -g -fno-leading-underscore -c -o f90_unix_env_ccode.o > f90_unix_env_ccode.c > f90_unix_env_ccode.c: In function 'c_clk_tck_': > f90_unix_env_ccode.c:32: error: 'CLK_TCK' undeclared (first use in this > function) > f90_unix_env_ccode.c:32: error: (Each undeclared identifier is reported > only once > f90_unix_env_ccode.c:32: error: for each function it appears in.) > f90_unix_env_ccode.c: In function 'c_uname_': > f90_unix_env_ccode.c:125: warning: incompatible implicit declaration of > built-in function 'strncpy' > make[1]: *** [f90_unix_env_ccode.o] Error 1 > ... > q1) How bad and relevant are make's errors to the matter at hand? After the first error, reproduced above, you can be sure the library won't be built correctly since this object file wasn't built. > Make install looks cleaner: > > $ make install > install -d /home/dan/source/posix90/f90/mod > install src/*.mod /home/dan/source/posix90/f90/mod > install -d /home/dan/source/posix90/lib > install src/libposix90.a /home/dan/source/posix90/lib > install: cannot stat `src/libposix90.a': No such file or directory > make: *** [install] Error 1 > ... > q2) How significant are the last 2 lines of output from make install? Very significant. The libposix90.a file is the static library itself--this is the main file you need. It wasn't fully built earlier and so it couldn't be installed. > So compiling, I have: > > $ gfortran -D_GNU_SOURCE -Wall -Wextra blev1.f90 -o out > blev1.f90:6.22: > > integer :: errno, name_len > 1 > Warning: Unused variable 'errno' declared at (1) > /tmp/ccArlpUf.o: In function `MAIN__': > blev1.f90:(.text+0x3c): undefined reference to > `__f90_unix_dirent_MOD_opendir' > blev1.f90:(.text+0x68): undefined reference to > `__f90_unix_dirent_MOD_readdir' > blev1.f90:(.text+0xf3): undefined reference to > `__f90_unix_dirent_MOD_closedir' > collect2: ld returned 1 exit status > $ > > q3) Can someone tell by .text+0x3c where these things are (blev1.f90 is > at the top of this post)? I've read through several modules trying to > find them. I also tried a technique that I'm still pretty shaky with: > > $ grep '^f90_unix_dirent_MOD_opendir' */*.f90 > $ grep '^f90_unix_dirent_MOD_opendir' */*.* > $ grep '^f90_unix_dirent_MOD_opendir' * The compiler 'mangles' the subroutine name opendir and ends up with f90_unix_dirent_MOD_opendir (see http://en.wikipedia.org/wiki/Name_mangling). > q4) If this is a string in a file: > > f90_unix_dirent_MOD_opendir > > , would I have grep'ed correctly for it? You're on the right track. If the library had been built, then f90_unix_dirent_MOD_opendir should appear in there: $ cd src $ grep f90_unix_dirent_MOD_opendir libposix90.a Binary file libposix90.a matches You probably don't want the carat (^) at the beginning since that would match only at the beginning of a line (which is really meaningless for a binary file anyway). For a library or object file, one can use nm to list all of the symbols contained within: $ nm libposix90.a .... 0000000000000126 T __f90_unix_dirent_MOD_opendir .... > Thanks for your comment, and cheers, Cheers, and good luck! -- Jason Blevins Ph.D. Candidate, Department of Economics, Duke University http://jblevins.org/
From: Uno on 9 Apr 2010 04:04 Jason Blevins wrote: > On 2010-04-09, Uno <merrilljensen(a)q.com> wrote: [lots of code, big snips] > I'm assuming you downloaded the latest tarball marked version 0.4. > I actually wasn't able to get that version to build correctly > either. I was working with the CVS version which you can obtain > as so: > > $ cvs -z3 -d:pserver:anonymous(a)cvs.savannah.nongnu.org:/sources/posix90 \ > co posix90 > > (I've put in a continuation since it would wrap, but that should > all be on one line.) Try installing that version instead. cvs seems to have done the trick. > The compiler 'mangles' the subroutine name opendir and ends up > with f90_unix_dirent_MOD_opendir > (see http://en.wikipedia.org/wiki/Name_mangling). ok > You're on the right track. If the library had been built, > then f90_unix_dirent_MOD_opendir should appear in there: > > $ cd src > $ grep f90_unix_dirent_MOD_opendir libposix90.a > Binary file libposix90.a matches > > You probably don't want the carat (^) at the beginning since > that would match only at the beginning of a line (which is > really meaningless for a binary file anyway). > > For a library or object file, one can use nm to list all of > the symbols contained within: > > $ nm libposix90.a > ... > 0000000000000126 T __f90_unix_dirent_MOD_opendir I entered this last part in my linuxlog, the better part of my experience with usenet and linux. I'm close now, but I'm simply out of guesses how to get gfortran to find a library. So I've put the module and the library in the same directory as the caller: $ ls blev1.f90 COPYING examples info libposix90.a README blev1.f90~ CVS f90 INSTALL Makefile src ChangeLog doc f90_unix_dirent.mod lib Makefile~ text1 I can't convince gfortran to link with it: $ gfortran libposix90.a blev1.f90 -o out /tmp/ccYv3yLJ.o: In function `MAIN__': blev1.f90:(.text+0x3c): undefined reference to `__f90_unix_dirent_MOD_opendir' blev1.f90:(.text+0x68): undefined reference to `__f90_unix_dirent_MOD_readdir' blev1.f90:(.text+0xf3): undefined reference to `__f90_unix_dirent_MOD_closedir' collect2: ld returned 1 exit status $ gfortran -l libposix90.a blev1.f90 -o out /usr/bin/ld: cannot find -llibposix90.a collect2: ld returned 1 exit status $ gfortran -llibposix90.a blev1.f90 -o out /usr/bin/ld: cannot find -llibposix90.a collect2: ld returned 1 exit status $ gfortran -l lib blev1.f90 -o out Couldn't find anything relevant in gfortran reference. -- Uno
From: jwm on 9 Apr 2010 05:10 On Apr 9, 2:04 am, Uno <merrilljen...(a)q.com> wrote: > Jason Blevins wrote: > > On 2010-04-09, Uno <merrilljen...(a)q.com> wrote: > > [lots of code, big snips] > > > I'm assuming you downloaded the latest tarball marked version 0.4. > > I actually wasn't able to get that version to build correctly > > either. I was working with the CVS version which you can obtain > > as so: > > > $ cvs -z3 -d:pserver:anonym...(a)cvs.savannah.nongnu.org:/sources/posix90 \ > > co posix90 > > > (I've put in a continuation since it would wrap, but that should > > all be on one line.) Try installing that version instead. > > cvs seems to have done the trick. > > > The compiler 'mangles' the subroutine name opendir and ends up > > with f90_unix_dirent_MOD_opendir > > (seehttp://en.wikipedia.org/wiki/Name_mangling). > > ok > > > > > > > You're on the right track. If the library had been built, > > then f90_unix_dirent_MOD_opendir should appear in there: > > > $ cd src > > $ grep f90_unix_dirent_MOD_opendir libposix90.a > > Binary file libposix90.a matches > > > You probably don't want the carat (^) at the beginning since > > that would match only at the beginning of a line (which is > > really meaningless for a binary file anyway). > > > For a library or object file, one can use nm to list all of > > the symbols contained within: > > > $ nm libposix90.a > > ... > > 0000000000000126 T __f90_unix_dirent_MOD_opendir > > I entered this last part in my linuxlog, the better part of my > experience with usenet and linux. I'm close now, but I'm simply out of > guesses how to get gfortran to find a library. > > So I've put the module and the library in the same directory as the caller: > > $ ls > blev1.f90 COPYING examples info libposix90.a README > blev1.f90~ CVS f90 INSTALL Makefile src > ChangeLog doc f90_unix_dirent.mod lib Makefile~ text1 > > I can't convince gfortran to link with it: > > $ gfortran libposix90.a blev1.f90 -o out > /tmp/ccYv3yLJ.o: In function `MAIN__': > blev1.f90:(.text+0x3c): undefined reference to > `__f90_unix_dirent_MOD_opendir' > blev1.f90:(.text+0x68): undefined reference to > `__f90_unix_dirent_MOD_readdir' > blev1.f90:(.text+0xf3): undefined reference to > `__f90_unix_dirent_MOD_closedir' > collect2: ld returned 1 exit status > $ gfortran -l libposix90.a blev1.f90 -o out > /usr/bin/ld: cannot find -llibposix90.a > collect2: ld returned 1 exit status > $ gfortran -llibposix90.a blev1.f90 -o out > /usr/bin/ld: cannot find -llibposix90.a > collect2: ld returned 1 exit status > $ gfortran -l lib blev1.f90 -o out > > Couldn't find anything relevant in gfortran reference. > -- > Uno Does it work if you change the order?: $ gfortran -o out blev1.f90 libposix90.a or $ gfortran -o out blev1.f90 -lposix90 gfortran only compiles the blev1.f90 file and implicitly invokes the linker (so that's what the reference covers). The linker (ld ), in turn, only checks static libraries once for missing dependencies, from left to right (unless you create a group for the static libraries). Also, the switch -lNAMESPEC usually expands to libNAMESPEC.a (for static libraries). You might want to take a look at ld manpage (especially, the -l, -L -- start-group and --end-group switches) : $ man ld or $info ld
From: Craig Powers on 9 Apr 2010 13:26 Uno wrote: > $ gfortran -llibposix90.a blev1.f90 -o out > /usr/bin/ld: cannot find -llibposix90.a > collect2: ld returned 1 exit status A standard feature of Unix-derived operating systems is that when specifying a library to a compiler via the '-l' switch, the leading 'lib' is omitted (as is the extension). Thus, the correct form of this command line would be, gfortran -lposix90 blev1.f90 -o out (assuming that libposix90.a is in the default library search path for gfortran... if it is and it's not being found, you may wish to try running ldconfig, otherwise you may wish to use the -L switch to instruct gfortran to search in that location in addition to the default search path.)
From: Uno on 10 Apr 2010 17:11
jwm wrote: > Does it work if you change the order?: > > $ gfortran -o out blev1.f90 libposix90.a Thx, jwm, this works. > > or > > $ gfortran -o out blev1.f90 -lposix90 This doesn't. > > gfortran only compiles the blev1.f90 file and implicitly invokes the > linker (so that's what the reference covers). The linker (ld ), in > turn, only checks static libraries once for missing dependencies, from > left to right (unless you create a group for the static libraries). > Also, the switch -lNAMESPEC usually expands to libNAMESPEC.a (for > static libraries). > > You might want to take a look at ld manpage (especially, the -l, -L -- > start-group and --end-group switches) : > > $ man ld > > or > > $info ld I took a look through specifically looking for a switch that would tell me what ld thinks are the default paths. Didn't find it, which makes just another on a heap of failures looking at man pages and walking away empty handed. What I have now compiles, links, and behaves: $ gfortran -o out blev1.f90 libposix90.a $ ./out apue.2e blev1.f90 .... a1.c a1.c~ caller2.f90~ $ ls /home/dan/source 9vx-0.12 blev1.f90~ c_interop.mod jb1.f90 primemover-0.1.5 a1.c caller1.f90 fortran_stuff jb1.f90~ primemover-0.1.5.tar.bz2 a1.c~ caller1.f90~ g1.c out src.tar.gz apue.2e caller2.f90 g1.c~ perl1.pl unleashed backups1 caller2.f90~ g2.c perl1.pl~ blev1.f90 cfunc.o g2.c~ posix90 $ cat blev1.f90 program ls use f90_unix_dirent implicit none type(DIR) :: dirp integer :: errno, name_len character(LEN=128) :: name call opendir('/home/dan/source', dirp) do call readdir(dirp, name, name_len) if (name_len > 0) then print *, name(1:name_len) else exit end if end do call closedir(dirp) end program ls ! gfortran -o out blev1.f90 libposix90.a $ So it's got some refining to do before it looks like the ls that comes out of the box with linux, but I think this is a great start. Thanks all for comments. -- Uno |