Link VS2008 to 2 external libraries

Link VS2008 to 2 external libraries

Dumb problem/question:  Using Visual Studio 2008 and Intel VF 11.1, I'm trying to link 2 external static fortran libraries to my fortran program, unsuccessfully at this point.

I'm specifying the libraries path under    Properties -> Linker -> General -> Additional Library Directories -> F:\folder\subfolder

I've tried to specify the libraries in that folder under Properties -> Linker -> Input -> Additional Dependencies -> name1.lib, name2.lib

What should I be doing?  Thanks for any suggestions!

35 posts / 0 nouveau(x)
Dernière contribution
Reportez-vous à notre Notice d'optimisation pour plus d'informations sur les choix et l'optimisation des performances dans les produits logiciels Intel.

If they are bespoke libaries you might want to consider just adding them to the project , Menu "project", "add existing item" then there is no ambiguity.

If you look under project, properies, linker, command line  you should see the libraries are included in the link command.

What error messages did the linker give you? Did it not find the specified libraries, or did it flag unsatisfied externals?

"trying to link unsuccessfully" is not of much help, if we do not know what you tried. The title of the thread is a bit misleading, since you are using VS2008 to link, rather than linking VS2008 itself.

Citation :

mecej4 a écrit :
What error messages did the linker give you? Did it not find the specified libraries, or did it flag unsatisfied externals?

The subrountines that are part of the needed library, each products a typical message such as "... error LNK2019: unresolved external symbol FMSINI referenced in function MAIN__"

Output from the build is as follows:

Compiling with Intel(R) Visual Fortran 11.1.051 [Intel(R) 64]... ifort /nologo /module:"x64\Release\\" /object:"x64\Release\\" /libs:static /threads /c /extfor:f /Qvc9 /Qlocation,link,"D:\Program Files (x86)\Microsoft Visual Studio 9.0\VC\bin\amd64" "F:\FMS1\Source Files\mode2_code.f"
Linking... Link /OUT:"x64\Release\FMS1.exe" /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"F:\FMS1\FMS1\Macro3d_Intel\x64\Release\FMS1.exe.intermediate.manifest" /SUBSYSTEM:CONSOLE /IMPLIB:"F:\Macro3d\FMS\fmsnogpu.lib F:\Macro3d\FMS\fmsnoshr.lib" "x64\Release\mode2_code.obj" "F:\Macro3d\FMS\Include Files\fmsnogpu.lib" "F:\Macro3d\FMS\Include Files\fmsnoshr.lib"
Link: executing 'link'
mode2_code.obj : error LNK2019: unresolved external symbol FMSINI referenced in function MAIN__
etc.

The 2 libraries I'm trying to link are fmsnogpu.lib and fmsnoshr.lib.

Do you expect the FMSINI reference to be satisfied in those libraries?  You might run dumpbin /symbols on the libraries to see what symbols are there, if they are recognizable in Visual Studio format, and whether they are "mangled" in some way, such as appended underscore.

The linker line shows clearly that the two libraries are being looked up, but the symbol FMSINI is not defined in either of them. Which of the two libraries is supposed to contain this routine? Have you checked whether the libraries do contain the symbol and could name mangling be the source of the problem?

Is it possible your libraries were built for 32-bits? If so, the external names would be different (a leading underscore on 32-bit. none on 64-bit.) You can't mix these.

Steve - Intel Developer Support

Steve,

Don't think so.  All the compiler options for the program using the library are 64-bit.  I'm checking with the supplier about the issue since I think I'm doing things right.

The options for the program aren't what is important here - it's how the libraries themselves were built.

Please open a Fortran command prompt window. Set default (cd) to the folder containing the libraries.  Type the command:

dumpbin -symbols name1.lib > name1.txt

Now open name1.txt in notepad (obviously you substitute the real library name here) and search for FMSINI. Please show the full line from the file that contains that text.

Steve - Intel Developer Support

Steve,

From the fmsnoshr.lib, under a heading "COFF SYMBOL TABLE" the first line is
004 00000000 SECT2  notype ()    External     | fmsini

Down a little further is
01D 00000000 UNDEF  notype ()    External     | fms$_fmsini

Nothing in fmsnogpu.lib

From this it appears the needed external subrountines are not there?

The routine is there, but in lowercase. This is evidently a C routine. On Windows, Fortran upcases routine names by default - hence the mismatch.

How are these routines declared in your Fortran code? Interface block, EXTERNAL or nothing at all? How many of these routines are you using? There are various ways to solve this but I need to know what your code looks like to recommend the best approach.

