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

Problem with linking to library

Alessandro
Beginner
1,750 Views
I'm trying to call some CUDA routines from Fortran. I'm using Visual Studio 2008 professional under Windows XP 64bit. I created a C static library with the C source, and I can build it, so that I have a .lib file somewhere on my hard disk. Then I try to link this .lib from a Fortran program, but it tells me:

Error 1 fatal error LNK1181: cannot open input file 'C_lib.lib' LINK

I put the exact path where the file C_lib.lib is in the tab Linker -> General -> Additional Library Directories, and I put C_lib.lib in the tab Linker -> Input -> Additional dependencies.

I commented the call to the routines contained in the library, so that actually in the Fortran code there aren't any calls to the library, and the problem seems to be exactly in linking the .lib file.

Could you please help me? Thank you.

Alessandro
0 Kudos
11 Replies
Steven_L_Intel1
Employee
1,750 Views
Can you attach the buildlog.htm from the failed build?
0 Kudos
Alessandro
Beginner
1,750 Views
Can you attach the buildlog.htm from the failed build?

The buildlog.htm follows:



Build Log
Build started: Project: BW_test, Configuration: Release|Win32

Output
Deleting intermediate files and output files for project 'BW_test', configuration 'Release|Win32'.
Compiling with Intel Visual Fortran 11.0.074 [IA-32]...
ifort /nologo /module:"Release" /object:"Release" /libs:static /threads /dbglibs /c /Qvc9 /Qlocation,link,"C:Program Files (x86)Microsoft Visual Studio 9.0VCbin" "C:NVIDIA CUDA SDKprojectsCUDA_libBW_testSource1.F90"
Linking...
Link /OUT:"ReleaseBW_test.exe" /INCREMENTAL:NO /NOLOGO /LIBPATH:"C:NVIDIA CUDA SDKprojectsCUDA_libRelease" /MANIFEST /MANIFESTFILE:"C:NVIDIA CUDA SDKprojectsCUDA_libBW_testreleasebw_test.exe.intermediate.manifest" /SUBSYSTEM:CONSOLE /IMPLIB:"C:NVIDIA CUDA SDKprojectsCUDA_libBW_testreleasebw_test.lib" C_lib.lib "ReleaseSource1.obj"
Link: executing 'link'
LINK : fatal error LNK1181: cannot open input file 'C_lib.lib'


BW_test - 1 error(s), 0 warning(s)



0 Kudos
Steven_L_Intel1
Employee
1,750 Views
And are you very sure that C_lib.lib exists in C:NVIDIA CUDA SDKprojectsCUDA_libRelease and that it is a valid library? Can you show a directory listing of that folder?
0 Kudos
Alessandro
Beginner
1,750 Views
And are you very sure that C_lib.lib exists in C:NVIDIA CUDA SDKprojectsCUDA_libRelease and that it is a valid library? Can you show a directory listing of that folder?

Yes, the file exists, but I don't know if it is a valid library, how can I check it?

If I change and compile in Debug mode it can find the library, but when I add the call to a routine it cannot resolve it:

Error 1 error LNK2019: unresolved external symbol _Maincuda referenced in function _MAIN__ Source1.obj

The fortran main code contains the following:


INTERFACE TO SUBROUTINE maincuda [C,ALIAS:'_Maincuda'] (argc,argv)
integer argc [VALUE]
character argv [VALUE]
END

integer argc
character argv

call maincuda(argc,argv)

end



The maincuda is defined in the library as follows:



void
Maincuda(int argc, char** argv)
{
runTest(argc, (const char**)argv);
cutilExit(argc, argv);
}

0 Kudos
Steven_L_Intel1
Employee
1,750 Views
Oh, yuck. Fortran PowerStation INTERFACE TO.

First, that the linker doesn't complain about the library in a Debug configuration suggests that either you have set the linker properties correctly for Debug but not for Release, or that you didn't add the library at all to Debug so the linker never looks for it.

To see what symbols are in a library, start a Fortran Build Environment command prompt window, set default (cd) to the folder with the library and type:

dumpbin -symbols C_lib.lib > c_lib.txt

Now open c_lib.txt and you'll see all the symbols listed. You can also do this on an object file.
0 Kudos
Alessandro
Beginner
1,750 Views
Oh, yuck. Fortran PowerStation INTERFACE TO.

First, that the linker doesn't complain about the library in a Debug configuration suggests that either you have set the linker properties correctly for Debug but not for Release, or that you didn't add the library at all to Debug so the linker never looks for it.

To see what symbols are in a library, start a Fortran Build Environment command prompt window, set default (cd) to the folder with the library and type:

dumpbin -symbols C_lib.lib > c_lib.txt

