From: Uno on
jwm wrote:
> On Apr 11, 10:09 pm, Uno <merrilljen...(a)q.com> wrote:

[snipped and re-ordered, for thematic reasons]

> Are you unable to combine all that's been said in this thread? That
> is, use the -L switch to add a non-standard search parth to the
> linker, AND ALSO take care of the order of dependencies:
>
> $ gfortran -L./lib blev1.f90 -lposix90

Did I miss a post about the order of dependencies? When I have to take
muscle relaxants and pain pills for a spasming back, my sight goes all
to heck.
>
> The dependencies work from left to right. So if the file blev1.f90
> has undefined references, the linker will look for them in the next
> item listed (-lposix90). If there were undefined references for -
> lposix90, the linker would look for them in an item listed next to it
> (not the current case, but I mention it as an example). Such
> dependency order is only required for (ungrouped) static libraries.

What would I need to do to make it dynamically-linked?

>> $ gfortran -o out5 -L. -lposix90 blev1.f90
>> /usr/bin/ld: cannot find -lposix90
>> collect2: ld returned 1 exit status
>> $ gfortran -o out5 -L./lib -lposix90 blev1.f90
>> /tmp/cc2qzjxS.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
>> $

Can someone say a few words about what is/is not happening here, in
particular, what the .text + 42 lines mean and why there are undefined
references in something that has MOD in the middle of it.

Thanks for your comment, and cheers,
--
Uno
From: Uno on
FX wrote:
>> $ gfortran -o out3 -Llib -lposix90 blev1.f90
>
> What about:
>
> $ gfortran -o out3 blev1.f90 -Llib -lposix90
>

Oui, cela fonctionne, Fran�ois-Xavier.

Qu'est-ce que je dois faire pour en faire une biblioth�que li�e
dynamiquement?
--
Uno
From: Richard Maine on
Uno <merrilljensen(a)q.com> wrote:

> >> $ gfortran -o out5 -L. -lposix90 blev1.f90
> >> /usr/bin/ld: cannot find -lposix90
> >> collect2: ld returned 1 exit status
> >> $ gfortran -o out5 -L./lib -lposix90 blev1.f90
> >> /tmp/cc2qzjxS.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
> >> $
>
> Can someone say a few words about what is/is not happening here, in
> particular, what the .text + 42 lines mean and why there are undefined
> references in something that has MOD in the middle of it.

The .text+ bits are showing where the reference is in the object code.
The exact location is pretty much meaningless to you unless you are into
reading assembly code; about all of that part that is useful is that th
ereference is from the source file blev1.f90, which you probably knew
already.

I'd have thought the things with MOD in the middle shouldn't be that
hard to decode with a source file as short as this one. You presumably
can see in the source file that it references, for example, a procedure
named opendir from a module named f90_unix_dirent. One might well not
understand the details of why the name ends up looking exactly like
__f90_unix_direct_MOD_opendir, but I would hope that it would be evident
that there was a connection. Anyway, to try to explain...

Realize first that these messages are from the linker, which doesn't
know anything about Fortran. In particular, it doesn't know about
Fortran modules. Combine that with an important fact about Fortran
modules - a single program can have multiple modules with different
procedures having the same name. Your short sample probably has only one
procedure named opendir - the one in module f90_unix_dirent, but it
would be valid to also have some other module with a different procedure
also named opendir. The compiler has to present things to the linker in
a way that this would all work, even though the linker doesn't know
about modules. The way the compiler does this is by internally
generating a link name that combines both the procedure name and the
module name. That generated name will always be unique within a program.
The uppercase MOD in the middle ensures that the generated name cannot
clash with any external (i.e. non-module) procedure name. That's because
the linker name used for an external procedure name is always lower
case, regardless of the case used in the source code (recall that
Fortran names are case insensitive).

This kind of thing is generally referred to as name mangling.

The leading underscores avoid potential conflicts with the names of
things in the system C libraries. The user is not supposed to have to
worry about the possibility of such conflicts; it is part of the
compiler's job to make sure that they don't happen, and the leading
underscores help with that. I have run into isolated cases of compilers
that don't do that. It is quite annoying when you are porting a library
that you have been supporting for a decade or so and find out that one
of your widely used routines, documented in your user interface,
irreconcilably conflicts with an important system routine. Been there;
done that. That was back in the days when my code was in f77, with
remnants from f66 even, so names had to be shorter and the chances of
conflict were much larger, particularly if you tried to use meaningful,
readable names. When I originally chose the names, fopen and fseek,
among others, had seemed like good choices; it was long enough ago that
while C did exist, it wasn't anything that I was much aware of or had
access to.

Be aware that the details can and do vary among compilers. None of this
is specified in the standard. Compilers are just supposed to come up
with a way to make the Fortran code work. Most f90 compilers use a
scheme at least recognizably simillar to this, but the exact details of
the spelling vary. For example, NAG at least used to use something like
MP (for module procedure) where gfortran apparently uses _MOD_.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: Uno on
Richard Maine wrote:
> Uno <merrilljensen(a)q.com> wrote:
>

> The .text+ bits are showing where the reference is in the object code.
> The exact location is pretty much meaningless to you unless you are into
> reading assembly code; about all of that part that is useful is that th
> ereference is from the source file blev1.f90, which you probably knew
> already.
>

