forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Linking order of object files

 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support
View previous topic :: View next topic  
Author Message
StamK



Joined: 12 Oct 2016
Posts: 159

PostPosted: Sat Mar 16, 2024 3:07 pm    Post subject: Linking order of object files Reply with quote

Is FTN95 the only linker where the order of the object files is not important? It seems that in Gfortran if they are not put in the correct dependency order, then it will throw up undefined reference errors.
The issue if that if there is not a clear dependency order (i.e. file A containing a subroutine S1 calling S2 from file B and file B containing S3 calling S1), then Gfortran will fail (perhaps there is a workaround though, need to investigate).
Has anyone got the same issue when linking code compatible with both FTN95 and Gfortran?
Thanks
Back to top
View user's profile Send private message
wahorger



Joined: 13 Oct 2014
Posts: 1217
Location: Morrison, CO, USA

PostPosted: Sat Mar 16, 2024 8:34 pm    Post subject: Reply with quote

This is my experience.

If you simply LOAD multiple objects (.OBJ files), then dependency matters; that is, if you don't express them in order, then they will not resolve references, and you're left with errors. On the other hand, building a library (32-bit SLIM) and specifying that as linker input , then it will satisfy as many references as it can (iterative processing of the library ). If there are still unresolved references, then the next library will be scanned and processed, etc. In other words, if you can build a library, it is better than simply loading .OBJ files.

In my system, I build a library of the hundreds of files containing many more hundreds of functions/subroutines. I link with the MAIN (and perhaps other needed extra routines), then specify the library (.LIB file) to be used.
Back to top
View user's profile Send private message Visit poster's website
StamK



Joined: 12 Oct 2016
Posts: 159

PostPosted: Sat Mar 16, 2024 9:17 pm    Post subject: Reply with quote

Thanks for the reply, but I don't quite understand. Are you saying that you are building a .LIB file first?
I was saying that with SLINK64 (or SLINK) I never have any issues with undefined references due to the order of the obj files (in this case I am creating a DLL), while in Gfortran it fails to do so unless they are in the correct dependency order when linking (but there is cyclic dependency so cannot do that).
Back to top
View user's profile Send private message
wahorger



Joined: 13 Oct 2014
Posts: 1217
Location: Morrison, CO, USA

PostPosted: Sat Mar 16, 2024 9:31 pm    Post subject: Reply with quote

Are you building a library with Gfortran, or just putting objects?

If the former, then you might be able to put the same library in twice, catching the cyclic dependencies.

SLINK (and SLIM) seem to do exactly what would be expected of them; that is, they produce a library that can be iteratively searched for unresolved references until there are no more, then move along to the next library/object/DLL.

My experience is that most linkers work this way with libraries. If Gfortran does not, perhaps it is an outlier(?).
Back to top
View user's profile Send private message Visit poster's website
StamK



Joined: 12 Oct 2016
Posts: 159

PostPosted: Sat Mar 16, 2024 10:35 pm    Post subject: Reply with quote

I am building a DLL file with a series of object files (.o in Gfortran or .obj in Silverfrost). I cannot put the same object more than once as it will complain that a function is already defined.
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sun Mar 17, 2024 2:14 am    Post subject: Reply with quote

I have not utilised .dll files and since converting to FTN95 /64 Ver 8.0, I have stoped using .lib files, but using a long list of "lo ..\lib64\xxlib\aaa.obj" files with "slink64 @saplot_load.txt >> ftn95.tce"
I do the same with Gfortran

This has the advantage in that if a .obj file is not loaded, I add it to the list. The disadvantage is that unnecessary .obj files are not identified, as all LO xx.obj are included in the build, even if not required.

