I want to build a DLL file from my source code but I had an error. During the linking, the command line couldn't resolve so many objects and abandoned the linking.
I decided to split the objects into two libraries and then to create the DLL from the two libraries.
I run my makefile but the linking is breaking up with a new error: unresolved external symbol _DllMainCRTStartup#12
I use the following settings:
Compiler options: /Od /MT /EHsc /MP /Zi /Zl /Zp8 /c /DSOMEDEFINE
Linker options: /MAPINFO:EXPORTS /SUBSYSTEM:WINDOWS /MACHINE:X86 /MANIFEST /INCREMENTAL:NO /NOLOGO /DLL /DEBUG /OUT:"$(__NAME).dll" /LIBPATH:$(__MS_LIB_PATH) \
/LIBPATH:"$(SW_HOME)\lib" /LIBPATH:"$(SW_HOME)\common\lib" /PDB:"$(__NAME).pdb" /MAP:"$(__NAME).map"
My build process runs in three steps:
first step: compile all objects
second step: use lib.exe to create two files with extension *.LIB
third step: use link.exe to create DLL file from LIB files.
but I have a linking error like in my title.
So, I suppose that the problem happens because some paths to visual studio folder during linking are not correct or during the splitting of objects in two libraries, something is going wrong and some information is gone.
Or I use not the correct options for the compiler and the linker.
Could someone help me to resolve it?
This is not a direct answer to your question, but an explanation in simple English of what might be the problem.
If you call a function, you first have to provide a declaration for it. The compiler will check your call against the declaration. If the function is a library function the compiler will look for it in one of the library’s interface files (GetTickCount declaration is in WinBase.h, for instance). If you do not include the file where declaration is located, the compiler will issue an error (GetTickCount not found).
If the function you are calling is a library function, you will have to provide the library where the function is implemented (GetTickCount is located in kernel32.lib). If the linker does not find the function in the provided libraries, it will issue an error (unresolved external symbol GetTickCount).
You actually do not specify any libraries in your options, just some additional library paths (/LIBPATH). Therefore the linker does not find the implementation of the functions you are calling: “During the linking, the command line couldn't resolve so many objects and abandoned the linking.” This is how automatically generated options look like (notice the differences):
/OUT:"m:\temp\Win32Project1\Release\Win32Project1.dll"
/MANIFEST
/LTCG:incremental
/NXCOMPAT
/PDB:"m:\temp\Win32Project1\Release\Win32Project1.pdb"
/DYNAMICBASE "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib"
/IMPLIB:"m:\temp\Win32Project1\Release\Win32Project1.lib"
/DEBUG
/DLL
/MACHINE:X86
/OPT:REF
/SAFESEH
/INCREMENTAL:NO
/PGD:"m:\temp\Win32Project1\Release\Win32Project1.pgd"
/SUBSYSTEM:WINDOWS
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"Release\Win32Project1.dll.intermediate.manifest"
/OPT:ICF
/ERRORREPORT:PROMPT
/NOLOGO
/TLBID:1
Regarding the CRT, again let VC do the work for you. Let VC chose the Runtime Library:
/Yu"stdafx.h"
/GS /GL /analyze- /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2
/Fd"Release\vc140.pdb"
/Zc:inline
/fp:precise
/D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL" /D "WIN32PROJECT1_EXPORTS" /D "_WINDLL" /D "_UNICODE" /D "UNICODE"
/errorReport:prompt
/WX-
/Zc:forScope
/Gd /Oy- /Oi /MD
/Fa"Release\"
/EHsc
/nologo
/Fo"Release\"
/Fp"Release\Win32Project1.pch"
If you insist in doing things manually, here are some interesting readings:
CRT Library Features
/MD, /MT, /LD (Use Run-Time Library)
/ENTRY (Entry-Point Symbol)
Related
I'm trying to generate a DLL based on existing software pieces compiled in a static library (.lib) file. I'm using Visual Studio 2019, and the target is purely Windows.
The existing project (P1) have the following function :
int runLocal();
It's compiled to P1.lib.
In my new DLL project (P2), I have the following code :
#include "..\path\to\P1.h" // declaration of "int runLocal()"
extern "C" __declspec(dllexport) int __stdcall DLLMain() {
int res = runLocal();
std::cout << res << std::endl;
}
Project P2 (DLL) have following linker options :
Additional dependencies: D:\path\to\P1.lib;%(AdditionalDependencies)
However the linker "refuse" to see or use the lib file, and I get this error :
LNK2001 unresolved external symbol "int __stdcall runLocal(void)" (?runLocal##YGHXZ).
In fact, I get excatly the same error if I didn't tell the linker to use P1.lib file.
I have control over all the project sources, so I can change stuffs where it's necessary.
Note 1: The P2 project is used by a debug application (a third project compiled separately) that use LoadLibrary() to run the exported DLLMain function.
Note 2: I already succeeded in compiling an exe file against the same .lib file using the same method. So the difference seems to be in the DLL generation.
Note 3: I tried (without success) to play with many options in Visual project properties, in both compiler & linker section, at least the options that are not beyond my understanding.
So, what should I do to link correctly the .lib file and create my dll ?
Edit 1: I add the compiler & linker options:
P1 compiler options:
/permissive- /GS /TP /GL /analyze- /W3 /Gy /Zc:wchar_t
/I"C:\_tools\boost_1_68_0\" /I"C:\_tools\cryptopp_8_2_0\"
/Qspectre /guard:cf /Zi /Gm- /O2 /sdl /Fd"tmp_Win32_Release\p1.pdb" /Zc:inline
/fp:precise /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_CRT_SECURE_NO_WARNINGS"
/D "_UNICODE" /D "UNICODE" /D "_AFXDLL"
/errorReport:prompt /WX- /Zc:forScope /Gd /Oy /Oi /MD /std:c++17 /FC
/Fa"tmp_Win32_Release\" /EHsc /nologo
/Fo"tmp_Win32_Release\" /Ot /Fp"tmp_Win32_Release\p1.pch" /diagnostics:column
P1 librarian options:
/OUT:"D:\Projets\XL4DLL\Common\p1.lib" /LTCG /MACHINE:X86 /SUBSYSTEM:WINDOWS /NOLOGO
Checked with dumpbin.exe as suggested, and the symbol "?runLocal##YGHXZ" exists in p1.lib
P2 compiler options:
/permissive- /MP /GS /TP /GL /analyze- /W3 /Gy /Zc:wchar_t
/I"C:\_tools\boost_1_68_0\" /I"C:\_tools\cryptopp_8_2_0\"
/Qspectre /guard:cf /Zi /Gm- /O2 /sdl /Fd"tmp_Win32_Release\vc142.pdb"
/Zc:inline /fp:precise /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_USRDLL"
/D "_WINDLL" /D "_UNICODE" /D "UNICODE"
/errorReport:prompt /WX- /Zc:forScope /Gz /Oy /Oi /MD /std:c++17 /FC
/Fa"tmp_Win32_Release\" /EHsc /nologo /Fo"tmp_Win32_Release\" /Ot
/Fp"tmp_Win32_Release\XL4DLL32.pch" /diagnostics:column
P2 linker options:
/OUT:"D:\Projets\XL4DLL\Release\XL4DLL32.dll" /MANIFEST /LTCG:incremental
/NXCOMPAT /PDB:"D:\Projets\XL4DLL\Release\XL4DLL32.pdb" /DYNAMICBASE
"D:\Projets\XL4DLL\Common\p1.lib" "D:\Projets\XL4DLL\Common\SharedToolsLib32.lib"
"kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib"
"advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib"
"odbc32.lib" "odbccp32.lib"
/IMPLIB:"D:\Projets\XL4DLL\Release\XL4DLL32.lib" /DLL /MACHINE:X86
/OPT:REF /SAFESEH /INCREMENTAL:NO /PGD:"D:\Projets\XL4DLL\Release\XL4DLL32.pgd"
/SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"tmp_Win32_Release\XL4DLL32.dll.intermediate.manifest"
/OPT:ICF /ERRORREPORT:PROMPT /NOLOGO
/LIBPATH:"C:\_tools\boost_1_68_0\stage\lib" /TLBID:1
There is another difference between P1 and P2 projects configuration:
P1 is configured to use "Use MFC in a Shared DLL"
P2 is configured to use "Use Standard Windows Libraries", because it requires the use of Windows.h header and uses symbols not defined with MFC usage.
I am getting an error LNK1104 in Visual Studio :
LNK1104 cannot open file './x64/Release/zlib.lib'
when compiling my project.
The point is that I cannot see a corresponding path defined in Additional Dependencies of the linker in the project properties.
The error is shown when I add to the list of dependencies the right path to the zlib.lib or when I remove it.
here are the project compilation cmd line and linker :
/Yu"stdafx.h" /GS /GL /W3 /Gy /Zc:wchar_t /Zi /Gm- /O2 /sdl /Fd"C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\PMDFilter\temp\Release\vc140.pdb" /Zc:inline /fp:precise /D "NDEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /Gd /Oi /MD /Fa"C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\PMDFilter\temp\Release\" /EHsc /nologo /Fo"C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\PMDFilter\temp\Release\" /Fp"C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\PMDFilter\temp\Release\PMDFilter.pch"
and
/OUT:"C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\PMDFilter\bin\Release\PMDFilter.exe" /MANIFEST /LTCG:incremental /NXCOMPAT /PDB:"C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\PMDFilter\bin\Release\PMDFilter.pdb" /DYNAMICBASE "C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\opennurbs_20130711\bin\Release\opennurbs.lib" "C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\opennurbs_20130711\zlib\bin\Release\zlib.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /DEBUG /MACHINE:X64 /OPT:REF /INCREMENTAL:NO /PGD:"C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\PMDFilter\bin\Release\PMDFilter.pgd" /SUBSYSTEM:CONSOLE /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"C:\Users\me\Documents\Visual Studio 2015\Projects\AnalysePMDSurf\PMDFilter\temp\Release\PMDFilter.exe.intermediate.manifest" /OPT:ICF /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
Not sure, but have you tried two "\" instead one "\"?
Also, some of those errors might be Linker Tools Error LNK1104:
Not enough disk space.
File does not exist.
When specifying libraries in a project's property pages dialog box,
library names should be separated by spaces (and not commas).
Incorrect filename or path.
Invalid drive specification.
Insufficient file permissions.
Path for filename expands to more than 260 characters.
If the given file is named LNKn, which is a filename generated by the
linker for a temporary file, the directory specified in the TMP
environment variable may not exist, or more than one directory is
specified for the TMP environment variable. Only one directory path
should be specified for the TMP environment variable.
If the error message occurs for a library name, and you recently
ported the .mak file from a previous Microsoft Visual C++ development
system, the library may no longer be valid. Ensure that the library
still exists in this circumstance.
Another program may have the file open and the linker cannot write to
it.
Incorrect LIB environment variable. For information on how to update
the LIB environment variable, see VC++ Directories Property Page .
Make sure any directories with libraries you need are listed here.
Well I could solve it that way : create a new solution and new projects, copy-paste all the code files. Set the linking for the new projects and everything's fine.
In my solution I have two projects: one is a C++ DLL, and the other is a C# Windows Forms EXE (with the latter having a build dependency on the former). The DLL gets linked in correctly and works (my test function returns the right number, at least). The actually useful functionality is throwing an exception somewhere, but I can't debug it because none of the debug symbols for the C++ project are being loaded.
The PDB is definitely being generated! The EXE, DLL and PDB are all in the same folder. I even added their directory as one of the symbol file locations (Options > Debugging > Symbols), but this didn't do anything.
Apparently, the Modules window is supposed to tell you something, but my DLL doesn't appear there (yet it still works fine).
I'm using a x64 DLL with no compiled headers, if that makes any difference.
Compiler commandline:
/GS /W3 /Zc:wchar_t /I"E:\Users\Sean\Documents\Visual Studio 2015\Projects\MusicStreamingClient\MusicStreamingClient\RapidJson\include\" /ZI /Gm /Od /Fd"x64\Debug\vc140.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_WINDOWS" /D "_USRDLL" /D "MUSICSTREAMINGCLIENT_EXPORTS" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /Fa"x64\Debug\" /EHsc /nologo /Fo"x64\Debug\" /Fp"x64\Debug\MusicStreamingClient.pch"
Linker commandline:
/OUT:"E:\Users\Sean\Documents\Visual Studio 2015\Projects\MusicStreamingClient\x64\Debug\MusicStreamingClient.dll" /MANIFEST /NXCOMPAT /PDB:"E:\Users\Sean\Documents\Visual Studio 2015\Projects\MusicStreamingClient\x64\Debug\MusicStreamingClient.pdb" /DYNAMICBASE "E:\Users\Sean\Documents\Visual Studio 2015\Projects\MusicStreamingClient\MusicStreamingClient\RapidJson\x64\Debug\RapidJson.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /IMPLIB:"E:\Users\Sean\Documents\Visual Studio 2015\Projects\MusicStreamingClient\x64\Debug\MusicStreamingClient.lib" /DLL /MACHINE:X64 /INCREMENTAL /PGD:"E:\Users\Sean\Documents\Visual Studio 2015\Projects\MusicStreamingClient\x64\Debug\MusicStreamingClient.pgd" /SUBSYSTEM:WINDOWS /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /ManifestFile:"x64\Debug\MusicStreamingClient.dll.intermediate.manifest" /ERRORREPORT:PROMPT /NOLOGO /TLBID:1
Any help would be appreciated.
You are currently debugging Managed code only. Native symbols will not be visible. You need to change your debug option to enable both Managed and Native modes for your project.
I am attempting to convert a project from Visual Studio 2005 to 2010. (To write a plugin for Maya 2014 as it is x64 only).
To start I am compiling with VS2010 against Maya 2013 x86. This compilation and linking works fine with VS 2005 but with 2010 I get a raft of errors along the lines:
error LNK2019: unresolved external symbol "void __cdecl operator delete(void *,char const *,int)" (??3#YAXPAXPBDH#Z) referenced in function __unwindfunclet$?creator#exporter##SAPAXXZ$0
I have attached the command line that generates the output below (some parts omitted for clarities sake). You will note the VS toolset differs from 80 to 100 (2005 vs 2010) and the block { project libs compiled with VS2005 .sln file } is missing from 2010 linker. This block is the list of dependant projects compiled by Visual Studio as part of the solution build.
Do you know how I can get these locally built libs to show up in the 2010 linker? Should I even expect them too? And can anyone suggest other points of attack to resolve this?
2005 c/c++
/Od /I "C:\Program Files (x86)\Autodesk\Maya2013\include" /I {our engine include} /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "NT_PLUGIN" /D "REQUIRE_IOSTREAM" /D "_WINDLL" /FD /EHsc /MTd /Fp{pch file output} /Fo"Debug_2013\" /Fd"Debug_2013\vc80.pdb" /W3 /nologo /c /Zi /TP /errorReport:prompt
2010 c/c++
/I"C:\Program Files (x86)\Autodesk\Maya2013\include" /I{our engine include} /Zi /nologo /W3 /WX- /Od /Oy- /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "NT_PLUGIN" /D "REQUIRE_IOSTREAM" /D "_WINDLL" /Gm- /EHsc /MTd /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fp*{pch file output}* /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /TP
/analyze- /errorReport:prompt
2005 linker
/OUT:{dll output file} /NOLOGO /LIBPATH:"C:\Program Files (x86)\Autodesk\Maya2013\lib" /DLL /MANIFEST /MANIFESTFILE:{manifest output file} /NODEFAULTLIB:"libcmt.lib" /DEBUG /PDB:{pdb file} /MAP /IMPLIB:{import library} /ERRORREPORT:PROMPT Opengl32.lib pnglib_d.lib zlib_d.lib libeay32.lib ssleay32.lib Foundation.lib OpenMaya.lib OpenMayaUI.lib OpenMayaAnim.lib OpenMayaFX.lib OpenMayaRender.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib { project libs compiled with VS2005 .sln file }
/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin
2010 linker
/OUT:{dll output file} /NOLOGO /LIBPATH:"C:\Program Files (x86)\Autodesk\Maya2013\lib" /DLL "Opengl32.lib" "pnglib_d.lib" "zlib_d.lib" "libeay32.lib" "ssleay32.lib" "Foundation.lib" "OpenMaya.lib" "OpenMayaUI.lib" "OpenMayaAnim.lib" "OpenMayaFX.lib" "OpenMayaRender.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /NODEFAULTLIB:"libcmt.lib" /MANIFEST /ManifestFile:{manifest output file} /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:{pdb output file} /MAP /PGD:{pgd output file} /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:PROMPT
/subsystem:windows /dll /debug /export:initializePlugin /export:uninitializePlugin
Finally figured out the problem!!!!
Followed the "new way" Visual Studio 2010 has project dependancies listed. http://manski.net/2011/11/project-dependencies-in-visual-c/
This solved the "unresolved symbol" issues but created this error:
error MSB4006: There is a circular dependency in the target dependency graph
I solved this via the instructions here https://connect.microsoft.com/VisualStudio/feedback/details/534361/better-error-message-for-output-circular-dependency#details
Hope this saves someone a lot of trouble.
I have a project in Visual C++ 2010 (Win32 application, non-managed code) in which I'm experiencing a really strange behavior. I put a breakpoint and it simply does not break!
The clues:
A PDB file is generated in the exe file path.
The Debug/Modules window shows the message "Binary was not built with debug information.".
Loading the PDB file manually (Debug/Modules, right click on the executable module, Load Symbols From/Symbols Path then double click on the PDB file) says "A matching symbol file was not found on this folder.".
My settings:
C++/General/Debug Information Format: Program Database.
C++/Optimization: Disabled.
C++/Code generation/Runtime library: Multi-threaded Debug.
Linker/Debugging/Generate Debug Info: Yes.
Linker/Debugging/Generate program database: $(TargetDir)$(TargetName).pdb.
Compiler command line:
/I"..\..\calibur64k\include" /I"C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include" /Zi /nologo /W3 /WX- /Od /Oy- /D "D3D_DEBUG_INFO" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MTd /GS /fp:precise /Zc:wchar_t /Zc:forScope /Fp"Debug\calibur_app.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /analyze- /Zl /errorReport:queue
Linker command line:
/OUT:"C:\Users\David\Desktop\calibur64k\vs2010\Debug\calibur_app.exe" /INCREMENTAL:NO /NOLOGO "kernel32.lib" "user32.lib" "d3dcompiler.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "advapi32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" "C:\Users\David\Desktop\calibur64k\vs2010\Debug\calibur64k.lib" /MANIFEST /ManifestFile:"Debug\calibur_app.exe.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"C:\Users\David\Desktop\calibur64k\vs2010\Debug\calibur_app.pdb" /ASSEMBLYDEBUG /SUBSYSTEM:WINDOWS /PGD:"C:\Users\David\Desktop\calibur64k\vs2010\Debug\calibur_app.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE
Nothing I've found on the Internet helped me :( Any ideas guys? Thanks!
The problem has been solved by trial and error :)
For anyone could be interested in:
Linker/Manifest File/Generate Manifest: set it to No.
Linker/Manifest File/Allow Isolation: set it to No.
Linker/Embedded IDL/Ignore embedded IDL: set it to Yes.
That's it. Maybe the generated PDB file manifest or the executable manifest were wrongly setup for a C++ project?
Thanks for your answers.
My Settings of Visual c++ 2010:
Linker/Manifest File/Generate Manifest: Yes.
Linker/Manifest File/Allow Isolation: Yes.
Linker/Embedded IDL/Ignore embedded IDL: No.
I have used these settings in all of my programs and break points are successfully hit.
So, my inference is that what you have proposed might not be the right solution.