Skip to content

Instantly share code, notes, and snippets.

@AbdoCooder
Last active October 19, 2025 13:18
Show Gist options
  • Save AbdoCooder/69d7d022201ece38513104e85c9bfa86 to your computer and use it in GitHub Desktop.
Save AbdoCooder/69d7d022201ece38513104e85c9bfa86 to your computer and use it in GitHub Desktop.
Clang-in-a-Box: C++ Dev Environment | Automated Clang-Tidy & VS Code Setup

🧰 C++ Clang Development Environment Setup Script

This script automates the setup of a modern C++ development environment on Debian/Ubuntu-based systems for use with Visual Studio Code (VS Code).
It installs essential Clang tools, build utilities, and configures VS Code extensions for a clean, standardized workflow.


🚀 Features

🔧 1. Installs System Dependencies

Automatically installs:

  • clang-16, clangd-16, clang-tidy-16, clang-format-16
  • cmake, ninja-build

All via the system package manager (apt).


⚙️ 2. Configures System Alternatives

Sets the newly installed Clang tools as the default system-wide versions:

  • clangdclangd-16
  • clang-tidyclang-tidy-16
  • clang-formatclang-format-16

💻 3. Installs VS Code Extensions

Automatically installs recommended extensions:

  • C/C++ Language Support: llvm-vs-code-extensions.vscode-clangd
  • CMake Tools: ms-vscode.cmake-tools
  • Enhanced Diagnostics: usernamehw.errorlens

🧩 4. Creates Configuration Files

Generates workspace-specific configuration files for:

  • VS Code (.vscode/settings.json)
  • Clang Format (.clang-format)
  • Clangd (.clangd)

These ensure consistent formatting, diagnostics, and code analysis across your workspace.


🪄 Usage

  1. Save the setup.sh script in your project root.
  2. Open a terminal in that directory.
  3. Make it executable:
    chmod +x setup.sh
  4. Run the script:
    ./setup.sh
    You may be prompted for your password to install system packages.
  5. Reload VS Code to apply all settings.

🗂️ Generated Configuration Files

📁 .vscode/settings.json

Configures VS Code to:

  • Use clangd as the language server and formatter
  • Disable the default IntelliSense engine to avoid conflicts
  • Enable format-on-save and visual rulers
{
	"clangd.arguments": [
		"--background-index",
		"--clang-tidy",
		"--header-insertion=iwyu",
		"--compile-commands-dir=${workspaceFolder}/build/"
	],
	"C_Cpp.intelliSenseEngine": "Disabled",
	"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd",
	"editor.formatOnSave": true,
	"editor.rulers": [79]
}

🧾 .clang-format

Defines a Google-style formatting profile:

BasedOnStyle: Google

⚙️ .clangd

Specifies compiler flags, diagnostics, and linting configuration.

CompileFlags:
  Add: [
    "-std=c++98",
    "-Wall",
    "-Wextra",
    "-Werror",
    "-Wpedantic"
  ]

Diagnostics:
  ClangTidy:
    Add: [
      "bugprone-argument-comment",
      "bugprone-parent-virtual-call", 
      "readability-qualified-auto",
      "readability-redundant-string-cstr",
      "modernize-pass-by-value"
    ]
    Remove: ["*"]

Index:
  Background: Build

🧠 Notes

  • Designed for Debian/Ubuntu systems only.
  • Requires sudo privileges to install system packages.
  • Compatible with VS Code (not VS Code Insiders or OSS builds).

🏁 Result

After running the script, you’ll have a fully configured C++ environment featuring: ✅ Modern Clang tools
✅ Linting and formatting integration
✅ CMake + Ninja build support
✅ Seamless VS Code experience

#include <iostream>
#include <string>
// Error: missing #include <vector> for std::vector
// Warning: For-range loop copies an expensive object. Pass by const reference.
void print_names(std::vector<std::string> names) {
for (const auto& name : names) {
std::cout << "Name: " << name << std::endl;
}
}
int main() {
// Warning: variable is unused.
int unused_variable = 10;
// Warning: 5 is a "magic number". Use a named constant instead.
int magic_number = 5;
// Warning: Use nullptr instead of NULL in modern C++.
int* ptr = NULL;
std::vector<std::string> students;
students.push_back("Alice");
students.push_back("Bob");
print_names(students);
if (magic_number > 0) {
std::cout << "Hello, World!" << std::endl;
}
return 0;
}
#!/bin/bash
# --- Function to check for and install packages (apt-based systems) ---
install_packages() {
local packages=("$@")
local packages_to_install=()
for pkg in "${packages[@]}"; do
if ! command -v "$pkg" &> /dev/null; then
echo "Package '$pkg' not found. Adding to installation list."
packages_to_install+=("$pkg")
else
echo "Package '$pkg' is already installed."
fi
done
if [ ${#packages_to_install[@]} -gt 0 ]; then
echo "Installing missing packages: ${packages_to_install[*]}..."
sudo apt update
sudo apt install -y "${packages_to_install[@]}"
echo "Packages installed successfully."
else
echo "All required packages are already installed."
fi
}
# --- Main script starts here ---
echo "Starting C++ workspace setup for VS Code on Linux..."
# 1. Install necessary command-line tools
echo ""
echo "--- Step 1: Installing system prerequisites (clang, cmake, etc.) ---"
REQUIRED_DEBS=(clang-16 clangd-16 clang-tidy-16 clang-format-16 cmake ninja-build)
install_packages "${REQUIRED_DEBS[@]}"
# Update alternatives for the clang binaries to ensure VS Code finds them
echo ""
echo "--- Configuring system alternatives for Clang tools ---"
sudo update-alternatives --install /usr/bin/clangd clangd /usr/bin/clangd-16 100
sudo update-alternatives --install /usr/bin/clang-tidy clang-tidy /usr/bin/clang-tidy-16 100
sudo update-alternatives --install /usr/bin/clang-format clang-format /usr/bin/clang-format-16 100
echo "Clang tools configured."
# 2. Install essential VS Code extensions
echo ""
echo "--- Step 2: Installing VS Code extensions ---"
if ! command -v code &> /dev/null; then
echo "VS Code 'code' command not found. Please ensure VS Code is installed and in your PATH."
else
code --install-extension llvm-vs-code-extensions.vscode-clangd
code --install-extension ms-vscode.cmake-tools
code --install-extension usernamehw.errorlens # Provides inline errors
fi
# 3. Create .vscode directory and settings.json
echo ""
echo "--- Step 3: Configuring VS Code workspace settings ---"
mkdir -p .vscode
cat > .vscode/settings.json <<EOL
{
"clangd.arguments": [
"--background-index",
"--clang-tidy",
"--header-insertion=iwyu",
"--compile-commands-dir=\${workspaceFolder}/build/"
],
"C_Cpp.intelliSenseEngine": "Disabled",
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd",
"editor.formatOnSave": true,
"editor.rulers": [79],
}
EOL
echo ".vscode/settings.json configured."
# 4. Create clang-tidy, clang-format, and clangd config files
echo ""
cat > .clang-format <<EOL
BasedOnStyle: Google
EOL
echo ".clang-format config file created."
cat > .clangd <<EOL
CompileFlags:
Add: [
"-std=c++98", # C++98 language standard flag
"-Wall", # Enable all standard compiler warnings
"-Wextra",
"-Werror",
"-Wpedantic" # Enable pedantic warnings
]
Diagnostics:
ClangTidy:
Add: [
"bugprone-argument-comment",
"bugprone-parent-virtual-call",
"readability-qualified-auto",
"readability-redundant-string-cstr",
"modernize-pass-by-value"
]
Remove: ["*"]
# To enable/disable specific ClangTidy checks.
# Add: [check-name]
# Remove: [check-name]
# Configure clang-format for your desired C++98 coding style.
# This is typically configured in a separate .clang-format file.
# To disable formatting, you might need to use a different key or explicitly disable it via command-line arguments.
Index: # Corrected from Indexing
Background: Build
EOL
echo ".clangd config file created."
echo ""
echo "Setup complete! Reload the VS Code window for changes to take effect."
@AmmarHaddadi
Copy link

extremely gay BraceWrapping choices

@AbdoCooder
Copy link
Author

extremely gay BraceWrapping choices

I updated the style checks from the LLVM style to Google's style checking which I found more useful actually.

cat > .clang-format <<EOL
BasedOnStyle: Google
EOL

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment