It's an boilerplate for usage of C/C++ and it's tools in a future project. Check out the docs below to be in an actual tune!
It was used only at actual Windows 10 x64 (TODO! check the Linux)!
Do all the steps from C/C++ for Visual Studio Code before usage.
!note: eslint, prettier, execa are not necessary for C++ project! (and by the way husky with commitlint too, but they're very convinient for following Git-flow principles).
So just take what you really need from the project.
!Strongly required the next list of tools to be used / installed / present at your PC:
- actual
VSCode(was tested with v1.96.4); - C/C++ for Visual Studio Code;
- C/C++ Extension Pack for Visual Studio Code;
- C/C++ Extension UI Themes for Visual Studio Code;
- Clangd Extension for Visual Studio Code (for linting);
- EditorConfig for Visual Studio Code;
- g++;
- gcc;
- gdb;
- clang, clang++, clang-tidy, clang-format and LLVM tools;
optional:
- Format Code Action for Visual Studio Code;
- VS Code ESLint extension;
- Prettier Formatter for Visual Studio Code;
note: It's a common practice for C/C++ languages tools collect them and place apart of your system (mean C:/Program Files etc). E.g. C:/Tools. It's expected in the project C:/Tools with adding to the Windows 's path environment variables.
Currently (Windows 10 x64):
C:/Tools/msys64/ucrt64/bin- GCC, the GNU Compiler Collection;C:/Tools/LLVM/bin- The LLVM Compiler Infrastructure Project;
Also this pathes must be added to the PATH environment (How to: Add Tool Locations to the PATH Environment Variable).
.husky- folder for husky's hooks (with hooks config);.vscode/settings.json- settings for appropraite work ofC/C++ corein the project at first and then (optionally) theESlintandPrettierVSCode extensions in a project (with a help ofFormat Code Actionextension). There're settings and scripts for a usage of the configs (and ignore) files in the project (i.e. links to ones config files) and there'send-of-line(EOF)property that is set toLF(i.e."files.eol": "\n");.vscode/launch.json- settings forC/C++code debugging;configs/- the folder includes config and ignore files for:ESlint,Prettier,Commitlintpackages. Currently about ignore files:node_modulesand a few more folders are ignored (check.gitignorefile);usefull_chunks- (optional!) the folder with usefull files and settings forgit(msys2version) and for adding quick access to theucrt64 terminalfromright-clickanywhere and examples of custombash scriptsfor compiling.exeof your project (@note: cwd will be is from wherebash scriptwas executed!)..editorconfig- the project common settings (as for now it's as in RSSchool recommended check the EditorConfig for VS Code for more.
notice:EditorConfigIDE extension required!);build/- built binaries of the project (note:build/compile_commands.jsonare strongly required for linter!);.gitignore- exludenode_modulesand a few more folders from git watching (likedistetc, check the file for more);LICENSE.txt- license file;package.json- the heart of all. Check the scripts (especially, the paths for linting/prettier'ing. Currently:'./src'). Scripts already have CLI prefixes to link with config and ignore files;
It's assumed that C/C++ lang tools are placed at their own folders inside C:/Tools/ and added to the PATH environment variable of Windows! Check the To add a path to the PATH environment variable for more.
- in
VSCodecreate newPowerShell terminal(Bashwon't suit, you'll get an error via compilation at Windows collect2.exe: error: ld returned 116 exit status / when using g++ with git bash and including ); - from
cwdgo to the folder with your*.cor*.cpp(orC/C++languages relative) files (e.g.cd src); - create
helloworld.cwithCcode insdie (don't forget to include headers); - run
gcc helloworld.c -o helloworld.exe; - run your new
.exefile (e.g../helloworld.exe); - the result will be in the terminal;
Check https://code.visualstudio.com/docs/languages/cpp#_create-a-hello-world-app for more;
Also useful Создание первой программы (RU);
Another way is to use Code Runner VSCode extenion to ease the compilation and execution processes. Don't forget to check the VSCode settings (Code-runner: Executor Map) to set the extension to proper way like this:
"code-runner.executorMap": {
"c": "cd $dirWithoutTrailingSlash && clang --target=x86_64-w64-windows-gnu -g -std=c23 $fileName -o $fileNameWithoutExt && ./$fileNameWithoutExt",
"cpp": "cd $dirWithoutTrailingSlash && clang++ --target=x86_64-w64-windows-gnu -g -std=c++23 $fileName -o $fileNameWithoutExt && ./$fileNameWithoutExt",
}or to link all the *.c or *.cpp files (glob patterns) into one main file
(@note! do not run code runner on files differ from main.(c|cpp) !
This params will work only for flat files structure!!!
otherwise link files manually with complier option -I
(e.g. gcc -g -std=c23 -Iinclude *.c -o main, where include (or whatever set folders) is a folder with *.h files (means, hey, compiler, look also for *.h files in the include folder!))
"code-runner.executorMap": {
"c": "cd $dirWithoutTrailingSlash && clang --target=x86_64-w64-windows-gnu -g -std=c23 *.c -o $fileNameWithoutExt && ./$fileNameWithoutExt",
"cpp": "cd $dirWithoutTrailingSlash && clang++ --target=x86_64-w64-windows-gnu -g -std=c++23 *.cpp -o $fileNameWithoutExt && ./$fileNameWithoutExt",
}about $fileName, $fileNameWithoutExt, $dirWithoutTrailingSlash read the Code Runner docs.
Debugging
-g flag is required for debugging (VSCode Debug C++: Why does the flow not stop at breakpoint?);
to ease the debugging process add .vscode/launch.json.
the two main settings are:
"program"=> e.g."program": "${fileDirname}/${fileBasenameNoExtension}.exe",path to the example_file.exe for debugging"miDebuggerPath"=> e.g."miDebuggerPath": "C:\\Tools\\msys64\\ucrt64\\bin\\gdb.exe",, path to the debugger (currently it's agdb).
${fileDirname}, ${fileBasenameNoExtension} here are VSCode variables. Learn about them (note: extremely usefull tool!) via Variables reference with examples (VSCode);
note!
clang and clang++ compilers won't work standalone!!! They're strongly required libs!!!, so that's why flag --target=x86_64-w64-windows-gnu is must be nested (for actual Windows especially)! Otherwise one'll have got the compilation error like this:
$ clang -std=c23 ./task.c -o task,exe
clang: warning: unable to find a Visual Studio installation; try running Clang from a developer command prompt [-Wmsvc-not-found]
task.c:2:10: fatal error: 'stdio.h' file not found
2 | #include <stdio.h>
| ^~~~~~~~~
1 error generated.check the using Clang in windows 10 for C/C++ for more.
it's required to be installed at your PC (and added to the PATH environment variable of Windows) / in VSCode :
- LLVM (e.g.
LLVM-20.1.5-win64.exeand installed toC:/Tools/LLVM); - clangd for Visual Studio Code;
- Clang-Format for Visual Studio Code;
then add following lines to the ./.vscode/settings.json
...
"[c]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
},
"[cpp]": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd"
},
"clangd.path": "C:\\Tools\\LLVM\\bin\\clangd.exe", // path to Clangd, required
"clangd.arguments": [
"--log=verbose", // logs of extension work
"--pretty", // logs formatting
"--background-index", // for indexing files
"--clang-tidy", // use clang-tidy in real time
"--header-insertion=iwyu", // include headers automatically (or set 'never')
"--completion-style=detailed", // autocomplete
"--enable-config" // required for .clangd config usage
],
"C_Cpp.intelliSenseEngine": "disabled", // disable C/C++
// extension intelliSense because we're using the clangd extension.
// Clangd conflicts with C/C++. Clangd is able "on fly" to show errors.build/compile_commands.json are strongly required for linter proper work! if they don't exist build binaries via Cmake + Ninja with
# enable build/compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)in the ./CMakeLists.txt.
note: Check the paths to msys64 folder (e.g. C/Tools/msys64/ucrt64)!
clang-tidy is a Linter for C and C++;
note
for technical reasons, .clang-format, .clang-tidy, .clangd configs work only from the root of the project.
Do not nest them to the ./configs/... (untidy, don't like that kind).
./.clang-format- contains rules for formatting theCandC++files' code. Feel free to change it as your wish (currently it's a custom K&R style, based onLLVMstyle, but withIndentWidth: 2instead ofIndentWidth: 4)../.clang-tidy- config for code lintering (Clang-Tidy docs. Currently set particularly toMozillachecks with AirBnB style param naming)../.clangd- config for Clangd VSCode extenion (clangd teach your editor C++) and don't forget about it's settings in the./.vscode/settings.json.
Clangd works only with clang, clang++ compilers (with --target=x86_64-w64-windows-gnu), no other way. Check the settings and params at ./.clangd and via official docs. Also check in the clangd settings: Clangd: Path => path to the clangd.exe (e.g. C:\\Tools\\LLVM\\bin\\clangd.exe) and don't forget to update the extension's databases (or enable Clangd: Check Updates in the Clangd extension settings).
One can ease the developer process just replacing a bunch of Windows specific installation tools (e.g. Git for Windows, Python, external: LLVM + tools, CMake, Ninja, even node.js!) to msys2 usage (with ucrt64 terminal preferred).
The msys2 with pacman will be the magic wand to rule all the developer tools and will ease their update process! It will produce the Linux portal inside your Windows 10x64.
Learn more about msys2: Pacman;
Learn more about Pacman: docs;
Learn more about Pacman: cheatsheet;
Learn more about msys2: Git ;
Learn more about msys2: Python ;
Learn more about msys2: CMake ;
Note
Don't forget to check (and to add if not done yet) that PATH (system variable) (as top as possible in the list)
contains full path to the installed msys2 folder with preferred terminal
(e,g. ucrt64 currently preferred or change / add folders you wish (e.g. clang64 that path will be
e.g. C:\Tools\msys64\clang64\bin))
with bin folder at the end!. E.g. (just below the %SYSTEMROOT%\System32\OpenSSH\):
C:\Tools\msys64\usr\bin
C:\Tools\msys64\ucrt64\bin
(with optional C:\Program Files\VSCode (check your VSCode folder path) at bottom of the list
to call code . from anywhere)
- update the installed tools
pacman -Syu- search for tool to download and to get info
pacman -Ss "tool_name or part_of_name"- install package
pacman -S "tool_name or part_of_name"- install the desired version of the package
pacman -U "packagefile_tar.zst"- remove package (!preferred command)
pacman -R "tool_name or part_of_name"or (!use with caution, can harm other relative packages!!!)
pacman -Rsc "tool_name or part_of_name"- install
clang(clang environmentincludingclangandclang++compilers )
pacman -S mingw-w64-ucrt-x86_64-clang- install
LLVM
pacman -S mingw-w64-ucrt-x86_64-llvm- install
LLVM extra tools (clangd etc)
pacman -S mingw-w64-ucrt-x86_64-clang-tools-extra- install
CMake
pacman -S mingw-w64-ucrt-x86_64-cmake- install
Ninja
pacman -S mingw-w64-ucrt-x86_64-ninjaoptional. install for your wish
- install
Git
pacman -S git- install
Git LFS
pacman -S mingw-w64-ucrt-x86_64-git-lfs- install
Node.js with npm
pacman -S mingw-w64-ucrt-x86_64-nodejs- install
npm for Node.js (only for reasons!)
pacman -S mingw-w64-ucrt-x86_64-npm- install
Python
(@note:msys2, similar toLinuxenvironment, already containspython, but better to sure)
pacman -S python- install
pip for Python
pacman -S python-pipoptional for Pacman. install for your wish
- install
midnight commander (mc)
pacman -S mc- install
wget
pacman -S wget- install
tree
pacman -S tree- install
curl
pacman -S curl- install
unzip
pacman -S unzip- install
zip
pacman -S zipoptional. Additional steps
-
set up
msys2Gitsimilar toGit-for-Windows(for now deal withmsys64/home/your_user_namefolder i.e.%HOME%)- copy
usefull_chunks/for git/git-prompt.shto thehomedirectory of themsys2(e.g.C:/Tools/msys64/home/Dmitriy Frostoffor from theucrt64terminal to~(i.e.%HOME%)) - copy fields start from the
usefull_chunks/for git/.bashrc(start from the comment# Bootstrap git-prompt.sh) to the end of your.bashrcfile - copy necessary fields from
usefull_chunks/for git/.gitconfigto your.gitconfig(check the comments inside!)
- copy
-
learn how to add
ucrt64 shell terminalto context menu (i.e.right-click) and check out theusefull_chunks/Win10 x64 ucrt64 terminal shell/msys2_ucrt64_shell.regas i did as for example))
Execa is a powerful tool for NodeJS based projects. it gives possibility to create CI/CD processes and to automate routine actions (like updating and regression testing of the boilerplate / project).
To install Execa run (as devDependencies)
npm i -D execaCheck the configs/execa/main.js script for details (it update's the boilerplate's packages and create configs/execa/update-error.log with result of the process).
for ease of use add the command to the package.json/scripts:
"scripts": {
"update:packages": "node ./configs/execa/main.js"
},suggestion:
one can automate process even more by creating script that update and run regression tesing of all the projects / boilerplates.
e.g. the directory of all projects / boilerplates is E:/Code learning. Then create script, let's name it update_all_packages.mjs with this logic (pay attention: E:/Code learning doesn't contain any npm packages! update_all_packages.mjs just imports Execa from the closest existing repo to prevent catalog pollution and bloating!):
E:/Code learning/update_all_packages.mjs example (click to view)
import {
execaNode,
ExecaError,
} from './boilerplate-eslint-prettier-husky/node_modules/execa/index.js';
import fs from 'fs/promises';
import path from 'path';
/**
* Write log file with date and `No errors logged.` inner.
* If `update-error.log` doesn't exist one will be created beside the script
*
* @param {string} pathToLogFile - path (absolute is preferred) to the log file
* @param {string} logMessage - log message for writing into the log file
*
* @returns {Promise<void>}
* @throws Error writing log: ${error.message}
*/
async function writeSuccessLogFile(pathToLogFile, logMessage) {
try {
// write logfile beside the script
await fs.appendFile(
pathToLogFile,
`[${new Date().toLocaleString()}]\n No errors logged.\n\n${logMessage}`,
);
console.log(`Log has been written to the ${pathToLogFile}`);
} catch (error) {
console.error(`Error writing log: ${error.message}`);
}
}
/**
* Write log file with date and error message inside.
* If `update-error.log` doesn't exist one will be created beside the script
*
* @param {string} pathToLogFile - path (absolute is preferred) to the log file
* @param {Error | ExecaError} error - object Error
*
* @returns {Promise<void>}
* @throws Error writing log: ${error.message}
*/
async function writeErrorLogFile(pathToLogFile, error) {
try {
// write logfile beside the script
await fs.appendFile(
pathToLogFile,
`[${new Date().toLocaleString()}] ${error.message}${
(error instanceof ExecaError ? error.stderr : error) ??
'No stderr available.'
}\n`,
);
console.log(`Log has been written to the ${pathToLogFile}`);
} catch (error) {
console.error(`Error writing log: ${error.message}`);
}
}
/**
* Execute NodeJS command `node path/to/script.js` for every path in the {@link array}.
* P.S. independantly to OS.
*
* @param {string[]} array - array of paths (strings)
* to boilerplate's / project ' s `configs/execa/main(js|ts)`
* @returns {Promise<string[]>}
* @throws ExecaError occur: ${error.message} - if error was thrown from the Execa
* @throws ${error.message} - if error happend in another one case
*/
async function runNodeScript(array) {
/** @type {string[]} */
const arrOfLogs = [];
for (const pathToScript of array) {
/** @type {string} */
const pathToScriptNormalized = path.resolve(pathToScript);
// configs/execa/main.(j|t)s is a folder with execa script (JavaScript or TypeScript one)
// this sctructure is the same (and must be the same!) in every project / boilerplate
/** @type {string} */
const currentScriptCWD = pathToScript.replace(
/\/configs\/execa\/main\.(j|t)s$/gi,
'',
);
// use `cwd` option to prevent paths problems!!!
try {
/**
* @type {import("./boilerplate-eslint-prettier-husky/node_modules/execa/index.d.ts").Result}
* @example
* string like this:
* 'start checking for outdated packages...
* All packages are up-to-date. Skipping npm update.
* Log has been written to the
* E:\Code learning\integration-playground__webpack-react-ts\configs\execa\update-error.log'
*/
const { stdout } = await execaNode(pathToScriptNormalized, {
cwd: currentScriptCWD,
verbose: 'full',
cleanup: true,
});
arrOfLogs.push(stdout ?? 'empty stdout');
console.log(`${currentScriptCWD}: successfully executed!`);
} catch (error) {
if (error instanceof ExecaError) {
console.error(`ExecaError occur: ${error.message}`);
} else {
console.error(error.message);
}
}
}
return arrOfLogs;
}
/**
* Update the project's | bolerplate's packages and run commands / tests
* for regression testing and compatibility. If errors occur check the `update-projects-packages.log`
* or `update-error.log` in the boilerplate's / project's configs/execa/update-error.log
*
* @returns {Promise<void>}
* @throws An error occured: ${error.message}
*/
async function main() {
const currentDir = path.resolve();
const logFile = path.resolve(currentDir, `./update-projects-packages.log`);
/** @type {string[]} */
const arrOfScriptpaths = [
'./integration-playground__webpack-react-ts/configs/execa/main.js',
'./integration-playground__webpack-react-js/configs/execa/main.js',
'./boilerplate-webpack-gulp-html-scss-ts-components/configs/execa/main.js',
'./boilerplate-webpack-gulp-html-scss-js-components/configs/execa/main.js',
'./design-patterns/configs/execa/main.js',
'./boilerplate-codewars/configs/execa/main.js',
'./boilerplate-eslint-prettier-husky/configs/execa/main.js',
'./boilerplate-jest/configs/execa/main.js',
'./boilerplate-webpack-react-js/configs/execa/main.js',
'./boilerplate-webpack-react-ts/configs/execa/main.js',
'./rs_school/rsschool-cv/configs/execa/main.js',
'./youtube-dl_utility/configs/execa/main.js',
];
// clean up the log file
await fs.writeFile(logFile, '');
console.log(`start running updating scripts...`);
try {
/** @type {string[]} */
const logMessage = await runNodeScript(arrOfScriptpaths);
// write logfile beside the script
await writeSuccessLogFile(logFile, logMessage.join('\n\n'));
} catch (error) {
console.error(`An error occured: ${error.message}`);
// write logfile beside the script
await writeErrorLogFile(logFile, error);
}
}
main();then just run node update_all_packages.mjs from the E:/Code learning and check logs in the terminal and E:/Code learning/update-projects-packages.log for details.
Execa contains all the necessary types annotations and it's scripts can be written in TypeScript (Execa and TypeScript). In a next coming releases of NodeJS that will support TypeScript as native one it will be pretty sweet for usage)
Integration with Connections links:
To integrate the boilerplate do the following steps (note: copy the project structure as is!!!):
@note all the next pathes are cwd relative.
It's assumed that LLVM (with clang-tidy and clang-format)
is installed in your system and added to the path environment => C:/Tools/LLVM/bin and compilers are installed:
-
clang,clang++(andpath environment=>C:/Tools/LLVM/bin) (must have forclangdreal time linter, won't work otherwise) andgcc,g++,gdb(andpath environment=>C:/Tools/msys64/ucrt64/bin) -
copy:
.clang-format
.clang-tidy
.clangd
.editorconfig
.gitignore
build
.vscode -
check out files and pathes to the compilers / debuggers to suit your system and folders layout!!!
(currently =>C:/Tools/):
.vscode/c_cpp_properties.json:configurations...{intelliSenseMode...},configurations...{compilerPath...},configurations...{compileCommands...},configurations...{cStandard...},configurations...{cppStandard...}
.vscode/settings.json:"[c]","[cpp]","clangd.path","clangd.arguments","C_Cpp.default.compilerPath"
.vscode/launch.json:"configurations"...{ "miDebuggerPath" }
use clangd and Doxygen Documentation Generator extensions for
VSCode.optionally (
TS/JSlinting / formatting,Huskyfor commit messages checking (to suit togit - flow)):
@note all the next pathes are cwd relative.copy:
configs,.husky
install the npm packages:
npm i -D @commitlint/cli @commitlint/config-conventional eslint-config-airbnb-base eslint-config-prettier eslint eslint-plugin-import execa husky prettier
copy from .vscode/settings.json all the data till "[c]"...
use format-code-action extension for VSCode (real - time linting and formatting on save).
With the new packages releases, the ones above can turn to pumpkin, so check'em out with official docs!!!
- vscode-cpptools;
- C/C++ for Visual Studio Code;
- C/C++ for Visual Studio Code extension;
- Clangd Extension for Visual Studio Code (for linting);
- gcc official GitHub repo;
- GCC, the GNU Compiler Collection, official documentation;
- GDB: The GNU Project Debugger, official documentation;
- clang, clang++, clang-tidy, clang-format and LLVM tools;
- VSCode Debug C++: Why does the flow not stop at breakpoint?;
- How to setup VS Code for C++ with clangd support?;
- How can I find out the version of MSYS2 from its bash shell;
- How to determine the LLVM version?;
- Variables reference (VSCode settings);
- LLVM;
- LLVM (github releases);
- clang, clang++, clang-tidy, clang-format and LLVM tools;
- clangd for Visual Studio Code;
- clangd: teach your editor C++;
- clang-tidy official documentation;
- Clang-Format for Visual Studio Code;
- using Clang in windows 10 for C/C++;
- MSYS2 official documentation;
- MSYS2 official GitHub repo;
- Learn more about MSYS2: Package Management;
- Learn more about MSYS2: Pacman;
- Learn more about Pacman: docs;
- Learn more about Pacman: cheatsheet;
- Learn more about MSYS2: Git ;
- Learn more about MSYS2: Python ;
- Learn more about MSYS2: CMake ;
- Open MSYS2 terminal here (mingw-w64) from right-click menu;
- Using Prettier and ESLint to automate formatting and fixing JavaScript by Rob O'Leary (Feb 11, 2022);
- ESlint official documentation;
Changes with ESlint v9.0.0 coming soon! (flat config, ES modules).
TODO! Change then theeslintrc.cjs=>eslint.config.jsand dig deeper using Docs! - VS Code ESLint extension by Microsoft;
- eslint rules recommended;
- eslint-config-airbnb-base by airbnb;
- eslint-config-airbnb-typescript at npmjs.com;
- The official github of the eslint-config-airbnb-typescript;
- The official website of typescript-eslint;
- The official github of the typescript-eslint;
- @typescript-eslint/eslint-plugin at npmjs.com;
note: deprecated now! Check the typescript-eslint Setup for actual one. - @typescript-eslint/parser at npmjs.com;
note: deprecated now! Check the typescript-eslint Setup for actual one. - Actual typescript-eslint Setup;
- Legacy typescript-eslint Setup;
- plugin:@typescript-eslint/recommended rules;
- the official page of eslint-plugin-import at npmjs.com;
- the official github repo of eslint-plugin-import;
- eslint-config-prettier by prettier;
- In an eslint config, do 'extends' in an 'overrides' replace or do they merge with 'extends' up in the main section?;
- Prettier official documentation; TODO! Changes coming soon, check the prettier configs;
- Prettier Formatter for Visual Studio Code by Prettier;
-
Husky official documentation;
Changes coming soon! New features will take place. TODO! Change the husky and commitlint configs!