Reputation: 45
I have been trying to get Visual Studio Code to recognize the MSVC cl.exe compiler and build using it for the better part of a day now. I have tried two different methods (setting it up myself, and using VSCode add-on called Easy C++ projects to generate the code) of getting it up and running and both have failed in the same way, raising my suspicions that the point of failure might be somewhere out of my control.
#include <Windows.h>
int CALLBACK WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow )
{
//register windows class
const auto pClassName = "Test";
WNDCLASSEX wc = {0};
wc.cbSize = sizeof(wc);
wc.style = CS_OWNDC;
wc.lpfnWndProc = DefWindowProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = nullptr;
wc.hCursor = nullptr;
wc.hbrBackground = nullptr;
wc.lpszMenuName = nullptr;
wc.lpszClassName = pClassName;
wc.hIconSm = nullptr;
RegisterClassEx(&wc);
HWND hWnd = CreateWindowEx(
0, pClassName,
pClassName,
WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
200, 200, 640, 480,
nullptr, nullptr, hInstance, nullptr
);
ShowWindow(hWnd, SW_SHOW);
while(true);
return 0;
}
This is the main.cpp. There are no other source or header files in the project.
**********************************************************************
** Visual Studio 2019 Developer Command Prompt v16.4.3
** Copyright (c) 2019 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28315 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
/std:c++latest is provided as a preview of language features from the latest C++
working draft, and we're eager to hear about bugs and suggestions for improvements.
However, note that these features are provided as-is without support, and subject
to changes or removal as the working draft evolves. See
https://go.microsoft.com/fwlink/?linkid=2045807 for details.
main.cpp
Microsoft (R) Incremental Linker Version 14.24.28315.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:main.exe
/debug
/OUT:bin\main.exe
main.obj
main.obj : error LNK2019: unresolved external symbol __imp_DefWindowProcA referenced in function WinMain
main.obj : error LNK2019: unresolved external symbol __imp_RegisterClassExA referenced in function WinMain
main.obj : error LNK2019: unresolved external symbol __imp_CreateWindowExA referenced in function WinMain
main.obj : error LNK2019: unresolved external symbol __imp_ShowWindow referenced in function WinMain
bin\main.exe : fatal error LNK1120: 4 unresolved externals
Could Not Find d:\GIT_REPOS_PERSONAL\MorrowEngine\bin\*.ilk
'.\bin\main.exe' is not recognized as an internal or external command,
operable program or batch file.
The terminal process terminated with exit code: 1
This is the terminal output from trying to build. It fails to resolve symbols from 'Windows.h'. This is the problem, now lets talk about some of the methodology.
My approach was to set it up manually by setting up the C/C++ VSCode extension. So it turns out that the VSCode terminal does not have the correct environment set up to compile with cl.exe by default, and there is no officially supported method to have VSCode boot up with a terminal that runs a different set of environment variables.
This means that we have to lead VSCode to the .bat that sets up the environment at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat
It must set this terminal up with the correct environment in VSCode before using the SAME TERMINAL to run the main build task for the program.
With that in mind what I did was make a build.bat that will execute cl.exe only after running vcvarsall.bat
BUILD.BAT
@echo off
if exist "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" x64
) else (
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
)
set compilerflags=/Od /Zi /EHsc /std:c++latest /I include
set linkerflags=/OUT:bin\main.exe
cl.exe %compilerflags% src\*.cpp /link %linkerflags%
del bin\*.ilk *.obj *.pdb
TASKS.JSON
{
"version": "2.0.0",
"tasks": [
{
"label": "Build C++ project",
"type": "shell",
"group": {
"kind": "build",
"isDefault": true
},
"command": ".\\build.bat"
},
{
"label": "Build & run C++ project",
"type": "shell",
"group": {
"kind": "test",
"isDefault": true
},
"command": ".\\build.bat && .\\bin\\main.exe"
}
]
}
SETTINGS.JSON
{
"files.associations": {
"*.tpp": "cpp"
},
"terminal.integrated.shell.windows": "cmd.exe"
}
This is the entire configuration. I have checked the C/C++ extension to make sure it is configured as well for the default MSVC x64. The extension also links to the right cl.exe path and has no additional include paths other than the root workspace folder. I have VS2019 BuildTools and no copy of Visual Studio installed.
I can't think of anymore pertinent information off the top of my head, but I'm sure I left something out. Feel free to let me know.
Upvotes: 0
Views: 2723
Reputation: 45
paxbun coming in hot with the correct answer!
I needed to link user32.lib
Thank you sir!
Upvotes: 1