I'm trying to build an old console program, and I get about 1000 linker errors like the following:
Error 730 error LNK2019: unresolved external symbol _vsprintf referenced in function _for__io_return libifcoremt.lib(for_diags_intel.obj)
Error 572 error LNK2001: unresolved external symbol _memmove imsl.lib(crgrg.obj)
Can anyone tell me what I'm doing wrong?
Please show the command line used at the link step (or the relevant lines in the VS build log). The indications are that the C run time library is not being searched, for some reason. One possibility is that a mixture of 32-bit and 64 bit objects is being fed to the linker.
build log is attached. Everything seems to be built as 32 bit Debug. There are three elements to the project.
One fortran console program xltorsion.exe
A small C lib that writes progress messages to the console window.
A small fortran DLL.
I have another very similar project that builds with no problem. I have compared them very carefully and can't find anything different about the build settings. I've got the following in the main program.
!DEC$ OBJCOMMENT LIB:'libiomp5md.lib'
This line in the build log tells us what is wrong:
Creating temporary file "RSP1.rsp" with contents [ /OUT:"Debug/XLTorsion.exe" /INCREMENTAL:NO /NOLOGO /NODEFAULTLIB:"libc" /NODEFAULTLIB:"libcmtd" /MANIFEST /MANIFESTFILE:"C:\Users\Brian\Documents\Visual Studio 2010\Projects\TRC-2013\Lateral Torsion Coupling\XLTorsion\Debug\XLTorsion.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"Debug/XLTorsion.pdb" /MAP /SUBSYSTEM:CONSOLE /STACK:500000000 /IMPLIB:"C:\Users\Brian\Documents\Visual Studio 2010\Projects\TRC-2013\Lateral Torsion Coupling\XLTorsion\Debug\XLTorsion.lib" /MACHINE:I386 "Debug/Security.obj" "Debug/DebugTools.obj" "Debug/Modules.obj" "Debug/TorInput.obj" "Debug/ForceResp.obj" "Debug/Spd Dependent.obj" "Debug/selmat.obj" "Debug/Damped.obj" "Debug/RK4.obj" "Debug/Conelem.obj" "Debug/UTF.obj" "Debug/Outputs.obj" "Debug/Main.obj" "Debug/AssembleMat.obj" "Debug/TorTransient.obj" "Debug/NewmarkBetaWilsonTheta.obj" "C:\Users\Brian\Documents\Visual Studio 2010\Projects\TRC-2013\Lateral Torsion Coupling\DLLUserTor\DLLUserTor\Debug\DLLUserTor.lib" "C:\Users\Brian\Documents\Visual Studio 2010\Projects\TRC-2013\Lateral Torsion Coupling\XLTorsion\Debug\XLTorsion_lib.lib" "C:\Users\Brian\Documents\Visual Studio 2010\Projects\TRC-2013\Lateral Torsion Coupling\XLTorsion\Code\KEY-LOK Security\KFUNC32.OBJ" "C:\Users\Brian\Documents\Visual Studio 2010\Projects\TRC-2013\Lateral Torsion Coupling\DLLUserTor\DLLUserTor\Debug\DLLUserTor.lib" "C:\Users\Brian\Documents\Visual Studio 2010\Projects\TRC-2013\Lateral Torsion Coupling\XLTorsion\Debug\XLTorsion_lib.lib" ]
Note that the C RTL is being explicitly ruled out. Linker options such as /nodefaultlib:libc are needed when there is a possibility of more than one version of the C RTL being used in a link job. What you need is that 1 (one, and only one) C RTL be used to link and build your EXE. You have to look at the various VS "project" settings to see why you ended up with specifying 0 (zero) versions of the C RTL instead.
I changed Fortran/Libraries from Debug Multithread to Debug Multithread DLL and it now builds and runs, but I do not understand why.
It did not seem to matter whether I used 'link_fnl_static.h' or 'link_fnl_shared.h'.
I'm relieved it's finally running, but I wish I knew why.
It's a C thing, where the compiler generates different code when linking against shared vs. static libraries. Fortran doesn't do this.
I would really like to get rid of the C component of this project. It only does one thing - repeatedly write progress messages to the console window on the same line by using printf(). I have read a couple of forum threads about doing this in fortran, which I think said it can be done easily enough, but is not "standard" fortran.
Unless you advise against it, I think I will go ahead and replace the C with fortran.
If you can do what you want all in Fortran, that would be fine. There are various ways of writing progress messages, some more standard than others.
I think I have successfully switched from C with prinft to Fortran with a $ sign as a format specifier.
Now that I've removed the C component from the project, I'm surprised that MSVCR100D.DLL still shows up in Dependency Walker. Is there a way to identify why the console program depends on this?
The project has a setting of Linker/Input/Ignore Specific Libraries libc; libcmtd but I don't know why or what this does. Trying to build w/o this gives an error of cannot open libc.lib.
I tested writing to the console window with a small test program, and that one doesn't have anything for Ignore Specific Libraries, and the .exe isn't dependent on any MSVCR DLL.
I should say that the code that still shows the dependence on MSCVRT DLL's uses IMSL with the following lines in the main program. Is this the reason for the dependence?
!DEC$ OBJCOMMENT LIB:'libiomp5md.lib'
libc,lib has not existed since VS2005. The linker setting is trying to avoid linking to variants of MSVC libraries that are incompatible with DLL linking. I would not expect a dependency on MSVCR100D.DLL unless you were building a Debug configuration using VS2010. I still think you should use link_fnl_shared.h. (and then you don't need the OBJCOMMENT directive.)
At the moment I am making a debug build, and I am using VS2010. My goal is build a single .exe without any dependencies on any DLL's other than one name DLLUserTor.DLL, which is unavoidable. That DLL is just standard fortran with one exported routine called by the main program.
Later today or tomorrow I will try the things you suggested. But I am stuck with VS2010.
As a general guideline (i.e. without taking specific care to avoid issues), if you have multiple executable modules (the windows operating system term - EXE's and DLL's basically) in your process then you need to use a DLL variant of any runtime library that is common to those executable modules. Otherwise you can end up with two instances of the runtime active in your process, and, without specific care, those instances can conflict at runtime over resources (memory, input/output aspects, exception handlers, thread control) that are inherently shared between them.
Recent compiler variants don't even provide static versions of the OMP runtime library as a consequence, because the inherently shared resources associated with the OMP runtime are very difficult to isolate.
The Release build doesn't have any dependency on a MSVCR DLL. So that's great.
But DWalker says there is a dependency on c:\program files (x86)\common files\intel\shared libraries\redist\intel64\compiler\LIBIOMP5MD.DLL
This is a 32 bit build. A dependency on 64 bit LIBIOMP5MD.DLL seems wrong? Is this going to be a problem?
I would like to eliminate the dependency on LIBIOMP5MD.DLL altogether. Is that possible?
Dependency walker can get confused when it encounters a DLL of the wrong bitness, ahead of a DLL of the relevant bitness in its search order.
As per the last paragraph of #14, if you use OpenMP with recent compilers you will always have a dependency on the OpenMP runtime DLL.
this old code doesn't need MPI. Fortran/Language/Process OpenMP Directives is set to Generate Parallel Code (/Qopenmp)
I changed this to Disable and rebuilt, but DWalker still says LIBIOMP5MD.DLL is in the dependencies.
What is the right way to turn off MPI?
With !DEC$ OBJCOMMENT LIB:'libiomp5md.lib' I get the dependency.
Without it I get 100+ linker errors like the following:
Error 159 error LNK2019: unresolved external symbol _omp_unset_nest_lock referenced in function _E1LOCK imsls_err.lib(e1lock.obj)