Skip to content

Instantly share code, notes, and snippets.

@DrFrankenstein
Last active January 7, 2021 00:32
Show Gist options
  • Save DrFrankenstein/9ea90183e308a14849aaad8b3c516f0f to your computer and use it in GitHub Desktop.
Save DrFrankenstein/9ea90183e308a14849aaad8b3c516f0f to your computer and use it in GitHub Desktop.
Build and run single-file C/C++ programs in Visual Studio
{
"configurations": [
{
"inheritEnvironments": [
"msvc_x64"
],
"name": "x64-Debug",
"includePath": [
"${workspaceRoot}\\..\\..\\Microsoft\\vcpkg\\installed\\x64-windows\\include",
"${env.INCLUDE}",
"${workspaceRoot}\\**"
],
"defines": [
"WIN32",
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"intelliSenseMode": "windows-msvc-x64",
"compilerSwitches": "/std:c++17"
},
{
"inheritEnvironments": [
"msvc_x64"
],
"name": "x64-Release",
"includePath": [
"${workspaceRoot}\\..\\..\\Microsoft\\vcpkg\\installed\\x64-windows\\include",
"${env.INCLUDE}",
"${workspaceRoot}\\**"
],
"defines": [
"WIN32",
"NDEBUG",
"UNICODE",
"_UNICODE"
],
"intelliSenseMode": "windows-msvc-x64",
"compilerSwitches": "/std:c++17 /Ox"
}
]
}

What's this? (Abstract)

These are sample files that, hopefully, will help you use a folder with single-file C/C++/Assembly programs in Visual Studio.

Why? (Rationale)

I use these files with my DrFrankenstein/prompts repository, which contains my solutions to Advent of Code, Project Euler, etc. problems. All of those solutions are self-contained, single-file programs. Maintaining a solution, CMakeLists, or Makefile for a bunch of small programs can get tedious, as a target needs to be added for each one. (Granted, CMake isn't that hard to use, but still...) I wanted to be able to just create a .c file, then build/run it with zero configuration.

This can also be used for running quick tests without creating a project. Just drop the (adjusted) config files where you need them and open the folder.

How? (Getting Started)

  1. Open your folder in Visual Studio (File/Open/Folder...). This requires VS 2017 or newer (I believe).
  2. In Solution Explorer, enable the "Show All Files" button.
  3. Copy the CppProperties.json file from this gist to your folder, and update the IncludePaths to point to your vcpkg include folder. Alternatively, you can remove that folder if you don't use vcpkg.
  4. Create a .vs folder (if missing) at the root of your folder, and copy the launch.vs.json and tasks.vs.json files to it.
  5. Update tasks.vs.json so that the CFLAGS and CPPFLAGS lines point to your vcpkg include folder. Alternatively, you can remove the /I flag completely if you don't use vcpkg. Add any flags you might want to use (such as optimizations).
  6. Right click a .c, .cpp, or .asm file, then select Build to compile it (sometimes it takes a couple of right clicks for the item to work). A .exe file will appear next to your source.
  7. To debug that .exe file, right-click it and select "Set as StartUp element", then hit F5.
  8. If you use the debugger, you can use the entries in launch.vs.json as a template to customize how your programs are launched.

Optional: I have all these files in my .gitignore, as the build setup is really up to whoever clones that repo.

How it Works (Implementation Details, Caveats)

The tasks file just calls nmake with ${fileBasename}.exe as the target, and compiler flags passed as environment variables. It takes advantage of the Predefined rules so that you don't need to create a Makefile for your folder. If you do need to customize how a specific program is compiled, you can create a makefile with rules just for those outliers.

The CppProperties file configures Intellisense to work with your folder.

Note that if you prefer using .cxx as the extension for your C++ files, you need to change CPPFLAGS to CXXFLAGS in the variables. If you use .cc for your C++ files, it'll use the CFLAGS variable, which may be undesired behaviour. This can be fixed by creating a Makefile with a custom .cc.exe rule (but that's what we've been trying to avoid, right? just use .cpp).

{
"version": "0.2.1",
"defaults": {},
"configurations": [
{
"type": "native",
"name": "aoc1.exe",
"project": "aoc\\2020\\aoc1.exe",
"projectTarget": "",
"args": [ "< input1.txt" ]
},
{
"type": "native",
"name": "aoc2.exe",
"project": "aoc\\2020\\aoc2.exe",
"projectTarget": "",
"args": ["< input2.txt"]
},
{
"type": "native",
"name": "aoc3.exe",
"project": "aoc\\2020\\aoc3.exe",
"projectTarget": "",
"args": ["< input3.txt"]
},
{
"type": "native",
"name": "aoc4.exe",
"project": "aoc\\2020\\aoc4.exe",
"projectTarget": "",
"args": [ "< input4.txt" ]
},
{
"type": "native",
"name": "aoc5.exe",
"project": "aoc\\2020\\aoc5.exe",
"projectTarget": "",
"args": ["< input5.txt"]
}
]
}
{
"version": "0.2.1",
"tasks": [
{
"contextType": "build",
"taskLabel": "Build",
"appliesTo": "*.c,*.cpp,*.asm",
"type": "launch",
"command": "nmake",
"args": [
"${fileBasename}.exe"
],
"envVars": {
"CFLAGS": "/IC:\\Users\\Carl\\Documents\\src\\Microsoft\\vcpkg\\installed\\x86-windows\\include /W4 /Zi",
"CPPFLAGS": "/IC:\\Users\\Carl\\Documents\\src\\Microsoft\\vcpkg\\installed\\x86-windows\\include /W4 /std:c++latest /EHsc /Zi",
"VSCMD_START_DIR": "\"${fileDirname}\""
},
"workingDirectory": "${fileDirname}"
},
{
"contextType": "clean",
"taskLabel": "Clean",
"appliesTo": "*.c,*.cpp,*.asm",
"type": "default",
"command": "cmd",
"args": [
"/c del ${fileBasename}.exe ${fileBasename}.obj ${fileBasename}.ilk ${fileBasename}.pdb"
],
"workingDirectory": "${fileDirname}"
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment