Unresolved external symbol when I add glfw3.lib to compiler argument - linker

I have written a little batch file to compile a project from emacs and when I added a glfw3.lib to compiler argument I started to get this error:
LNK2019: unresolved external symbol glfwInit referenced in function WinMain.
So I created a project in Visual Studio 2012, added SAME libs and SAME includes, it magically compiled. What am I doing wrong?
This is my build.bat file:
#echo off
mkdir ..\Build
pushd ..\Build
cl -Zi ..\source\win32main.cpp -I..\includes user32.lib gdi32.lib opengl32.lib ..\libs\glew32.lib ..\libs\glfw3.lib
popd
Main file:
#include <windows.h>
#include <GL/glfw3.h>
int CALLBACK
WinMain(HINSTANCE Instance,
HINSTANCE PrevInstance,
LPSTR CommandLine,
int ShowCode)
{
glfwInit(); // Here is the error, but i don't get why?
return 0;
}

Problem solved when I added this flag to linker -nodefaultlib:libcmt.lib

Related

Rust missing libraries while linking static C libraary

I have encountered problem with linking static lib - when there no windows.h and calls to WinAPI, it links and works fine, but when they used, I get this error when building:
error: linking with `link.exe` failed: exit code: 1120
note: external-test.lib(library_win32.cpp.obj) : error LNK2019: unresolved external symbol __imp_MessageBoxW referenced in function init_window
In list of all used libs, there no user32.lib. Maybe it is the problem? How can I tell linker to use it
note: "C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\BuildTools\\VC\\Tools\\MSVC\\14.16.27023\\bin\\HostX64\\x64\\link.exe" ... "kernel32.lib" "advapi32.lib" "ws2_32.lib" "userenv.lib" "msvcrt.lib"
Here build script:
fn main() {
println!("cargo:rustc-link-search={}/src/external",env::var("CARGO_MANIFEST_DIR").unwrap());
}
Solution was simple - link user32 in build script

Unresolved ___stdio_common_vsprintf_s, what library has this?

I'm using VS2015 Community. I have obtained some C code that I'm trying to build. It is all in C and I have made a project as a Console Application.
When I build I get the below errors. The problem is that __stdio_common_vsprintf_s cannot be found during the link process. So I searched the internet for the symbols but don't get any useful information.
I am using the Runtime Library setting called Multi-threaded (/MT).
I have tried adding #define STDC_WANT_LIB_EXT1 1 before all includes but that did not help. I have searched for this problem and have not found any postings that help.
So I searched all of the VS libraries and got lots of hits but I don't know which are definitions and which are references. Then I searched all of the .h files in the VS include folder but no hits.
I suspect there may be another library that I need but don't know what it is. Does anyone have any ideas?
1>LIBCMT.lib(_error_.obj) : error LNK2019: unresolved external symbol ___stdio_common_vsprintf_s referenced in function __vsprintf_s_l
1>LIBCMT.lib(_pdblkup_.obj) : error LNK2019: unresolved external symbol ___vcrt_GetModuleFileNameW referenced in function "int __cdecl _RTC_GetSrcLine(unsigned char *,wchar_t *,unsigned long,int *,wchar_t *,unsigned long)" (?_RTC_GetSrcLine##YAHPAEPA_WKPAH1K#Z)
1>LIBCMT.lib(_pdblkup_.obj) : error LNK2019: unresolved external symbol ___vcrt_LoadLibraryExW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDllFromInstallPath(void)" (?GetPdbDllFromInstallPath##YAPAUHINSTANCE__##XZ)
1>MSVCRTD.lib(_chandler4gs_.obj) : error LNK2019: unresolved external symbol __except_handler4_common referenced in function __except_handler4
1>W:\efifs\Debug\testing.exe : fatal error LNK1120: 6 unresolved externals
Here are my options:
Compile
----------
/GS
/analyze-
/W3
/Zc:wchar_t
/I"W:\efifs\\gnu-efi\inc"
/I"W:\efifs\\gnu-efi\inc\ia32"
/I"W:\efifs\\grub\include"
/I"W:\efifs\\grub-core\lib\minilzo"
/I"W:\efifs\testing\"
/I"W:\efifs\\gnu-efi\inc\protocol"
/I"W:\efifs\\gnu-efi\lib"
/I"W:\efifs\\include"
/I"W:\efifs\\grub\grub-core\lib\minilzo"
/I"W:\efifs\.msvc"
/ZI
/Gm
/Od
/Fd"Debug\vc140.pdb"
/Zc:inline
/fp:precise
/D "__STDC_WANT_LIB_EXT1__=1"
/D "_UNICODE"
/D "UNICODE"
/D "GRUB_FILE=__FILE__"
/D "HAVE_USE_MS_ABI"
/D "GNU_EFI_USE_EXTERNAL_STDARG"
/D "DRIVERNAME=testing"
/D "WIN32"
/D "_DEBUG"
/D "_CONSOLE"
/errorReport:prompt
/WX-
/Zc:forScope
/RTC1
/Gd
/Oy-
/MT
/Fa"Debug\"
/EHsc
/nologo
/Fo"Debug\"
/Fp"Debug\testing.pch"
Link
-----
/OUT:"W:\efifs\Debug\testing.exe"
/MANIFEST
/NXCOMPAT
/PDB:"W:\efifs\Debug\testing.pdb"
/DYNAMICBASE "efifs.lib" "grub.lib" "gnu-efi.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"
/MACHINE:X86
/INCREMENTAL
/PGD:"W:\efifs\Debug\testing.pgd"
/SUBSYSTEM:CONSOLE
/MANIFESTUAC:"level='asInvoker' uiAccess='false'"
/ManifestFile:"Debug\testing.exe.intermediate.manifest"
/ERRORREPORT:PROMPT
/NOLOGO
/LIBPATH:"W:\efifs\testing\\grub"
/LIBPATH:"W:\efifs\testing\\efifs"
/LIBPATH:"W:\efifs\testing\\gnu-efi"
/TLBID:1
If you look how vsprintf is declared you can trace it corecrt_stdio ... where it says to inline it.
I had some old DLL which were linking against old msvcrt and trying to import vsprintf from it but seems like VS2015 have new headers and trying to inline it.
Setting _NO_CRT_STDIO_INLINE helped to resolve it, Enjoy.
Edit: Also https://msdn.microsoft.com/en-us/library/bb531344.aspx
You configuration appears to be incorrect. You don't seem to be linking with a couple of new libraries added in Visual Studio 2015's reorganization of the C runtime library. You also appear to linking with both the release static (/MT) and debug DLL (/MDd) version of the same library, specifically LIBCMT.lib and MSVCRTD.lib.
The symbol ___stdio_common_vsprintf_s can be found in the in Universal CRT which part of the Windows 10 SDK. The release static version of the library is called libucrt.lib. The other unresolved symbols are part of "vcruntime" library which is part of Visual Studio 2015. The name of it's release static version is libvcruntime.lib.
It not clear why you're not linking with the correct libraries. Normally this handled automatically for you. You'll need to check to your project's configuration settings to see where you've overridden the default behaviour.
You need insert this line
#define _NO_CRT_STDIO_INLINE
According to the C standard annex K
K.3.1.1 Standard headers
The functions, macros, and types declared or defined in K.3 and its subclauses are not
declared or defined by their respective headers if _ _STDC_WANT_LIB_EXT1_ _ is
defined as a macro which expands to the integer constant 0 at the point in the source file
where the appropriate header is first included.
Meaning that in order to use the "_s" functions such as vsprintf_s, which are all found in the mentioned annex, you must define that macro to a value other than 0 before including the header files.
#define __STDC_WANT_LIB_EXT1__ 1
#include <stdarg.h>
#include <stdio.h>
I suspect that you must have a C11 compiler. Whether or not Visual Studio follows that standard, I have no idea. It is notorious for its poor standard conformance.

Compile & link static library calling winapi under cygwin

I have a project in C which I am porting to from unix/linux to Windows/Cygwin (using autotools).
I need to call some winapi functions. These functions require inclusion of some windows headers. But when I specify those includes a lot of errors caused by redefinition of some structs or functions are raised.
So I decided to create a static library where all winapi function will be called to avoid these errors. But i have some difficulties getting it work.
For now the static library contains only one call of winapi function GetAdaptersAddresses and looks like this:
#include <windows.h>
#include <winsock2.h>
#include <iphlpapi.h>
void win_if_scan(void)
{
ULONG size = 10 * sizeof(IP_ADAPTER_ADDRESSES);
IP_ADAPTER_ADDRESSES *addresses = (IP_ADAPTER_ADDRESSES *)malloc(size);
GetAdaptersAddresses(AF_INET,
GAA_FLAG_INCLUDE_ALL_INTERFACES |
GAA_FLAG_INCLUDE_PREFIX |
GAA_FLAG_SKIP_DNS_SERVER,
NULL,
addresses,
&size);
}
and I am compiling the library libwin.a like this:
gcc libwin.c -liphlpapi -o libwin.o
ar crv libwin.a libwin.o
From the project I call the win_if_scan function (and I include header for the libwin). But I got error: undefined reference to WinMain, full message is:
$ make > /dev/null
/usr/lib/gcc/x86_64-pc-cygwin/4.9.2/../../../../lib/libcygwin.a(libcmain.o): In function `main':
/usr/src/debug/cygwin-1.7.33-1/winsup/cygwin/lib/libcmain.c:39: undefined reference to `WinMain'
/usr/src/debug/cygwin-1.7.33-1/winsup/cygwin/lib/libcmain.c:39:(.text.startup+0x7e): relocation truncated to fit: R_X86_64_PC32 against undefined symbol `WinMain'
collect2: error: ld returned 1 exit status
make[1]: *** [libwin.o] Error 1
make: *** [all] Error 2
I don't understand what is happening here. It is a library, why it requires main function? When I tried to add:
int main(void) { return 0; }
or
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { return 0; }
it indeed says multiple definition of main as expected.
How to get this work?
Or is there a better way how to handle redefinition errors between cygwin & windows headers?
First step is to generate only object file from libwin as I mentioned in the comment.
Second, the specification of the library -liphlpapi must go where the project is linked together, not where the object file is generated. Which makes sense since no linkage is done there.
So the library archive is created by following commands:
gcc -c libwin.c -o libwin.o
ar crv libwin.a libwin.o
and the project is linked together like this:
$(exedir)/bin: $(bin-dep)
$(CC) $(LDFLAGS) -o $# $^ ../libwin/libwin.a $(LIBS) -liphlpapi
which is a Makefile rule, where you can see where I added the ../libwin/libwin.a and -liphlpapi
This is still a work in progress, so sorry for not very nice or systematic solution, but the idea is there.
Important thing to have on mind is also location of the -liphlpapi in the Makefile rule as mentioned a here

Visual Studio C++ link with psapi.lib

I have written a C Program which calls the function, GetModuleInformation() which is defined in psapi.h
I am using Microsoft Visual Studio C++ command line compiler (cl.exe) for compiling and linking the program.
I have included the psapi.h header file:
#include <psapi.h>
when I try to compile using:
cl program.c
It generates the object file, however fails during the linking stage with the error:
program.obj : error LNK2019: unresolved external symbol _GetModuleInformation#16 ref
erenced in function _main
program.exe : fatal error LNK1120: 1 unresolved externalsprogram.obj : error LNK2019: unresolved external symbol _GetModuleInformation#16 ref
I also place the psapi.lib file in the same folder where the source code file (program.c) is placed, however even then I get the same error message as above.
How do I successfully link it using the command line compiler (cl.exe)?
Method 1
If you want to compile from the command line with cl.exe you can use the /link option to specify linker options :
cl /TC program.c /link psapi.lib
Method 2
The following pragma directive causes the linker to search in your source file for the psapi.lib library while linking .
#pragma comment( lib, "psapi.lib" )
Possible reason for your errors can be, if psapi.lib is missing in a list of additional libraries of linker.
To resolve this, use the following /LIBPATH option :
cl /TC program.c /link Psapi.Lib /LIBPATH:C:\MyLibFolder\
Where C:\MyLibFolder specifies a path to the folder, that contains your psapi.lib .
Also, you can try to set the proper /SUBSYSTEM option .
For a Console application use :
/SUBSYSTEM:CONSOLE
Solution to similar problem here .
Example on using the GetModuleInformation function :
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
#pragma comment( lib, "psapi.lib" )
int main(void)
{
MODULEINFO minfo = {0};
GetModuleInformation( GetCurrentProcess(), GetModuleHandle( "psapi.dll" ), &minfo, sizeof(minfo) );
/* printf("%X", minfo.lpBaseOfDll); /* The load address of the module */
return 0;
}
The code has been tested on Windows 7 and XP .
The output from linking session is :
program.c
/out:program.exe
psapi.lib
/LIBPATH:C:\MyLibFolder\
/SUBSYSTEM:CONSOLE
/VERBOSE
program.obj
Starting pass 1
Processed /DEFAULTLIB:uuid.lib
Processed /DEFAULTLIB:LIBCMT
Processed /DEFAULTLIB:OLDNAMES
Searching libraries
Searching C:\MyLibFolder\psapi.lib:
Found _GetModuleInformation#16
Referenced in program.obj
Loaded psapi.lib(PSAPI.DLL)
Found __IMPORT_DESCRIPTOR_PSAPI
Referenced in psapi.lib(PSAPI.DLL)
Loaded psapi.lib(PSAPI.DLL)
Found __NULL_IMPORT_DESCRIPTOR
Referenced in psapi.lib(PSAPI.DLL)
Loaded psapi.lib(PSAPI.DLL)
...
If vsvars32.bat and all appropriate environment variables in your Visual Studio are set correctly the above linker options will produce a valid executable(.exe) file.

GetUserName under Win64

I am trying to compile a C program using the Intel icl compiler under MINGW/64. The program uses the following code:
#include <Userenv.h>
HANDLE process;
HANLDE token;
GetUserProfileDirectory(process, TOKEN_QUERY, &ptoken)
I am using the following compile command:
$ icl -g -DMINGW32 -DTESTMAIN user.c -o user -UserEnv.Lib
and I am linking against the UserEnv.Lib from the Microsoft SDK.
Intel(R) C++ Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version Microsoft (R) Incremental Linker Version 9.00.21022.08
-out:user.exe
user.obj
user.obj : error LNK2019: unresolved external symbol __imp_GetUserProfileDirectoryA referenced in function main
Any idea how to solve this problem?
SOLUTION:
The solution is to use
/link /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Lib/x64/UserEnv.Lib /c/Program\ Files/Microsoft\ SDKs/Windows/v6.0A/Lib/x64/A
I copied the file UserEnv.lib from the Microsoft SDK (x64, 6.0) into the current working directory and compiled the program with
$ icl test.c -DMINGW32 ./UserEnv.Lib
LNK2019: unresolved external symbol __imp_GetUserNameA referenced in function main test.obj : error LNK2019: unresolved external symbol __imp_OpenProcessToken referenced in function main test.obj : error LNK2019: unresolved external symbol –
and I am still getting the unresolved symbols.
Olaf
You need to add userenv.lib to your input libraries for the linker to see GetUserProfileDirectory().
EDIT: It's been a while since I've touched an Intel compiler, but IIRC you're supposed to use /link to introduce linker options:
$ icl test.c -DMINGW32 /link ./UserEnv.Lib

Resources