Since slink64 was enhanced to use libraries, I have not updated my approach :-(

I recall that in /32 Slink, "le obj_files.lib" did a multi pass search for unsatisfied routines to complete the build.
But if you had a collection of .lib files, they were not all searched for inter-related routines, so you must organise the entries in libraries and library order.

Surely the same applies for .dll, so you need to plan the order of building a .dll. This should be doable? My lazy approach to loading .obj files removes the problem.

Are there any advantages of .dll's when building a .exe ?

These days, I don't have time to get a coffee when I select "remake.bat" !!
Back to top
View user's profile Send private message
wahorger



Joined: 13 Oct 2014
Posts: 1217
Location: Morrison, CO, USA

PostPosted: Tue Mar 19, 2024 3:46 pm    Post subject: Reply with quote

I just had a hint about objects versus libraries.

File A contains MAIN and SUB_A, in OBJ_A
File B contains SUB_B, in OBJ_B.

SUB_B calls SUB_A. OBJ_B is in a library.

OBJ_A, because it contains the MAIN is loaded as an object.

The link fails because SUB_A is not referenced by MAIN and therefore not useful.

Moving SUB_A to FILE B solves the problem because now SUB_B and SUB_A are part of a library.
Back to top
View user's profile Send private message Visit poster's website
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Wed Mar 20, 2024 4:41 am    Post subject: Reply with quote

Bill, why would main and file A be a library ? They should be loaded from a .obj file.

You say sub_a is not referenced, but if in an .obj it would be in the link list and recognised for le file_b.lib, or any other lo operation. SLINK and SLINK64 should have a symbol list that copes with this.

Also if sub_b in file_b.lib requires sub_a, this is a bad approach to creating a library.

If file_X.lib has unsatisfied routines, they should be provided in subsequent libraries. I would have some libraries that require other utility "system" or "vector" libraries, but all related routines should be in the same library.

With /32 "LE libx.lib" I thought you could have the routines out of order in libx.lib, so if sub_a was stored before sub_b in the same .lib file, SLINK would do a multi scan and find sub_a.

However, it should not be too hard to get a workable order, else you have a recursive code library.

My only question is if SLINK64 supports LE functionality that I described for SLINK.
Back to top
View user's profile Send private message
wahorger



Joined: 13 Oct 2014
Posts: 1217
Location: Morrison, CO, USA

PostPosted: Wed Mar 20, 2024 5:15 am    Post subject: Reply with quote

John, I think you misread.

FILE_A contains MAIN and SUB_A. They get compile into OBJ_A

FILE_B contains SUB_B. It compiles into OBJ_B. This becomes a library.. SUB_B contains a reference to SUB_A.

When the final link is done, one first LOADS OBJ_A. Because (at this point) SUB_A is not referenced, it is discarded from the link and the next file in sequence (a library) is processed. MAIN called SUB_B (it was not obvious in my original post). But now, there is no SUB_A (it was discarded). And there is your unknown reference (SUB_A).

The point is if you simply LOAD an object file, don't count on its components remaining as part of the linking. If they are not referenced (yet) they will be discarded. This goes to StamK's original question/concern.

By the way, although it certainly makes no sense, you CAN put a MAIN program into a library. And, the link will ultimately fail. Due to a manually created error in a MAKE definition, I was able to do this just a few days ago. Makes perfect sense that it makes no sense at all. Yet, you can do it.

The whole point of this is that when you make a library, the library is processed iteratively. So all references that can get resolved will get resolved. Then the linker moves on to the next file/library/DLL and the process (with its rules regarding file types) continues.
Back to top
View user's profile Send private message Visit poster's website
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Wed Mar 20, 2024 12:57 pm    Post subject: Reply with quote

If "FILE_A contains MAIN and SUB_A. They get compile into" OBJ_A.obj

Then, "Because (at this point) SUB_A is not referenced, it is discarded from the link". This does not happen with a .obj file.
It should remain available in the link name table.

Now if SUB_A was in an earlier listed .lib file, it will not be included.

Have you tried this ?
I would be very surprised if this discarding is the case, but I have been surprised before !

When I build my @load.txt file, I don't bother with the call order, but typically do arrange them in some grouping order.

I should revisit SLINK64 and create .lib files for the libraries I once used.
Back to top
View user's profile Send private message
wahorger



Joined: 13 Oct 2014
Posts: 1217
Location: Morrison, CO, USA

PostPosted: Wed Mar 20, 2024 2:08 pm    Post subject: Reply with quote

John, I did precisely this, and was left with an unresolved reference. The reason being that my main (and a subroutine referenced by a library function) were compiled together in one object file (for no other reason than I was lazy). I said my "mea culpa" and moved the subroutine to be with its companion (and in the library) and all was well with the world.

I learned early on that it is best to have very routine EXCEPT the main in a library or DLL and let the linker do what it does best, resolving the references and arranging memory in an orderly fashion.

If, however, I violate that rule and just LOAD object files, sometimes I will be successful, other times, I'll be re-arranging orders of objects trying to get things done in the proper order, usually with poor results.

I place similar function routines or ones that reference the same data into a single file for compilation. This does not lead to very good results simply loading routines object files. Great for building a library, however!

I have also been able to use this feature to force functional "stubs" to be loaded in place of their functional counterparts. I have one program that is not windows (runs in a DOS window) so doesn't need many of the routines specifically written for window/dialog interaction. I have a separate file with the stubs, and LOAD that object file to make the run-time executable considerably smaller.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> Support All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group