Steve - Intel Developer Support

Useful info Steve.

Supplier has just said that I need to add two additional files, one .f90 and one .h  they provided to reference the C rountines.  I'm not experienced enough to figure these things out without a little guidence from them.

Steve,

Get a compile error associated with the .f90 file that was provided (I modified it and file is attached).  Main program is.fixed format file (.f attached)..

Probably some error due to my lack of knowledge in mixing fortran.

Thanks!

Fichiers joints: 

Fichier attachéTaille
Télécharger build.txt2.07 Ko
Télécharger mode2-code.f13.49 Ko
Télécharger fmshdrf.f9030.71 Ko

You evidently modified it by removing the MODULE and END MODULE lines. (The error message suggests you removed one and not the other.)

1. Put the MODULE and END MODULE lines back.

2. Add this .f90 source file to your project or compile it separately.

3. Add USE MODULENAME (where MODULENAME is the name of the module) to each program unit in your program that needs to call one of these routines. This line should go directly after the PROGRAM, SUBROUTINE or FUNCTION statement.

Steve - Intel Developer Support

I have seen only pieces of your source files, but here is one part that raised a red flag:

      !DEC$ATTRIBUTES C, REFERENCE, ALIAS:' fmsini'::FMSINI

Note the leading blank in the alias name. These leading blanks are present in a number of aliases in file fmshdrf.f90; in particular, for FMSINI. Naturally, that is going to cause problems at link time. Try removing the leading blanks and building, or ask your library provider to explain those blanks.

Steve,

There were no MODULE statements anywhere before I modified the fmshdrf.f90 file.  Seems like the compiler doesn't like using an INTERFACE in the .f90 when that is all there is, i.e. there are no other parts in the file, only the INTERFACE and END INTERFACE and stuff in between.

Fichiers joints: 

Fichier attachéTaille
Télécharger fmshdrf.f9031.44 Ko

An interface block is not a complete program unit, just as any other fragment of Fortran code such as a DO loop is not a complete program unit. Therefore, it cannot be compiled by itself.

The interface block can be placed inside a module that is than USEd where needed, or the file with the interface block can be INCLUDEd where needed.

Citation :

mecej4 a écrit :
An interface block is not a complete program unit, just as any other fragment of Fortran code such as a DO loop is not a complete program unit. Therefore, it cannot be compiled by itself.

The interface block can be placed inside a module that is than USEd where needed, or the file with the interface block can be INCLUDEd where needed.

I tried both ways. For example, placed the file with INTERFACE and END INTERFACE as a file to be INCLUDED.  This ends up with all the routines as unresolved.  Same result if I place MODULE and END MODULE around the file and add a USE command.

This ends up with all the routines as unresolved.

Of course! Interfaces are just that: descriptions of the interfaces to subprograms. The code for the subprograms is, presumably, in your libraries, and you have to link your code to those libraries.

Interfaces help the compiler to know how to pass arguments to the called subroutine. What to do with the arguments is up to the library code. Think of an interface as a phone number. When you call the number, there has to be someone at that phone number to receive the call.

mecej,

I understand.  But as noted by Steve, based on the dumpbin output the files are there.  I also tried by removing the space in front of some of the routines as you note, still no improvement.

You could INCLUDE this file in the declarations section of each and every procedure that calls one of these library routines, or create a module and USE the module. You have to do this in each place these routines are called. You also need to specify the .lib as a source file or linker input.

If you do that and it still doesn't link, do you get exactly the same errors as before?

Steve - Intel Developer Support

Steve,

Made the file into a header file and added INCLUDEs in the needed routines.  The lines within the header file are typically like
           SUBROUTINE FMSIGT (NAME, VALUE)
              !DEC$ATTRIBUTES C, REFERENCE, ALIAS:'fmsigt'::FMSIGT
              CHARACTER *(*)  NAME
              INTEGER         VALUE
           END SUBROUTINE FMSIGT
to denote the C rountines stored in a .dll  I've added the path to the .dll into the environmental PATH.

Error messages coming out relate to "unresolved external symbol" for each of the C rountines called in the fortran program and subrounties.  VS2008 build log attached.

I've referenced the 2 needed librariesbut how does VS link to the .dll that contains the C rountines?  Do I need to reference it in VS2008?

Fichiers joints: 

Fichier attachéTaille
Télécharger buildlog.txt3.42 Ko

Ok - you are now correctly using the include files. However, I wonder if the .lib files are correct. Can you attach a ZIP of one to a reply here?  If they are DLL import libraries they have no code.

