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

problem with including files

Reza_Ahmadian
Beginner
872 Views

Hi All,

I have started using Intel Fortran after a long time of using Compaq Fortran. And I have been setting up a solution which used to work in Compaq Fortran in Intel Fortran, but it gives me linking error which doesnt make sense to me. I was wondering if any one can help.

The solution consists of three projects, 1 console application and 2 static libraries. I refer to them as project 1, 2 and 3, as you can see below.

The second library (project 2) depends on the first library (project 1) and the application (project 3) depends on both libraries (project 1 and 2). Netcdf.inc file which consist of some data is included in all three projects. All the projects compile correctly and two libraries are built without any error. However, when I build the application or the solution I receive many linking errors such as you can see below.

Error 1 error LNK2019: unresolved external symbol _NF_STRERROR referenced in function _CWRMETHODS_mp_CHECKNETCDFSTATUS LibCwrCommon.lib(cwrmethods.obj)

Error 2 error LNK2001: unresolved external symbol _NF_STRERROR LibCwrCommon.lib(dysimio.obj)
Error 4 error LNK2019: unresolved external symbol _NF_INQ_VARID referenced in function _CWRMETHODS_mp_GETVARID LibCwrCommon.lib(cwrmethods.obj)


LibCwrCommon.lib is the first library or project 1.

errors.TIF


This doesnt make sense to me as these variables which are referred to as unresolved external symbols in the error message are part the netcdf.inc which is included in the subroutines and functions via Include command. For instance, the first error is about unresolved external symbol _NF_STRERROR referenced in function _CWRMETHODS_mp_CHECKNETCDFSTATUS.

However, as you can see below, NF_STRERROR is declared in netcdf.inc and netcdf.inc is included in the CHECKNETCDFSTATUS function using the include command.

netcdf.inc: NF_STRERROR declared on line 7.

[fxfortran]!
! miscellaneous routines:
!
      character*80   nf_inq_libvers
      external       nf_inq_libvers

      character*80   nf_strerror
!                         (integer             ncerr)
      external       nf_strerror

      logical        nf_issyserr
!                         (integer             ncerr)
      external       nf_issyserr

!
! control routines:
!
[/fxfortran]



CHECKNETCDFSTATUS function, netcdf.inc is included on lie 9 and NF_STRERROR is used on line 25.

