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

LNK2001 error from old Compaq Visual Fortran Code

Chris_H_4
Beginner
2,266 Views

Hi,

I have searched around this issue quite a lot but non of the suggestions seem to solve my problem. I am evaluating whether some old Compaq Visual Fortran code that we have can be built in Intel Visual Fortran on VS2013. The project loads and VF seems to understand the project structure however when I build it I get a lot of LNK2001 errors and a LNK1120: 117 unresolved externals. The project builds a DLL from Fortran routines

The project has a DEF file

LIBRARY XXSUBS
EXPORTS
  ASBEEP
  ASCURS
  ASCOL
  ASGET
...

Some of these routines are Fortran subroutines and some are ENTRY's in other subroutines

ENTRY ASGET (IFLD, MAXLEN, LENC, CHARS)

 

All the code seems to compile OK but I am at a loss as to why I get the Linker errors when as far as I can see all the Exported routines in the DEF file seem to have built and be available to the linker. Any ideas?

0 Kudos
1 Solution
Steven_L_Intel1
Employee
2,266 Views

Ok, that helps. I'm a bit puzzled you didn't see this before, maybe the linker got more picky.

Both Intel Fortran and CVF would generate two symbol names for STDCALL procedures, one with the @n suffix and one without. This allowed you to pass a procedure declared EXTERNAL without needing to know the signature.

My first suggestion is to not use the DEF file but to add !DEC$ ATTRIBUTES DLLEXPORT :: xxx directives to each routine you want to export. My second suggestion is to ask if you need these routines to be STDCALL and, if not, change the calling convention property back to Default. A third suggestion would be to add the @n suffixes to the DEF file, though I am not sure if this works.

View solution in original post

0 Kudos
5 Replies
Steven_L_Intel1
Employee
2,266 Views

It would help if you showed a sample of the linker errors. Do you have the Fortran > External Procedures > Calling Convention set to CVF? There could be a mismatch between STDCALL and C conventions.

0 Kudos
mecej4
Honored Contributor III
2,266 Views

Please post at least a few of the linker error messages verbatim. In particular, we need to see the names of the missing external symbols. It is possible that there is a clash between STDCALL and CREF symbol decorations.

If you built from Visual Studio, there will be a build log file containing all the needed information. Simply zip it and attach the zip to your reply.

0 Kudos
Chris_H_4
Beginner
2,266 Views

Thanks for the quick replies. Steve, I didn't have Fortran > External Procedures > Calling Convention set to CVF but I do now and I get some warnings as well as the linker error. I have been playing with a small project which just has one .FOR and one .DEF, attached

here is the build Log from the small project with Calling Convention set to CVF

Deleting intermediate files and output files for project 'YDABGE', configuration 'Debug|Win32'.
Compiling with Intel(R) Visual Fortran Compiler 16.0 [IA-32]...
ifort /nologo /debug:full /Od /I"../../../../Source/Fortran/Includes" /DYDABGE /d_lines /Qsave /iface:cvf /iface:nomixed_str_len_arg /module:"Debug/" /object:"Debug/" /Fd"Debug\vc120.pdb" /traceback /libs:static /threads /dbglibs /c /dll /Qlocation,link,"D:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\\bin" "D:\_work\CAPS\CAPS\Source\Fortran\CAPS\YDABGE.FOR"
Linking...
Link /OUT:"..\..\..\..\Library\YDABGE.dll" /INCREMENTAL:NO /NOLOGO /DEF:".\YDABGE.DEF" /MANIFEST /MANIFESTFILE:"Debug\YDABGE.dll.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"..\..\..\..\Library/YDABGE.pdb" /SUBSYSTEM:WINDOWS /IMPLIB:"..\..\..\..\Library\YDABGE.lib" /DLL kernel32.lib /MACHINE:I386 "Debug/YDABGE.obj"
ipo: warning #11082: D:\_work\CAPS\CAPS\Projects\Fortran\Modules\YDABGE\Debug/YDABGE.obj: locally defined symbol __imp__XXPFIL imported
YDABGE.DEF : warning LNK4022: cannot find unique match for symbol 'YDABGE'
YDABGE.DEF : warning LNK4002: _YDABGE defined in Debug/YDABGE.obj
YDABGE.DEF : warning LNK4002: _YDABGE@28 defined in Debug/YDABGE.obj
YDABGE.DEF : error LNK2001: unresolved external symbol YDABGE
..\..\..\..\Library\YDABGE.lib : fatal error LNK1120: 1 unresolved externals

 

OK it wouldn't let me attach the .DEF but it looks like this

LIBRARY YDABGE
EXPORTS
  YDABGE

 

I appreciate the help, I am probably not going to be able to respond until Monday but thanks again for the input

0 Kudos
Steven_L_Intel1
Employee
2,267 Views

Ok, that helps. I'm a bit puzzled you didn't see this before, maybe the linker got more picky.

Both Intel Fortran and CVF would generate two symbol names for STDCALL procedures, one with the @n suffix and one without. This allowed you to pass a procedure declared EXTERNAL without needing to know the signature.

My first suggestion is to not use the DEF file but to add !DEC$ ATTRIBUTES DLLEXPORT :: xxx directives to each routine you want to export. My second suggestion is to ask if you need these routines to be STDCALL and, if not, change the calling convention property back to Default. A third suggestion would be to add the @n suffixes to the DEF file, though I am not sure if this works.

0 Kudos
Chris_H_4
Beginner
2,266 Views

Tried various combinations of the above and eventually got the linker to complain that it could not find some referenced libraries so I fixed the linker path and additional libraries and it worked, so I wound back to the original code/config (plus additional libs) and that worked too.

Thanks for the help, problem solved.

0 Kudos
Reply