error when linking a Fortran library to c++ code in VC8

J

Julian

I get the following error when i try to link a fortran library to a c++ code
in .NET 2005.

LINK : fatal error LNK1104: cannot open file 'libc.lib'

the code was working fine when built using .NET2003.
also, when I do not try to link the fortran library (just to see if that was
the cause), it builds the exe without any problems.

i don't even know how to begin addressing this problem...any help would be
appreciated.

thanks,
Julian.
 
W

William DePalo [MVP VC++]

Julian said:
I get the following error when i try to link a fortran library to a c++
code in .NET 2005.

LINK : fatal error LNK1104: cannot open file 'libc.lib'

the code was working fine when built using .NET2003.
also, when I do not try to link the fortran library (just to see if that
was the cause), it builds the exe without any problems.

i don't even know how to begin addressing this problem...any help would be
appreciated.

The singly threaded library you mention has been removed from VS2005. See
here:

http://msdn2.microsoft.com/en-us/library/abx4dbyh.aspx

It should be a simple matter of switching to a multithreaded library to get
your project to build. This box does not have 2005 installed, but if you
have trouble finding the setting in the project's properties dialog, post
again and I'll reply with instructions later on the off chance no one else
sets you straight first.

Regards,
Will
 
J

Julian

William DePalo said:
The singly threaded library you mention has been removed from VS2005. See
here:

http://msdn2.microsoft.com/en-us/library/abx4dbyh.aspx

It should be a simple matter of switching to a multithreaded library to
get your project to build. This box does not have 2005 installed, but if
you have trouble finding the setting in the project's properties dialog,
post again and I'll reply with instructions later on the off chance no one
else sets you straight first.

Regards,
Will

thanks for the reply.
I see that when I upgraded my c++ project from 2003 to 2005, it
automatically made it multi-threaded.
but it is the FORTRAN library that is single-threaded. so, I guess I need to
rebuild the FORTRAN library with the multi-thread option? in this particular
case, that is possible since I have the source code to the library. but what
if I was using a third-party library to which I didn't have the source?
would I be stuck then ?
also, in order to compile the FORTRAN library and get it running with my vc8
code, do I have to use the latest multi-threaded CRTs? or will any version
do (this is for rebuilding the FORTRAN library alone)?

Julian.
 
W

William DePalo [MVP VC++]

Julian said:
thanks for the reply.

You are welcome.
I see that when I upgraded my c++ project from 2003 to 2005, it
automatically made it multi-threaded.
OK.

but it is the FORTRAN library that is single-threaded. so, I guess I need
to rebuild the FORTRAN library with the multi-thread option?

First the disclaimer: the last time I did any Fortran development on a
regular basis I was sitting at an IBM 029 keypunch nachine. I suspect that
things have changed a lot since the dark ages. :)

That said, I don't think that you should have to rebuild your Fortran
library though I may be wrong.
but what if I was using a third-party library to which I didn't have the
source? would I be stuck then ?

The problem of mismatched libraries usually occurs when you try to pass
references to objects created in a component built with one library to a
component built in another. Passing, for example, C file handles or pointers
to blocks allocated with malloc() or the new operator, may bite you,
depending on how the callee uses them.

I doubt that either the C or C++ runtime is similar enough to that of
Fortran to allow this kind of problematic sharing. Of course, I could be
wrong.

Rather, I think that by using the multi-threaded runtime you will make your
application safe for multi-threading. With the single thread I expect that
you have, that should be a nit.
also, in order to compile the FORTRAN library and get it running with my
vc8 code, do I have to use the latest multi-threaded CRTs? or will any
version do (this is for rebuilding the FORTRAN library alone)?

As I said, I have to duck the Fortran questions because of my lack of
experience with it. Whose compiler are you using? And what does your library
do? If you post again, someone with Fortran knowledge may pop in. If no one
does, you might post again in

microsoft.public.vc.language

which I think sees a bit more traffic than this group.

Regards,
Will
 
J

Julian

William DePalo said:
You are welcome.


First the disclaimer: the last time I did any Fortran development on a
regular basis I was sitting at an IBM 029 keypunch nachine. I suspect that
things have changed a lot since the dark ages. :)

