Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

Using module functions....

Intel_C_Intel
Employee
984 Views
In 'Library A' I have a module that CONTAINS some functions. Also in 'LibraryA' I have 'FunctionB'. Library A compiles correctly and the MOD file is copied to a common include location.
Now, in 'Library B' I have some code that is USEing my module, but also calls 'FunctionB'.
Linkinggives me unresolved externals from my module OBJECT file to functions CONTAINed within the module.
Why? Do I need an interface?
0 Kudos
18 Replies
wkramer
Beginner
984 Views
Have you tried to build the project again (not a rebuild all) after the initial failed build.
The initial build will create the *.mod file and the second build will find the *.mod file from the previous build. Not very elegant, but it works. I think this issue has been resolved with the current intel compiler.
Walter
0 Kudos
Intel_C_Intel
Employee
984 Views
Yes I have tried rebuilding...I've also set my project dependencies to ensure that the .mod file is produced before anything tries to USE it.
0 Kudos
Intel_C_Intel
Employee
984 Views
Does module.obj serve any purpose? Presumably I really only need module.mod?
0 Kudos
wkramer
Beginner
984 Views
Sorry, I misunderstood.
If libraryB builds correctly there is probably no problem with the *.mod files of libraryA. But are both libraries visible for the application that links against these libraries? Have you added both *.lib files to the project (as you would source code files) and did you add the locations where the *.mod files are situated to INCLUDE and USE paths under Project Settings|Fortran|Preprocessor?
Walter
0 Kudos
Steven_L_Intel1
Employee
984 Views
You need the .obj. This contains any routine code, variables, and the values of some PARAMETER constants, plus any initializers specified in derived type declarations.
0 Kudos
wkramer
Beginner
984 Views
Are the module.obj files for modules contained in a static library always required during build of a project that is linked against the library?
I have just deleted the *.obj files from the include and use path, but my application linked without any problem (using cvf for this issue)
Walter
0 Kudos
Intel_C_Intel
Employee
984 Views
I guess I wasn't too clear either! :smileyhappy:
Both libraries compile and link fine. I get the error when I'm trying to link the main EXE. All includes, lib file references etc are correct. I can make the EXE link properly simply by removing references to FunctionB from LibraryB.
To be more explicit:
FunctionB is in LibraryA and USEs the module, alsoin LibraryA.
A routine in LibraryB calls FunctionB and this causes the problem.

Message Edited by judd on 07-21-2005 05:23 PM

0 Kudos
wkramer
Beginner
984 Views
Have you tried to link against libraryA in a simple main EXE and call FunctionB directly from the EXE?
Walter
0 Kudos
Intel_C_Intel
Employee
984 Views
I tried that Walter, thanks for the suggestion.
However, I get the same unresolved externals.
It probably stems from the way I'm using the MODULE, which I guessing doesn't follow best practices.
My module is not 'standalone' - it links a large common block from my main executable and the functions it CONTAINs call other functions from other libraries in my main exe.
It all gets a bit incestuous I'm afraid - I may have to try and untangle it a bit.

Message Edited by judd on 07-22-2005 11:23 AM

0 Kudos
Intel_C_Intel
Employee
984 Views
Steve,
Would any problems arise from a CONTAINed function in a MODULE calling another CONTAINed function in the same MODULE?
Dan
0 Kudos
Intel_C_Intel
Employee
984 Views
The actual error I get is:
Code:
Instrument.lib(LinkedList.obj) : error LNK2001: unresolved external symbol _LL_GETNEXTENTRY@8
Instrument.lib(LinkedList.obj) : error LNK2001: unresolved external symbol _LL_GETPREVENTRY@8
Instrument.lib is the static library that contains the MODULE, which is defined in LinkedList.for. LL_GetNextEntry and LL_GetPrevEntry are functions contained in the MODULE.
I'd like to get to the bottom of this, otherwise I'll have to re-write a few functions that already exist - and that seems dumb...
0 Kudos
Intel_C_Intel
Employee
984 Views
OK...sorry for all the posts...I've SOLVED IT! Hurrah!
Simply a case of adding the following aliases to the 'problem' functions CONTAINed in the MODULE:
!DEC$ATTRIBUTES ALIAS:'_LL_GETNEXTENTRY@8' :: LL_GetNextEntry
!DEC$ATTRIBUTES ALIAS:'_LL_GETPREVENTRY@8' :: LL_GetPrevEntry
Any ideas why this was necessary though?
Dan
0 Kudos
Steven_L_Intel1
Employee
984 Views
Module procedures have their own name decoration convention, of the form MODNAME_mp_ROUTINENAME
0 Kudos
Intel_C_Intel
Employee
984 Views
Can you actually call them using that convention Steve?
0 Kudos
Steven_L_Intel1
Employee
984 Views
Sure. It's even documented in the manual. Apply usual name decoration conventions (leading underscore, etc.)
0 Kudos
Jugoslav_Dujic
Valued Contributor II
984 Views
Still, there's something fishy. ALIAS cures the symptoms, but it's seldom necessary for pure Fortran projects (and this is not one of the cases). If aroutine Foo is CONTAINed in a MODULE Bar, it should never be referenced by _FOO@8, but only as _BAR_mp_FOO@8. Thus, the linker error you posted should never have emerged, especially because it points to the source file containing the module itself.
1) Are you positive that these two LL_ functions are CONTAINed within the module?
2) Are you sure you don't have a redeclaration of LL's within the module? If you have an EXTERNAL LL_WHATEVER, or INTEGER LL_WHATEVER, or INTERFACE declarationsomewhere within the module, that effectively declares that you're calling a function outside of the module, not the CONTAINed one. You should remove these.
Did you try the simpler case of putting everything in a single project instead of compiling the library first?
Jugoslav
0 Kudos
jim_dempsey
Beginner
984 Views
Judd,
Try the following:
In the project file that includes your main add a dummy subroutine that uses both LibraryA and LibraryB as well as calls LibraryA::FunctionB. (i.e. force an explicit reference)
Also, in the project for your main module open the Properties page and look at Linker | Input. Make sure your .lib file (files) is (are) included as input.
Jim Dempsey
0 Kudos
Intel_C_Intel
Employee
984 Views
Jugoslav - you hit the nail on the head!
Those two CONTAINed LL_ functions are called by the other CONTAINed LL_ functions and in each function I had included a function declaration (i.e., INTEGER*4 LL_ ...) and since the compiler and linker gave no errors I assumed everything was OK.
I've removed them and managed to get rid of the ALIASes.
Cheers,
Dan
0 Kudos
Reply