[fortran] !========================================================
  SUBROUTINE CheckNetCDFStatus(netCDFstatusCode,infoRoutine,infoVar)
  
    IMPLICIT NONE


    ! ---------------------------------------
    
       INCLUDE 'netcdf.inc'    
   
    INTEGER,                INTENT(IN) :: netCDFstatusCode
    CHARACTER(*),           INTENT(IN) :: infoRoutine
    CHARACTER(*), OPTIONAL, INTENT(IN) :: infoVar

    !----------------------------------

    IF (NetCDFstatusCode .NE. NF_NOERR) THEN
       WRITE(*,'(1X,"CheckNetCDFStatus:  A netCDF access error has &
                                                    &occurred.")')
       IF (PRESENT(infoVar)) THEN
          WRITE(*,'(1X,3X,"netCDF entity:  ",A)') infoVar
       END IF
       WRITE(*,'(1X,3X,"Reported by:  ",A)') infoRoutine
       WRITE(*,'(1X,3X,"netCDF status value = ",I0)') netCDFstatusCode
       WRITE(*,'(1X,3X,A)') NF_STRERROR(netCDFstatusCode)
    END IF
  END SUBROUTINE CheckNetCDFStatus
[/fortran]




I would be grateful if anyone can help why this is happening or how I can resolve it.

Many Thanks,

Reza


0 Kudos
17 Replies
mecej4
Honored Contributor III
872 Views
Compaq Visual Fortran and Intel Fortran use different default calling conventions with external functions and subroutines. If you use Intel Fortran to compile some source files and try to link to libraries or .OBJ files produced by CVF, you will run into mismatches.

If you have the sources for everything, it is best to recompile and rebuild the libraries using the current compiler. If you do not have the library sources, you will need to know how they were compiled and provide switches to the Intel compiler to enable compatibility with the CVF libraries.

Read the documentation on conversion from CVF ("Migrating from CVF" link at the top of this forum), and the chapters on calling conventions and mixed language programming in the Intel Fortran User Guide.
0 Kudos
Reza_Ahmadian
Beginner
872 Views
Thanks for your reply. I have the source code for all these files and I have built all the libraries using Intel Fortran, that's why I am confused. Any idea what I can do?
0 Kudos
Steven_L_Intel1
Employee
872 Views
In your Fortran projects, open the project properties > Fortran > External Procedures. Make sure that the Calling Convention is "Default" or " If you converted projects from CVF, it would set the convention to CVF and you may have a mixture.
0 Kudos
Reza_Ahmadian
Beginner
872 Views
Thanks Steve. I checked all the project and files and they were all set to default. I use :
Intel Visual Fortran Compiler Integration for Microsoft Visual Studio* 2008, 11.1.3466.2008
Microsoft Visual Studio 2008, version 9.0.30729.1 SP

the other options available forCalling Convention are:
C, Reference
STDCALL
STDCALL, Reference
CVF

Shall I set the Call Convention to anything else? Is there anything else I can do?

Many Thanks,

Reza
0 Kudos
Steven_L_Intel1
Employee
872 Views
Leave this setting at Default.

Let's concentrate on NF_STRERROR - where is this routine defined? Is it in a module?
0 Kudos
Reza_Ahmadian
Beginner
872 Views
yes it is. and it is declared in an external file, i.e. netcdf.inc. This file is included in that modulde using Include statement as:

INCLUDE 'netcdf.inc'

I get 72 linking errors and all of them are related to the variables which are declared in netcdf.inc.

I can send you the file including the NF_STRERROR if you think it is useful.


0 Kudos
mecej4
Honored Contributor III
872 Views
Although I have not used NetCDF myself, this is probably a good guess of the situation:

The include file contains only declarations that are used in correctly compiling your source code that calls the function nf_strerror. The actual source code that implements the function is probably part of the NetCDF library.

If so, all that is needed for you to do is to include the NetCDF library in the link command lines.
0 Kudos
Steven_L_Intel1
Employee
872 Views
So the routine is defined in an include file and you include it in the module. If so, make sure you USE that module and that you do NOT name the routine in an EXTERNAL statement.
0 Kudos
mecej4
Honored Contributor III
872 Views
Steve, I don't think that I have seen anything in this thread to indicate that O.P. is using Fortran 9X modules and module USE statements. We should probably ask to see a short reproducer at this point.
0 Kudos
IanH
Honored Contributor II
872 Views
yes it is. and it is declared in an external file, i.e. netcdf.inc. This file is included in that modulde using Include statement as:

INCLUDE 'netcdf.inc'

I get 72 linking errors and all of them are related to the variables which are declared in netcdf.inc.

The things declared in netcdf.inc are not variables - they are functions (based off the declarations and your usage). The problem is that there are no definitions for those functions. The compiler has been told what type the function is, but the compiler and linker in combination have not been given the actual code that does the work for those functions.

I expect that your solution is missing a library, which is probably called netcdf.lib, or you have specified that library but it has not been compiled in a manner that is compabile for Intel Fortran defaults (hence the other responses).

Do you have the netcdf library in a form suitable for Intel Fortran? Alternatively, do you have it in a form suitable for CVF?

In Visual Studio solutions you can specify a library on the properties page under Linker > Input > Additional Dependencies.

Posting your build log may help further diagnosis.
0 Kudos
Reza_Ahmadian
Beginner
872 Views
I have added NetCDF to the project as an exiting item and also included its folder to the "Additional Include Directories" which is equivalent to: /I"L:\Debugging\Setup Fortran 2010\include". do you mean I should do something else?
0 Kudos
IanH
Honored Contributor II
872 Views
I have added NetCDF to the project as an exiting item...

Exactly what did you add to the project - what extension did the file have?

...and also included its folder to the "Additional Include Directories" which is equivalent to: /I"L:\Debugging\Setup Fortran 2010\include". do you mean I should do something else?

Include directories are used by the compiler (note in Visual Studio you specify this in the Fortran compiler properties) - for finding things such as the files named in INCLUDE statements (and other files such as modules and #include files, that aren't directly relevant here).

It is not the compiler that is reporting errors - it is finding all the files that it thinks it needs.

You have a linking problem, which comes after compiling. That might be caused by an "upstream" problem with the compiler settings (the linker has been given the wrong symbols to link together into your final program) or it might be caused by missing libraries or object files - we're not sure yet.

The linker is looking for the (previously compiled) object code that sits behind a particular function, but it can't find that code. The INC files don't contain that code - they just tell the compiler that a function exists and the type of result it returns.

The linker also has a search path for libraries, but if it couldn't find a library that it was told it needed it would complain about that directly.

So post your build log.

0 Kudos
Reza_Ahmadian
Beginner
872 Views

Hi Ian,

You are absolutely right about in yopur reply #10. Those are functions and I hadnt noticed that before. I have another library which is already built in CVF but unfortunately, I dont have the source code for that one. I had included the folder containing that library in Properties>Fortran>General>additional include directories and had also added the library to the project as an existing item and that had not helped. Is this way of adding a library to the solution correct?

If So, I think the library must be incompatible with Intel Fortran. Is there anyway that I can add this library which is built using CVF to the Intel Fotran solution?

I have also attached my build logs. As I have already mentioned, the order of building is as sollows: 3,1,2

Thank you very much,

Kind Regards,

Reza

1-+BuildLog+caedym1.htm

2-+BuildLog+full+2.htm

3-+BuildLog+libcommon+3.htm

0 Kudos
mecej4
Honored Contributor III
872 Views
From the logs it is clear that the unsatisfied externals are the Fortran wrappers which redirect calls to the underlying C functions in NetCDF, that is, externals with names prefixed with _NF_.

I do not know which version of NetCDF you are using and whether you built the libraries yourself or obtained a prebuilt set; however, a significant point is that from version 3.6.2 and later the Fortran interfaces are not included in the DLL by default. This is the relevant quote from UCAR:

In all netCDF versions before 3.6.2, the Fortran 77, Fortran 90, and the C libraries were all built into the same library file. That is, the libnetcdf.a file contains the C functions, the F77 functions, and the F90 functions. (The C++ library is separate.)

Starting with version 3.6.2, another method of building the netCDF fortran libraries becomes available. With the enable-separate-fortran option to configure, the user can specify that the C library should not contain the fortran functions. In these cases an additional library, libnetcdff.a (note the extra f) will be built. This library contains the fortran functions.

Thus, you need to determine the location in your NetCDF installation where the Fortran interface functions are kept, and include that library in the link step.In all likelihood, that library will be called NETCDFF.lib
0 Kudos
Reza_Ahmadian
Beginner
872 Views

HI,

I am using pre-built netcdf.lib version 3.6.1. I dont understand what you mean be the interface. Is it simply the netcdf.inc which is shown below or I need to write a new interface. Moreover, I have included netcdf.lib in the linker option of the application and in the librarian option of the libraries but it didnt help. Do I need to do anything else? I have attached the new logs.

Sorry if I am too amature.

Many Thanks,

Reza

netcdf.inc

3+BuildLog.htm

1+BuildLog.htm

2+BuildLog.htm

0 Kudos
mecej4
Honored Contributor III
872 Views
By "interfaces" I meant wrapper routines that are included in the NetCDF.dll that are for calling from Fortran code. These routines do nothing but pass the parameters through to the C routines that do the actual work. In this sense, the Fortran wrapper routines provided a Fortran "interface" to the C routines.

The UCAR file WIN32_README.TXT gives instructions on how to build a version of netcdf.dll that includes the Fortran interfaces. I just tried building it on Windows XP, and things went fine. The building of the DLL took less than a minute.

I think that you have at least two choices: 1) use the DLL that you have, and convert your code to call the C routines in NetCDF directly, and 2) build a new version of the DLL as I described in the preceding paragraph.
0 Kudos
Reza_Ahmadian
Beginner
872 Views
Thank you very much for this. I really didn't know that I should make the interface myself. I will try and make the dll as you described and hopefully it will be fine. I will let you know how I am getting on with it.

Thank you veryt much for your help once again,
0 Kudos
Reply