Now open c_lib.txt and you'll see all the symbols listed. You can also do this on an object file.

These are the lines in c_lib.txt where maincuda appears:

...
Section length 1F, #relocs 2, #linenums 0, checksum CEFEC89B, selection 1 (pick no duplicates)
248 00000000 SECTB1 notype () External | ?Maincuda@@YAXHPEAPEAD@Z (void __cdecl Maincuda(int,char * *))
249 00000000 SECTB2 notype Static | .pdata
Section length C, #relocs 3, #linenums 0, checksum A59B2387, selection 5 (pick associative Section 0xB1)
24B 00000000 SECTB2 notype Static | $pdata$?Maincuda@@YAXHPEAPEAD@Z
24C 00000000 SECTB3 notype Static | .xdata
Section length C, #relocs 0, #linenums 0, checksum 2559CD25, selection 5 (pick associative Section 0xB1)
24E 00000000 SECTB3 notype Static | $unwind$?Maincuda@@YAXHPEAPEAD@Z
24F 00000000 SECTB1 notype Label | $LN4
....

How should I use the ouput of the command dumpbin?
0 Kudos
Steven_L_Intel1
Employee
1,750 Views
Oh dear. Maincuda is C++ and has the C++ "name mangling" applied.

Try this as a replacement for your INTERFACE TO block.

INTERFACE
SUBROUTINE Maincuda (argc, argv)
!DEC$ ATTRIBUTES C, ALIAS:"?Maincuda@@YAXHPEAPEAD@Z" :: Maincuda
INTEGER argc
INTEGER(INT_PTR_KIND()), DIMENSION(*) :: argv
END SUBROUTINE Maincuda
END INTERFACE

I'm not sure what you are passing for argv - it is certainly not a single character. I believe that the correct value is an array of pointers to null-terminated strings.
0 Kudos
Alessandro
Beginner
1,750 Views
Oh dear. Maincuda is C++ and has the C++ "name mangling" applied.

Try this as a replacement for your INTERFACE TO block.

INTERFACE
SUBROUTINE Maincuda (argc, argv)
!DEC$ ATTRIBUTES C, ALIAS:"?Maincuda@@YAXHPEAPEAD@Z" :: Maincuda
INTEGER argc
INTEGER(INT_PTR_KIND()), DIMENSION(*) :: argv
END SUBROUTINE Maincuda
END INTERFACE

I'm not sure what you are passing for argv - it is certainly not a single character. I believe that the correct value is an array of pointers to null-terminated strings.

Actually I don't know how to manage it. This is something I'm trying to do with the working examples I have from CUDA, since I need to interface my Fortran code to CUDA. Then the maincuda was in origin the main of the C++ program, and I only changed the name from "main" to "maincuda", willing to call it from a Fortran program.
Can you maybe show me a Fortran program which can call the following C++ code:

void Maincuda(int argc, char** argv)
{
runTest(argc, (const char**)argv);
cutilExit(argc, argv);
}

And, considering that the Maincuda and all the routines should be contained in the library C_lib.lib (supposing that I compiled the library correctly), how would you compile and link it? Maybe this is the easiest way to understand what I should do in order to use CUDA.

Hope you can help me. Thank you.

Alessandro


0 Kudos
Steven_L_Intel1
Employee
1,750 Views
I don't think you want to "call" maincuda. The sample you were provided has a C++ main program which, I assume, calls some CUDA routines. You want to replace the C++ main, not call it. It may be that you need to create some jacket C++ routine that does the CUDA stuff and call it, but not try to make it look like a "main". I assume that the sample you were shown doesn't actually do anything with argc and argv - those are standard arguments to a C/C++ main program.

In any event, if you write some C++ code you want to call from Fortran, be sure to prefix the declaration of it in the C++ side with 'extern "C"' to avoid name mangling.
0 Kudos
Alessandro
Beginner
1,750 Views
I don't think you want to "call" maincuda. The sample you were provided has a C++ main program which, I assume, calls some CUDA routines. You want to replace the C++ main, not call it. It may be that you need to create some jacket C++ routine that does the CUDA stuff and call it, but not try to make it look like a "main". I assume that the sample you were shown doesn't actually do anything with argc and argv - those are standard arguments to a C/C++ main program.

In any event, if you write some C++ code you want to call from Fortran, be sure to prefix the declaration of it in the C++ side with 'extern "C"' to avoid name mangling.

And how can I replace the c++ main? I suppose I want a Fortran main which calls runTest and cutilExit, but I'd like to see an example on how to do it.
0 Kudos
Steven_L_Intel1
Employee
1,750 Views
Sorry, I'm not familiar with the CUDA software and its use. You may want to study samples of calling C from Fortran.
0 Kudos
Reply