That said, I don't think that you should have to rebuild your Fortran
library though I may be wrong.


The problem of mismatched libraries usually occurs when you try to pass
references to objects created in a component built with one library to a
component built in another. Passing, for example, C file handles or
pointers to blocks allocated with malloc() or the new operator, may bite
you, depending on how the callee uses them.

I doubt that either the C or C++ runtime is similar enough to that of
Fortran to allow this kind of problematic sharing. Of course, I could be
wrong.

Rather, I think that by using the multi-threaded runtime you will make
your application safe for multi-threading. With the single thread I expect
that you have, that should be a nit.


As I said, I have to duck the Fortran questions because of my lack of
experience with it. Whose compiler are you using? And what does your
library do? If you post again, someone with Fortran knowledge may pop in.
If no one does, you might post again in

microsoft.public.vc.language

which I think sees a bit more traffic than this group.

Regards,
Will
actually, I went ahead and rebuilt the fortran library using the
multi-threaded option (using Digital Visual Fortran). and it worked ! VC8
linked the files this time with no errors !

thanks for the reply !
 
C

Carl Daniel [VC++ MVP]

Julian said:
actually, I went ahead and rebuilt the fortran library using the
multi-threaded option (using Digital Visual Fortran). and it worked ! VC8
linked the files this time with no errors !

Great!

Another option that probably would have worked would have been to add
/nodefaultlib:libc.lib to your linker options. If you have another fotran
library that you can't rebuild, that might be an option for you.

-cd
 
J

Julian

Great!
Another option that probably would have worked would have been to add
/nodefaultlib:libc.lib to your linker options. If you have another fotran
library that you can't rebuild, that might be an option for you.

-cd
what actually happens when you do that ?
does that mean that it will force the fortran library to be a multi-threaded
library?

also, while i didn't get any errors, i did get this warning:
LINK : warning LNK4098: defaultlib 'libcmt.lib' conflicts with use of other
libs; use /NODEFAULTLIB:library

can you explain that to me? what exactly is the conflict? and will that
cause problems for me later on?
I used "multithreaded-debug" for the c++ program. and "multi-threaded" in
the debug configuration as the 'active configuration' for the fortran
library.

thanks,
Julian.
 
C

Carl Daniel [VC++ MVP]

Julian said:
what actually happens when you do that ?
does that mean that it will force the fortran library to be a
multi-threaded library?

also, while i didn't get any errors, i did get this warning:
LINK : warning LNK4098: defaultlib 'libcmt.lib' conflicts with use of
other libs; use /NODEFAULTLIB:library

can you explain that to me? what exactly is the conflict? and will
that cause problems for me later on?
I used "multithreaded-debug" for the c++ program. and
"multi-threaded" in the debug configuration as the 'active
configuration' for the fortran library.

Object files, regardless of the compiler they're created with, can contain
default library requests. These tell the linker to include a particular
library in the link even if it's not mentioned specifically in the linker
input settings.

The /nodefaultlib option tells the linker to ignore default library requests
for the named library. If symbols from that library are indeed needed,
either the library will have to be supplied explicitly in the linker input
settings or some other library will have to supply those symbols for the
link to complete without an error.

Now, here's the key - the different versions of the runtime library - libc,
libcmt, msvcrt and the debug versions of each of those all export the same
symbols, with a very few differences. For example, only the multi-threaded
libraries contain a definition for _beginthread().

Now, if your code is single threaded (which apparently it is, since you were
using the single-threaded libraries with VC6), then it's perfectly safe to
link that code against the multi-threaded runtime library. The fact that
you're linking a multi-threaded RTL doesn't make your code multi-threaded.
It simply means that you're linking with a version of the library that's
safe for use by multiple threads - it's also safe for use by a single
thread.

So, when you re-built your fortran code for multi-threaded, the compiler
emitted a default library record requesting libcmt.lib - the static
multi-threaded runtime library. Your program was actually linked against
msvcrt.lib - the import library for the DLL runtime library. As discussed
above, these libraries actually define all of the same symbols. The linker
is just warning you that the default library that was specified for your
fortran module duplicates symbols that are already in the link and suggests
that you use /nodefaultlib to suppress that default library request.

