Prev: Do Loops
Next: Usage of iso_c_binding
From: Uno on 12 Apr 2010 21:24 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 12 Apr 2010 21:43 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 12 Apr 2010 22:03 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 16 Apr 2010 02:44 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 16 Apr 2010 11:59
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 |