As for the DLL, the way it works on Windows is that the the import library contains information the linker uses to set up the relationship to the DLL. You don't link to the DLL itself. When you run the program, Windows sees the DLL name and looks for it in its normal search paths.

Steve - Intel Developer Support

Steve, lib attached.

Fichiers joints: 

Fichier attachéTaille
Télécharger fmsnogpu-lib.zip3.88 Ko

Steve,

Did a "lib /list F:\Macro3d\FMS\fmsnogpu.lib" and it contains a number of lines each of which has fmsnogpu.dll.   If I do a "dumpbin -exports F:\Macro3d\FMS\fmsnogpu.dll" it indicates 136 functions and then lists a bunch of C rountines on each line.  I might assume that the lines in fmsnogpu.lib map the corresponding .dll (different .dll for each is possible) where the C routine is contained (good assumption?).  If this is correct, Windows should know the needed .dll for each C rountine and with the PATH set find the dll.

There is an additioal .lib input (fmsnoshr.lib).  I don't know what purpose it serves but I've attached it, just in case it might help figure this out.

Fichiers joints: 

Fichier attachéTaille
Télécharger fmsnoshr-lib.zip3.39 Ko

fmsnogpu.lib is a DLL import library. It has some of the routines your program is looking for, but not all, such as fmsini. fmsnoshr-lib is a static library that defines many of the same routines - it does have fmsini.

Still, I am puzzled that your build did not find fmspsh since it is in fmsnogpu.lib. Please do one more thing.  In your project, go to the Linker > General property page and set the "Show progress messages" property to "Show all progress messages", then try the link again. Attach the new buildlog.htm (as a zip) so I can see what it is doing.

Steve - Intel Developer Support

Oh, one thing is really odd - the library shows in the middle of the link line, not at the end where I might expect it. Please also attach a ZIP of the .vfproj file.

Steve - Intel Developer Support

Steve, see attachments.

Fichiers joints: 

Fichier attachéTaille
Télécharger build-log-htm.zip11.13 Ko
Télécharger fms-vfproj.zip1.1 Ko

Got it! The problem is that you added the FMS libraries in the linker property Advanced > Import Library. I can sort of see why you may have thought that was the right place, since one of these libraries is indeed an import library, but if you read the inline help for that property it says "Specifies which import library to generate". This isn't what you want and in fact has no effect at all in this build.

Move this value to Linker > Input > Additional Dependencies and it will be much happier.

Steve - Intel Developer Support

Bingo!  How did you figure that out? Compiles fine now.

With great flexibility (such as VS) comes even more changes to screw it up.

Thanks Steve!!

Well, remember that I said that the log showed the libraries in an odd place in the link line. Then when you showed the log with "progress" messages, I saw that the FMS libraries were never even looked at. So I asked for the .vfproj file to see where you were specifying these and found them in the wrong place. I did get confused a bit before I realized that you had these in one configuration only - Release x64.

May I also suggest that you change your "Display Name" for Intel Developer Zone to be something other than your email address? You should be able to do this through the "Dashboard" (click on the triangle to the right of your name in the upper right.)

Steve - Intel Developer Support

Thanks Steve, changed the dashboard.

Opps, not out of the woods yet.

Build doesn't complete the link.  There are 5 C rountines not identified in the fnamefile.dll and these produce the unresolved externals.  The supplier suggested to just change the calls from CAPITALIZED FILE NAMES (call XYZ) to lower case file names (call xyz).  This makes sense but doesn't work.  I'm wondering if I have something else screwed up in my project properties.

Attached is both the build.log and the vfproj again for my current setup.  They look OK to me but something is amiss.

Fichiers joints: 

Fichier attachéTaille
Télécharger vfproj.zip1.02 Ko
Télécharger build-log.zip8.51 Ko

Citation :

The supplier suggest to just change the calls from CAPITALIZED FILE NAMES (call XYZ) to lower case file names (call xyz).

Let's not confuse file names and subprogram names.

Intel Fortran has a default case for the names of external symbols (routine names, module names, common block names, etc.), and the .OBJ files contain names with that default regardless of the case used in the source (Fortran is case-insensitive except w.r.t. the contents of character variables). See if the /names:lowercase compiler option will help resolve your problems.

Please do not use /names. Simply changing the names in the Fortran source won't help. What this tells me is that either the include file/module doesn't declare those routines, or you forgot to include/use it in the main program.

Steve - Intel Developer Support

Laisser un commentaire

Veuillez ouvrir une session pour ajouter un commentaire. Pas encore membre ? Rejoignez-nous dès aujourd’hui