- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How can I use a static library in a Intel Fortran Project and at the same time, include some of the library subroutines in other parts of the project with some changes? In other words, in the case that I have two definitions of the same subroutine, How can I ask the program to use the subroutine that is included in the project rather than the same subroutine in the library?
Link Copied
36 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Normally this would "just work". As long as the library routine you are overriding isn't included in the same object module as something else you're pulling in, the linker will ignore the library version. If that's not the case and you're getting linker errors for duplicate definitions, you can add /force:multiple to the Linker > Command Line property page. (Note, Linker, not Fortran).
Does this help? If not, please describe in more detail what you are trying to do and what goes wrong.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have done exactly the same , and got a warnings :
'ATIFLib.lib(AtifM.obj) : warning LNK4006: _CONT510 already defined in Atsurface.obj; second definition ignored'
Debug\Contactone.exe : warning LNK4088: image being generated due to /FORCE option; image may not run
I think this means that IntelFortran did recognize the existence of CONT510 subroutine sharing the same name with the one in the library and the one in the library seems to be replaced with the new one. But it is not the case, cause I wrote a 'pause' in the CONT510 subroutine I have and it was not called , and is still using the one in the library. I hope i made is clear
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Mr. Lionel
I actually came across the same problem and do not know how to solve it. Looking forward to your reply.
Many thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
It is not "Intel Fortran" that is the issue here - it is the linker that resolves references. All of the definitions in your sources would be used before any from the library. If you can construct a case that shows this is not happening, please attach a ZIP of the project that shows this. If you are getting the multiple definition error, then there is a reference in the library that is causing the duplicate name to be pulled in.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Mr. Lionel
The attached please find the .zip file. All the file was created by visual studio 2010 (Parallel Studio XE 2011 with VS2010)
In this folder you could find a project folder called NEWLIBTEST there is a small subroutine 'SUB.for' and the library 'Lib1.lib'. The 'Lib1.lib' was created by 'Source1.for'.
I took the advice that use force option under linker. The results should be 2*5*5=50, but it remains still 7.
Thanks for your help.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mr. Lionel
I have already tested the project that Liang attached and the problem is much clear in this example . It seems that the project recognized that there is two definitions for the ADD subroutine , it is still using the one in the library not the one I added in the project. Your reply will be appreciated
Many Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
In Liang's example, all of the routines in the library are from a single source file, which means they'll all be in a single object module. The main program calls MAINTEST, from the library. When the linker pulls in MAINTEST it also sees ADD in that module and resolves it there, even though there is an ADD in the project.
To fix this, put each of the routines in a separate file - or at least the ones you want to override.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
`Hi
I have did exactly what you recommend ,where i put the ADD subroutine in a separate file . But I still Have the same problem , the project still call the subroutine in the library not the one i added. Could you please check that.
Many Thanks
Ahmed
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Mr. Lionel and Ahmed
I tried to separate the ADD routines from the library which means using two source files to build the library one is source1 and the other is source2. You could find that in the attached file,Ahmed. And now I could replace the ADD using the one in the project.
I also have a question, Mr, Lionel, that the size of the library generated by Intel Fortran is much larger than that created by PowerStation and I don't know why. Thanks for your kind help.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
But I think this property is not quite convenient for our work. Cause every time when we would like to modify a routine in the library we have to separate it from library first and then rebuild the library. Actually in PowerStation we do not have to do such kind of things. We created the library using one source file in Powerstation and the only thing we should do is to use the "force" option under "link" tab and the subroutine in the project will automatically replace the one in the library. I was wondering if IntelFortran could do the same thing. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One possible difference is that the Intel compiler does automatic inlining of procedures in the same source file - this would probably explain the difference.
I can't comment on the size of the library - unless you're comparing a debug build, perhaps.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Liang for your clarification. Exactly Mr Lionel this way of creating the library will not work with us, We would like to have your answer if we could create the library using one source file and enforce the project to use the subroutines I added as user subroutines , as exactly we can do in Power station.
your reply will be appreciated
many Thanks
Ahmed
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>only thing we should do is to use the "force" option under "link" tab and the subroutine in the project will automatically replace the one in the library
This is a Linker issue, not Intel Fortran issue. The linker on Windows is provided by Microsoft.
You might consider using (requiring) your FORTRAN program to use interfaces. Then, in your interface declaration, attribute the conflicting subroutine name to use a different link name
INTERFACE SUBROUTINE happy(i)
!DEC$ ATTRIBUTES STDCALL, DECORATE, ALIAS:'OtherName' :: happy
INTEGER i
END SUBROUTINE
END INTERFACE
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I looked at this closer and do not see any way to prevent ADD from being resolved from the same file where the call was made. This appears to be controlled by the linker - the compiler can't do anything about it. You will have to move ADD to a separate source file. Once you do this, you won't need /force anymore.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Mr. Dempsey
We Do Appreciate your contribution. But could you please explain more what you mean by attribute the conflicting subroutine name to use a different link name. and really it will be very kind from you to look closely at the example we have and apply your solution on it.
Many Thanks
Ahmed
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Compounding the problem here is that the caller of ADD is in the library and in the same source file as ADD.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
From my understanding of your situation you currently have a library where one .obj (of potentially several .obj's in the library) contains multiple functions. One of these functions you wish to replace with other code using the same function name, however, your code is also dependent of other functions contained within the .obj contained in the library containing that .obj and potentially other .obj's. The Linker will load any (but not necessarily all) .obj contained within a library which has a reference made to any of its externals (and which are not already defined).
One way to correct this is to rename your functions (AhmedADD) but this may not be practical or convienent.
A different way is to seperate the sources of the seperate functions such that you compile to seperate .obj files then Lib into one .lib file. And code your replacement function using the same name (ADD). Then let the linker substitute your function for all calls using ADD. This too may be unaccepible when functions contained within the .lib (or elsewhere) need to call the library's version of ADD and not your substitution for ADD.
To resolve this I believe the best way is to declare a generic interface, not normally used to define an internal name for an external subroutine/function
Assume you have
SUBROUTINE ADD(A,B,C)
A = B + C
call TestBounds(A) ! your diagnostic subroutine
END SUBROUTINE ADD
However this name conflicts with a library subroutine name, now you want to selectively use (replace) the call to the library ADD with a call to your ADD.
! SubstituteFunctions.f90
MODULE SubstituteFunctions
INTERFACE ADD
SUBROUTINE AhmedADD(A, B, C)
REAL :: A, B, C
END SUBROUTINE AhmedADD
END INTERFACE
... ! Other subroutine/functions follow
END MODULE SubstituteFunctions
--------------------------
! YourCode.f90
SUBROUTINE YourCode(...
USE SubstituteFunctions
...
CALL ADD(SUM, X, Y)
...
END SUBROUTINE YourCode
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I forgot to mention, it is assumed you will supply "AhmedADD.f90" with the appropriate subroutine.
>>Compounding the problem here is that the caller of ADD is in the library and in the same source file as ADD.
Then this clearly calls for the replacement of the contents of ADD or seperation of ADD into seperate source.
An alternate way might be to use a procedure pointer that is initialized to the .LIB ADD routine but reset to the alternate routine.
The procedure pointer could be declared as ADD in the module but not given EXTERNAL attribute. Then only subroutine/function USEing the module would reference the module declared ADD procedure pointer as opposed to the library EXTERNAL ADD subroutine/function.
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Why won't this work?
1) Put the subroutine ADD that you really want to invoke in a module.
2) USE the module in the program unit where you really want to invoke it.
3) Give the subroutine a different linker name with !DEC$ ATTRIBUTES ALIAS
Even step 3 above seems unnecessary because a module procedure already has a different linker name.
If the module won't be available at the time the prospective caller is compiled, you could still write out an interface block with a different linker name as specified in 3 above. I don't think you are reduced to LoadLibrary/GetProcAddress/C_F_PROCPOINTER to get this to work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi, Mr. Lionel
To separate the subroutines into a different source file did work for our examples, but when the library containing thousands routines that calling each other the we could not separate each calling statement and each subroutine. So, I was wondering if there is any settings that we could do in the linking part to overcome this problem. Thanks for your answer.
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page