In your case, there's no harm in adding /nodefaultlib:libcmt.lib to your
linker settings to quite the warning. If you'd rather not have a dependency
on msvcr80.dll, you can change your project settings to "Multi-threaded"
instead of the default "Multi-threaded DLL" so that your program is linked
against libcmt.lib instead of msvcrt.lib.

HTH

-cd
 
J

Julian

Carl Daniel said:
Object files, regardless of the compiler they're created with, can contain
default library requests. These tell the linker to include a particular
library in the link even if it's not mentioned specifically in the linker
input settings.

The /nodefaultlib option tells the linker to ignore default library
requests for the named library. If symbols from that library are indeed
needed, either the library will have to be supplied explicitly in the
linker input settings or some other library will have to supply those
symbols for the link to complete without an error.

Now, here's the key - the different versions of the runtime library -
libc, libcmt, msvcrt and the debug versions of each of those all export
the same symbols, with a very few differences. For example, only the
multi-threaded libraries contain a definition for _beginthread().

Now, if your code is single threaded (which apparently it is, since you
were using the single-threaded libraries with VC6), then it's perfectly
safe to link that code against the multi-threaded runtime library. The
fact that you're linking a multi-threaded RTL doesn't make your code
multi-threaded. It simply means that you're linking with a version of the
library that's safe for use by multiple threads - it's also safe for use
by a single thread.

So, when you re-built your fortran code for multi-threaded, the compiler
emitted a default library record requesting libcmt.lib - the static
multi-threaded runtime library. Your program was actually linked against
msvcrt.lib - the import library for the DLL runtime library. As discussed
above, these libraries actually define all of the same symbols. The
linker is just warning you that the default library that was specified for
your fortran module duplicates symbols that are already in the link and
suggests that you use /nodefaultlib to suppress that default library
request.

In your case, there's no harm in adding /nodefaultlib:libcmt.lib to your
linker settings to quite the warning. If you'd rather not have a
dependency on msvcr80.dll, you can change your project settings to
"Multi-threaded" instead of the default "Multi-threaded DLL" so that your
program is linked against libcmt.lib instead of msvcrt.lib.

HTH

-cd
thanks a lot for taking the time to explain all that. it did help a lot...
but i also have some questions:
how could you tell that my program was linked against msvcrt.lib? actually,
the project settings say "Multi-threaded Debug" and not "Multi-threaded
Debug DLL". this is in Property Pages -> C/C++ -> Code Generation -> Runtime
Library

is there some other place where i need to make this setting?
 
C

Carl Daniel [VC++ MVP]

Julian said:
thanks a lot for taking the time to explain all that. it did help a lot...
but i also have some questions:
how could you tell that my program was linked against msvcrt.lib?
actually, the project settings say "Multi-threaded Debug" and not
"Multi-threaded Debug DLL". this is in Property Pages -> C/C++ -> Code
Generation -> Runtime Library

is there some other place where i need to make this setting?

Process of elimination. Since I already knew that you'd changed from using
libc, the only other library that would conflict with libcmt is msvcrt.
Unless you're mixing debug and non-debug builds anyway!

If the fortran module is using libcmt and you're linking it with a debug
build, that'd produce the linker warning since your program would be using
libcmtd. You can tell which default library(ies) are specified in an .OBJ
file by using DUMPBIN /DIRECTIVES {your file here}. Dumpbin is in your
Visual Studio tools directory and should be on the PATH if you use the
command-prompt shortcut that was installed with Visual Studio.

-cd
 
J

Julian

Carl Daniel said:
Process of elimination. Since I already knew that you'd changed from
using libc, the only other library that would conflict with libcmt is
msvcrt. Unless you're mixing debug and non-debug builds anyway!

If the fortran module is using libcmt and you're linking it with a debug
build, that'd produce the linker warning since your program would be using
libcmtd. You can tell which default library(ies) are specified in an .OBJ
file by using DUMPBIN /DIRECTIVES {your file here}. Dumpbin is in your
Visual Studio tools directory and should be on the PATH if you use the
command-prompt shortcut that was installed with Visual Studio.

-cd
yeah... u guessed it right... the fortran library was using libcmt.lib ,
while the program was in debug mode. once i fixed that, the warning
vanished.

thanks !
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top