From: Jason Blevins on
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
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
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
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
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
 |  Next  |  Last
Pages: 1 2 3 4 5
Prev: Do Loops
Next: Usage of iso_c_binding