No, I didn't *know* this, hence the question. When things aren't
working for mysterious reasons, it throws what seems common sensical
into question as well.
> I'd have thought the things with MOD in the middle shouldn't be that
> hard to decode with a source file as short as this one. You presumably
> can see in the source file that it references, for example, a procedure
> named opendir from a module named f90_unix_dirent. One might well not
> understand the details of why the name ends up looking exactly like
> __f90_unix_direct_MOD_opendir, but I would hope that it would be evident
> that there was a connection. Anyway, to try to explain...

$ gfortran -c -o blev2.o blev2.f90 -Llib -lposix90

$ nm blev2.o
00000000 T MAIN__
U __f90_unix_dirent_MOD_closedir
U __f90_unix_dirent_MOD_opendir
U __f90_unix_dirent_MOD_readdir
U _gfortran_set_options
U _gfortran_st_write
U _gfortran_st_write_done
U _gfortran_transfer_character
00000000 r options.0.546
$ gfortran -o out6 blev2.o -Llib -lposix90
$ ./out6
text3
blev1.f90
blev2.f90~
...
$ nm -l blev2.o
00000000 T MAIN__
U __f90_unix_dirent_MOD_closedir blev2.f90:0
U __f90_unix_dirent_MOD_opendir blev2.f90:0
U __f90_unix_dirent_MOD_readdir blev2.f90:0
U _gfortran_set_options blev2.f90:0
U _gfortran_st_write blev2.f90:0
U _gfortran_st_write_done blev2.f90:0
U _gfortran_transfer_character blev2.f90:0
00000000 r options.0.546

So I tried to go in and verify what Richard says, and I'm a little
disappointed that I couldn't get the text + x numbers to show.

q1) Is nm the right command to see the text + 3c as in the following:

>> >> blev1.f90:(.text+0x3c): undefined reference to
>> >> `__f90_unix_dirent_MOD_opendir'


> Realize first that these messages are from the linker, which doesn't
> know anything about Fortran. In particular, it doesn't know about
> Fortran modules. Combine that with an important fact about Fortran
> modules - a single program can have multiple modules with different
> procedures having the same name. Your short sample probably has only one
> procedure named opendir - the one in module f90_unix_dirent, but it
> would be valid to also have some other module with a different procedure
> also named opendir. The compiler has to present things to the linker in
> a way that this would all work, even though the linker doesn't know
> about modules. The way the compiler does this is by internally
> generating a link name that combines both the procedure name and the
> module name. That generated name will always be unique within a program.
> The uppercase MOD in the middle ensures that the generated name cannot
> clash with any external (i.e. non-module) procedure name. That's because
> the linker name used for an external procedure name is always lower
> case, regardless of the case used in the source code (recall that
> Fortran names are case insensitive).

ok
>
> This kind of thing is generally referred to as name mangling.
>
> The leading underscores avoid potential conflicts with the names of
> things in the system C libraries. The user is not supposed to have to
> worry about the possibility of such conflicts; it is part of the
> compiler's job to make sure that they don't happen, and the leading
> underscores help with that. I have run into isolated cases of compilers
> that don't do that. It is quite annoying when you are porting a library
> that you have been supporting for a decade or so and find out that one
> of your widely used routines, documented in your user interface,
> irreconcilably conflicts with an important system routine. Been there;
> done that. That was back in the days when my code was in f77, with
> remnants from f66 even, so names had to be shorter and the chances of
> conflict were much larger, particularly if you tried to use meaningful,
> readable names. When I originally chose the names, fopen and fseek,
> among others, had seemed like good choices; it was long enough ago that
> while C did exist, it wasn't anything that I was much aware of or had
> access to.
>
> Be aware that the details can and do vary among compilers. None of this
> is specified in the standard. Compilers are just supposed to come up
> with a way to make the Fortran code work. Most f90 compilers use a
> scheme at least recognizably simillar to this, but the exact details of
> the spelling vary. For example, NAG at least used to use something like
> MP (for module procedure) where gfortran apparently uses _MOD_.
>

Alright, thx Richard, I'm certain I've never read the above material on
the fortran linker before. In particular, I wouldn't have guessed that
the standard doesn't prattle on forever about linking modules and
instead says nothing at all.
--
Uno
From: Richard Maine on
Uno <merrilljensen(a)q.com> wrote:

> In particular, I wouldn't have guessed that
> the standard doesn't prattle on forever about linking modules and
> instead says nothing at all.

The Fortran standard doesn't say anything about linking at all (unless
perhaps there is some small side mention in a note somewhere, but notes
are not strictly speaking part of the standard specification; they just
are attempts at clarification or explanation.)

In fact, the standard doesn't even say anything about compilation
either. The standard just talks about there being a "processor," which
is a bit unfortunate terminology, as the word has gathered more specific
meaning in other contexts. In standard-speak, processor just means
something like "whatever it takes to make the Fortran code run." (Those
are my words rather than the standard's, but they aren't that far off).

A processor doesn't have to involve compilation. I believe I recall that
Fortran interpreters (as opposed to compilers) have existed. It doesn't
even strictly have to involve computers. One could make the argument
that a roomful of grad students with paper and pencils could constitute
a standard conforming implementation of a Fortran processor...albeit
probably not a very "user friendly" one if you made them do that for
very long. :-)

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
First  |  Prev  | 
Pages: 1 2 3 4 5
Prev: Do Loops
Next: Usage of iso_c_binding