🔝 Retour au Sommaire
Maintenant que vous comprenez la structure d’un fichier .devcontainer.json, nous allons configurer les quatre outils essentiels pour le développement C professionnel :
L’objectif de cette section est de créer un DevContainer complet et fonctionnel avec tous ces outils correctement configurés et intégrés à VS Code.
Analogie : C’est comme équiper un atelier de menuiserie avec les bons outils, correctement rangés et réglés. GCC est la scie principale, GDB est la loupe pour inspecter les détails, CMake est le plan de travail organisé, et Valgrind est le détecteur de défauts.
Avant de commencer, assurez-vous d’avoir :
docker --version
# Docker version 24.x.x ou supérieur
docker ps
# Devrait s'exécuter sans erreur
Pour cette section, nous allons créer la structure suivante :
mon-projet-c/
├── .devcontainer/
│ └── devcontainer.json
├── .vscode/
│ ├── tasks.json
│ ├── launch.json
│ └── c_cpp_properties.json
├── src/
│ └── main.c
├── include/
│ └── (fichiers .h)
├── build/
│ └── (fichiers générés par CMake)
├── CMakeLists.txt
└── README.md
GCC (GNU Compiler Collection) est le compilateur standard sous Linux. Il transforme votre code source C (.c) en un programme exécutable que l’ordinateur peut lancer.
L’image Microsoft pour C/C++ contient déjà GCC :
{
"name": "Projet C avec GCC",
"image": "mcr.microsoft.com/devcontainers/cpp:ubuntu-22.04"
}
Cette image inclut :
Si vous partez d’une image Ubuntu de base :
{
"name": "Projet C - GCC manuel",
"image": "ubuntu:22.04",
"postCreateCommand": "apt-get update && apt-get install -y build-essential"
}
Le paquet build-essential installe GCC, G++, Make et les bibliothèques essentielles.
Pour installer une version précise de GCC :
{
"name": "Projet C - GCC 12",
"image": "ubuntu:22.04",
"postCreateCommand": "apt-get update && apt-get install -y gcc-12 g++-12 make && update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 && update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-12 100"
}
Pour que VS Code comprenne votre configuration GCC, créez ou modifiez le fichier .vscode/c_cpp_properties.json :
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/include",
"/usr/include/**",
"/usr/local/include/**"
],
"defines": [],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "linux-gcc-x64"
}
],
"version": 4
}
Explications :
| Paramètre | Description |
|---|---|
includePath |
Dossiers oĂą chercher les fichiers .h |
compilerPath |
Chemin vers le compilateur GCC |
cStandard |
Norme C Ă utiliser (c11, c17, c23) |
intelliSenseMode |
Mode d’analyse pour Linux avec GCC |
Dans le devcontainer.json, définissez les options de compilation par défaut :
{
"remoteEnv": {
"CC": "gcc",
"CXX": "g++",
"CFLAGS": "-Wall -Wextra -Werror -std=c17 -g",
"LDFLAGS": ""
}
}
Signification des flags :
| Flag | Description |
|---|---|
-Wall |
Active tous les avertissements courants |
-Wextra |
Active des avertissements supplémentaires |
-Werror |
Traite les avertissements comme des erreurs |
-std=c17 |
Utilise la norme C17 |
-g |
Inclut les symboles de débogage (pour GDB) |
Créez .vscode/tasks.json pour compiler facilement :
{
"version": "2.0.0",
"tasks": [
{
"label": "GCC: Compiler le fichier actuel",
"type": "shell",
"command": "gcc",
"args": [
"-Wall",
"-Wextra",
"-std=c17",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"],
"detail": "Compile le fichier C actuel avec GCC"
},
{
"label": "GCC: Compiler tout le projet",
"type": "shell",
"command": "gcc",
"args": [
"-Wall",
"-Wextra",
"-std=c17",
"-g",
"${workspaceFolder}/src/*.c",
"-I${workspaceFolder}/include",
"-o",
"${workspaceFolder}/build/programme"
],
"problemMatcher": ["$gcc"],
"detail": "Compile tous les fichiers .c du dossier src"
}
]
}
Utilisation :
Ctrl+Shift+B : Lance la tâche de build par défautCtrl+Shift+P → « Tasks: Run Task » : Choisir une tâche spécifiqueGDB (GNU Debugger) est l’outil qui vous permet de :
Analogie : C’est comme un médecin qui peut mettre un patient « en pause » pour examiner son état interne à tout moment.
{
"image": "mcr.microsoft.com/devcontainers/cpp:ubuntu-22.04"
}
GDB est déjà installé dans cette image.
{
"postCreateCommand": "apt-get update && apt-get install -y gdb"
}
IMPORTANT : GDB nécessite des permissions spéciales pour fonctionner dans un conteneur Docker.
{
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt", "seccomp=unconfined"
]
}
Explications :
| Option | Pourquoi c’est nécessaire |
|---|---|
--cap-add=SYS_PTRACE |
Permet à GDB de s’attacher aux processus |
--security-opt seccomp=unconfined |
Désactive les restrictions de sécurité qui bloquent le débogage |
Sans ces options, vous aurez des erreurs comme :
Could not attach to process
ptrace: Operation not permitted
Créez .vscode/launch.json pour configurer le débogueur VS Code :
{
"version": "0.2.0",
"configurations": [
{
"name": "GDB: Déboguer le fichier actuel",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Activer le pretty-printing pour GDB",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Définir le mode de désassemblage sur Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "GCC: Compiler le fichier actuel",
"miDebuggerPath": "/usr/bin/gdb"
},
{
"name": "GDB: Déboguer le projet CMake",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/mon_programme",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Activer le pretty-printing pour GDB",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "CMake: Build",
"miDebuggerPath": "/usr/bin/gdb"
},
{
"name": "GDB: Attacher Ă un processus",
"type": "cppdbg",
"request": "attach",
"program": "${workspaceFolder}/build/mon_programme",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
Paramètres importants :
| Paramètre | Description |
|---|---|
program |
Chemin vers l’exécutable à déboguer |
args |
Arguments passés au programme |
stopAtEntry |
S’arrêter au début de main() si true |
preLaunchTask |
Tâche à exécuter avant le débogage (compilation) |
miDebuggerPath |
Chemin vers GDB |
F5 ou menu Run → Start DebuggingF10 : Step Over (ligne suivante, sans entrer dans les fonctions)F11 : Step Into (entrer dans la fonction)Shift+F11 : Step Out (sortir de la fonction)F5 : Continue (jusqu’au prochain breakpoint)Pour des fonctionnalités avancées, créez un fichier .gdbinit à la racine du projet :
# Activer l'historique des commandes
set history save on
set history size 10000
set history filename ~/.gdb_history
# Affichage amélioré
set print pretty on
set print array on
set print array-indexes on
# Pagination désactivée (pour les longues sorties)
set pagination off
# Confirmer avant de quitter
set confirm off
# Définir des alias utiles
define parray
set $i = 0
while $i < $arg1
printf "[%d] = ", $i
print $arg0[$i]
set $i = $i + 1
end
end
document parray
Print array elements. Usage: parray array_name length
end
CMake est un système de build moderne qui génère automatiquement les fichiers de compilation (Makefile, Ninja, etc.) à partir d’une description de haut niveau.
Avantages par rapport Ă un Makefile manuel :
Analogie : Si le Makefile est une liste d’instructions détaillées pour construire une maison, CMake est l’architecte qui génère ces instructions automatiquement à partir d’un plan simplifié.
{
"image": "mcr.microsoft.com/devcontainers/cpp:ubuntu-22.04"
}
CMake est déjà inclus.
{
"postCreateCommand": "apt-get update && apt-get install -y cmake"
}
Les dépôts Ubuntu ont parfois des versions anciennes. Pour une version récente :
{
"postCreateCommand": "apt-get update && apt-get install -y wget && wget -qO- 'https://apt.kitware.com/keys/kitware-archive-latest.asc' | gpg --dearmor -o /usr/share/keyrings/kitware-archive-keyring.gpg && echo 'deb [signed-by=/usr/share/keyrings/kitware-archive-keyring.gpg] https://apt.kitware.com/ubuntu/ jammy main' | tee /etc/apt/sources.list.d/kitware.list && apt-get update && apt-get install -y cmake"
}
Dans le devcontainer.json :
{
"customizations": {
"vscode": {
"extensions": [
"ms-vscode.cpptools",
"ms-vscode.cmake-tools",
"twxs.cmake"
]
}
}
}
Extensions :
| Extension | Fonction |
|---|---|
ms-vscode.cmake-tools |
Intégration CMake complète dans VS Code |
twxs.cmake |
Coloration syntaxique pour CMakeLists.txt |
Créez CMakeLists.txt à la racine du projet :
# Version minimale de CMake requise
cmake_minimum_required(VERSION 3.16)
# Nom du projet et langage
project(MonProjetC
VERSION 1.0.0
DESCRIPTION "Un projet C d'exemple"
LANGUAGES C
)
# Standard C Ă utiliser
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
# Options de compilation
# Mode Debug par défaut si non spécifié
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()
# Flags de compilation selon le mode
set(CMAKE_C_FLAGS_DEBUG "-g -O0 -Wall -Wextra -Werror -DDEBUG")
set(CMAKE_C_FLAGS_RELEASE "-O2 -Wall -Wextra -DNDEBUG")
# Afficher le mode de compilation
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
# Dossier des headers
include_directories(${PROJECT_SOURCE_DIR}/include)
# Collecter tous les fichiers source
file(GLOB SOURCES "src/*.c")
# Créer l'exécutable
add_executable(${PROJECT_NAME} ${SOURCES})
# Optionnel : Lier des bibliothèques
# target_link_libraries(${PROJECT_NAME} m pthread)
# Afficher un résumé
message(STATUS "Project: ${PROJECT_NAME}")
message(STATUS "Version: ${PROJECT_VERSION}")
message(STATUS "C Standard: ${CMAKE_C_STANDARD}")
cmake_minimum_required(VERSION 3.16)
project(MonProjetC
VERSION 1.0.0
LANGUAGES C
)
# Options configurables
option(BUILD_TESTS "Build unit tests" ON)
option(ENABLE_SANITIZERS "Enable AddressSanitizer and UBSan" OFF)
# Standard C
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
# Flags de base
add_compile_options(-Wall -Wextra)
# Sanitizers (optionnel)
if(ENABLE_SANITIZERS)
add_compile_options(-fsanitize=address,undefined -fno-omit-frame-pointer)
add_link_options(-fsanitize=address,undefined)
endif()
# Headers
include_directories(${PROJECT_SOURCE_DIR}/include)
# Bibliothèque principale (pour réutilisation dans les tests)
file(GLOB LIB_SOURCES "src/*.c")
list(REMOVE_ITEM LIB_SOURCES "${PROJECT_SOURCE_DIR}/src/main.c")
add_library(${PROJECT_NAME}_lib STATIC ${LIB_SOURCES})
# Exécutable principal
add_executable(${PROJECT_NAME} src/main.c)
target_link_libraries(${PROJECT_NAME} ${PROJECT_NAME}_lib)
# Tests (optionnel)
if(BUILD_TESTS)
enable_testing()
file(GLOB TEST_SOURCES "tests/*.c")
foreach(TEST_SOURCE ${TEST_SOURCES})
get_filename_component(TEST_NAME ${TEST_SOURCE} NAME_WE)
add_executable(${TEST_NAME} ${TEST_SOURCE})
target_link_libraries(${TEST_NAME} ${PROJECT_NAME}_lib)
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME})
endforeach()
endif()
# Installation (optionnel)
install(TARGETS ${PROJECT_NAME} DESTINATION bin)
Créez .vscode/settings.json (ou ajoutez dans le devcontainer.json) :
{
"cmake.configureOnOpen": true,
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.generator": "Unix Makefiles",
"cmake.configureSettings": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
}
}
Explications :
| Paramètre | Description |
|---|---|
configureOnOpen |
Configure automatiquement à l’ouverture du projet |
buildDirectory |
Dossier pour les fichiers générés |
generator |
Type de fichiers de build (Makefile, Ninja) |
CMAKE_EXPORT_COMPILE_COMMANDS |
Génère un fichier pour IntelliSense |
Ajoutez ces tâches dans .vscode/tasks.json :
{
"version": "2.0.0",
"tasks": [
{
"label": "CMake: Configure",
"type": "shell",
"command": "cmake",
"args": [
"-S", "${workspaceFolder}",
"-B", "${workspaceFolder}/build",
"-DCMAKE_BUILD_TYPE=Debug",
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
],
"group": "build",
"problemMatcher": []
},
{
"label": "CMake: Build",
"type": "shell",
"command": "cmake",
"args": [
"--build", "${workspaceFolder}/build",
"--parallel"
],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"],
"dependsOn": ["CMake: Configure"]
},
{
"label": "CMake: Clean",
"type": "shell",
"command": "cmake",
"args": [
"--build", "${workspaceFolder}/build",
"--target", "clean"
],
"problemMatcher": []
},
{
"label": "CMake: Rebuild",
"type": "shell",
"command": "cmake",
"args": [
"--build", "${workspaceFolder}/build",
"--clean-first",
"--parallel"
],
"problemMatcher": ["$gcc"]
}
]
}
# 1. Créer le dossier de build
mkdir -p build
cd build
# 2. Configurer le projet
cmake .. -DCMAKE_BUILD_TYPE=Debug
# 3. Compiler
cmake --build . --parallel
# 4. Exécuter
./MonProjetC
# 5. Lancer les tests (si configurés)
ctest --output-on-failure
Avec VS Code et l’extension CMake Tools :
Ctrl+Shift+P → « CMake: Configure »Ctrl+Shift+P → « CMake: Build » (ou F7)Ctrl+Shift+P → « CMake: Debug » (ou cliquez sur l’icône de débogage en bas)Valgrind est un outil d’analyse mémoire qui détecte :
Analogie : C’est comme un inspecteur sanitaire qui vérifie que vous n’avez pas laissé de robinets ouverts, que vous n’avez pas mangé de nourriture périmée, et que vous avez bien rangé après utilisation.
{
"postCreateCommand": "apt-get update && apt-get install -y valgrind"
}
valgrind --version
# valgrind-3.18.1 ou similaire
Valgrind n’a pas besoin de configuration complexe, mais quelques options sont utiles.
# Vérification de base des fuites mémoire
valgrind ./mon_programme
# Vérification détaillée avec origine des erreurs
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes ./mon_programme
# Avec log dans un fichier
valgrind --leak-check=full --log-file=valgrind.log ./mon_programme
| Option | Description |
|---|---|
--leak-check=full |
Détaille toutes les fuites |
--show-leak-kinds=all |
Montre tous les types de fuites |
--track-origins=yes |
Indique l’origine des valeurs non initialisées |
--verbose |
Mode verbeux |
--log-file=<file> |
Enregistre dans un fichier |
--suppressions=<file> |
Ignore certaines erreurs connues |
Ajoutez dans .vscode/tasks.json :
{
"version": "2.0.0",
"tasks": [
{
"label": "Valgrind: Vérifier les fuites mémoire",
"type": "shell",
"command": "valgrind",
"args": [
"--leak-check=full",
"--show-leak-kinds=all",
"--track-origins=yes",
"--verbose",
"${workspaceFolder}/build/${workspaceFolderBasename}"
],
"problemMatcher": [],
"dependsOn": ["CMake: Build"],
"detail": "Lance Valgrind pour détecter les fuites mémoire"
},
{
"label": "Valgrind: Fichier actuel",
"type": "shell",
"command": "valgrind",
"args": [
"--leak-check=full",
"--show-leak-kinds=all",
"--track-origins=yes",
"${fileDirname}/${fileBasenameNoExtension}"
],
"problemMatcher": [],
"dependsOn": ["GCC: Compiler le fichier actuel"],
"detail": "Lance Valgrind sur le fichier compilé actuel"
},
{
"label": "Valgrind: Générer rapport",
"type": "shell",
"command": "valgrind",
"args": [
"--leak-check=full",
"--show-leak-kinds=all",
"--track-origins=yes",
"--log-file=${workspaceFolder}/valgrind-report.txt",
"${workspaceFolder}/build/${workspaceFolderBasename}"
],
"problemMatcher": [],
"detail": "Génère un rapport Valgrind dans valgrind-report.txt"
}
]
}
#include <stdlib.h>
#include <stdio.h>
int main(void) {
// Fuite mémoire : allocation sans free
int *leak = malloc(10 * sizeof(int));
leak[0] = 42;
// Accès hors limites
int *array = malloc(5 * sizeof(int));
array[5] = 100; // Erreur ! Index max = 4
free(array);
// Variable non initialisée
int *uninit = malloc(sizeof(int));
if (*uninit > 0) { // Lecture d'une valeur non initialisée
printf("Positif\n");
}
free(uninit);
// leak n'est jamais libéré = fuite mémoire
return 0;
}
==12345== Memcheck, a memory error detector
==12345== Invalid write of size 4
==12345== at 0x4005E7: main (exemple.c:12)
==12345== Address 0x5204054 is 0 bytes after a block of size 20 alloc'd
==12345== at 0x4C2FB0F: malloc (in /usr/lib/valgrind/...)
==12345== by 0x4005D1: main (exemple.c:11)
==12345==
==12345== Conditional jump or move depends on uninitialised value(s)
==12345== at 0x400600: main (exemple.c:17)
==12345==
==12345== LEAK SUMMARY:
==12345== definitely lost: 40 bytes in 1 blocks
==12345== indirectly lost: 0 bytes in 0 blocks
==12345== possibly lost: 0 bytes in 0 blocks
==12345== still reachable: 0 bytes in 0 blocks
==12345== suppressed: 0 bytes in 0 blocks
Comment lire ce rapport :
Certaines bibliothèques système génèrent des « fausses alertes ». Créez .valgrind-suppressions :
{
ignore_libc_cond
Memcheck:Cond
...
obj:/lib/x86_64-linux-gnu/libc-*.so
}
Utilisez-le avec :
valgrind --suppressions=.valgrind-suppressions ./programme
Créez .devcontainer/valgrind-check.sh :
#!/bin/bash
# Script de vérification mémoire avec Valgrind
PROGRAM="${1:-./build/MonProjetC}"
REPORT="valgrind-report-$(date +%Y%m%d-%H%M%S).txt"
echo "=== Analyse Valgrind de $PROGRAM ==="
echo ""
valgrind \
--leak-check=full \
--show-leak-kinds=all \
--track-origins=yes \
--verbose \
--log-file="$REPORT" \
"$PROGRAM"
echo ""
echo "=== Résumé ==="
# Extraire les informations importantes
grep -E "(definitely|indirectly|possibly|still reachable|ERROR SUMMARY)" "$REPORT"
echo ""
echo "Rapport complet : $REPORT"
# Vérifier s'il y a des erreurs
if grep -q "ERROR SUMMARY: 0 errors" "$REPORT"; then
echo "✓ Aucune erreur mémoire détectée"
exit 0
else
echo "✗ Erreurs mémoire détectées, consultez le rapport"
exit 1
fi
Rendez-le exécutable :
chmod +x .devcontainer/valgrind-check.sh
Voici le fichier .devcontainer/devcontainer.json complet intégrant tous les outils :
{
// ============================================
// IDENTIFICATION
// ============================================
"name": "Environnement C Complet - GCC/GDB/CMake/Valgrind",
// ============================================
// IMAGE DE BASE
// ============================================
"image": "mcr.microsoft.com/devcontainers/cpp:ubuntu-22.04",
// ============================================
// FEATURES
// ============================================
"features": {
"ghcr.io/devcontainers/features/common-utils:2": {
"installZsh": true,
"installOhMyZsh": true,
"upgradePackages": true
}
},
// ============================================
// EXTENSIONS VS CODE
// ============================================
"customizations": {
"vscode": {
"extensions": [
// C/C++ essentiels
"ms-vscode.cpptools",
"ms-vscode.cpptools-extension-pack",
// CMake
"ms-vscode.cmake-tools",
"twxs.cmake",
// Makefile
"ms-vscode.makefile-tools",
// Qualité de code
"usernamehw.errorlens",
"oderwat.indent-rainbow",
"streetsidesoftware.code-spell-checker",
// Git
"eamodio.gitlens",
// Utilitaires
"gruntfuggly.todo-tree",
"mhutchie.git-graph"
],
"settings": {
// ========== C/C++ ==========
"C_Cpp.default.cStandard": "c17",
"C_Cpp.default.compilerPath": "/usr/bin/gcc",
"C_Cpp.default.intelliSenseMode": "linux-gcc-x64",
"C_Cpp.clang_format_fallbackStyle": "{ BasedOnStyle: LLVM, IndentWidth: 4, ColumnLimit: 80 }",
"C_Cpp.errorSquiggles": "enabled",
// ========== CMake ==========
"cmake.configureOnOpen": true,
"cmake.buildDirectory": "${workspaceFolder}/build",
"cmake.generator": "Unix Makefiles",
"cmake.configureSettings": {
"CMAKE_BUILD_TYPE": "Debug",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
},
// ========== Éditeur ==========
"editor.formatOnSave": true,
"editor.tabSize": 4,
"editor.insertSpaces": true,
"editor.rulers": [80, 120],
"editor.renderWhitespace": "boundary",
// ========== Fichiers ==========
"files.eol": "\n",
"files.trimTrailingWhitespace": true,
"files.insertFinalNewline": true,
"files.associations": {
"*.h": "c"
},
// ========== Terminal ==========
"terminal.integrated.defaultProfile.linux": "zsh"
}
}
},
// ============================================
// INSTALLATION DES OUTILS SUPPLÉMENTAIRES
// ============================================
"postCreateCommand": "sudo apt-get update && sudo apt-get install -y valgrind clang-format cppcheck && echo '✓ Outils supplémentaires installés'",
// ============================================
// VARIABLES D'ENVIRONNEMENT
// ============================================
"remoteEnv": {
"CC": "gcc",
"CXX": "g++",
"CFLAGS": "-Wall -Wextra -std=c17",
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
},
// ============================================
// OPTIONS DOCKER POUR GDB
// ============================================
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt", "seccomp=unconfined"
],
// ============================================
// UTILISATEUR
// ============================================
"remoteUser": "vscode"
}
{
"configurations": [
{
"name": "Linux",
"includePath": [
"${workspaceFolder}/**",
"${workspaceFolder}/include",
"/usr/include/**",
"/usr/local/include/**"
],
"defines": [
"DEBUG"
],
"compilerPath": "/usr/bin/gcc",
"cStandard": "c17",
"cppStandard": "c++17",
"intelliSenseMode": "linux-gcc-x64",
"configurationProvider": "ms-vscode.cmake-tools",
"compileCommands": "${workspaceFolder}/build/compile_commands.json"
}
],
"version": 4
}
{
"version": "2.0.0",
"tasks": [
// ========== GCC ==========
{
"label": "GCC: Compiler fichier actuel",
"type": "shell",
"command": "gcc",
"args": [
"-Wall", "-Wextra", "-std=c17", "-g",
"${file}",
"-o", "${fileDirname}/${fileBasenameNoExtension}"
],
"group": "build",
"problemMatcher": ["$gcc"]
},
{
"label": "GCC: Compiler avec sanitizers",
"type": "shell",
"command": "gcc",
"args": [
"-Wall", "-Wextra", "-std=c17", "-g",
"-fsanitize=address,undefined",
"-fno-omit-frame-pointer",
"${file}",
"-o", "${fileDirname}/${fileBasenameNoExtension}"
],
"problemMatcher": ["$gcc"]
},
// ========== CMake ==========
{
"label": "CMake: Configure",
"type": "shell",
"command": "cmake",
"args": [
"-S", "${workspaceFolder}",
"-B", "${workspaceFolder}/build",
"-DCMAKE_BUILD_TYPE=Debug",
"-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
],
"problemMatcher": []
},
{
"label": "CMake: Build",
"type": "shell",
"command": "cmake",
"args": ["--build", "${workspaceFolder}/build", "--parallel"],
"group": {
"kind": "build",
"isDefault": true
},
"problemMatcher": ["$gcc"],
"dependsOn": ["CMake: Configure"]
},
{
"label": "CMake: Clean",
"type": "shell",
"command": "cmake",
"args": ["--build", "${workspaceFolder}/build", "--target", "clean"],
"problemMatcher": []
},
{
"label": "CMake: Release",
"type": "shell",
"command": "cmake",
"args": [
"-S", "${workspaceFolder}",
"-B", "${workspaceFolder}/build-release",
"-DCMAKE_BUILD_TYPE=Release"
],
"problemMatcher": []
},
// ========== Valgrind ==========
{
"label": "Valgrind: Vérifier fichier actuel",
"type": "shell",
"command": "valgrind",
"args": [
"--leak-check=full",
"--show-leak-kinds=all",
"--track-origins=yes",
"${fileDirname}/${fileBasenameNoExtension}"
],
"problemMatcher": [],
"dependsOn": ["GCC: Compiler fichier actuel"]
},
{
"label": "Valgrind: Vérifier projet CMake",
"type": "shell",
"command": "valgrind",
"args": [
"--leak-check=full",
"--show-leak-kinds=all",
"--track-origins=yes",
"${workspaceFolder}/build/${workspaceFolderBasename}"
],
"problemMatcher": [],
"dependsOn": ["CMake: Build"]
},
// ========== Analyse statique ==========
{
"label": "Cppcheck: Analyser le projet",
"type": "shell",
"command": "cppcheck",
"args": [
"--enable=all",
"--std=c17",
"--suppress=missingIncludeSystem",
"-I", "${workspaceFolder}/include",
"${workspaceFolder}/src"
],
"problemMatcher": []
}
]
}
{
"version": "0.2.0",
"configurations": [
{
"name": "GDB: Fichier actuel",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/${fileBasenameNoExtension}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "GCC: Compiler fichier actuel",
"miDebuggerPath": "/usr/bin/gdb"
},
{
"name": "GDB: Projet CMake (Debug)",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/${workspaceFolderBasename}",
"args": [],
"stopAtEntry": false,
"cwd": "${workspaceFolder}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
],
"preLaunchTask": "CMake: Build",
"miDebuggerPath": "/usr/bin/gdb"
},
{
"name": "GDB: Avec arguments",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/build/${workspaceFolderBasename}",
"args": ["arg1", "arg2", "arg3"],
"stopAtEntry": true,
"cwd": "${workspaceFolder}",
"environment": [
{"name": "DEBUG", "value": "1"}
],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb"
},
{
"name": "GDB: Attacher Ă un processus",
"type": "cppdbg",
"request": "attach",
"program": "${workspaceFolder}/build/${workspaceFolderBasename}",
"processId": "${command:pickProcess}",
"MIMode": "gdb",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}
Créez un fichier test-toolchain.sh à la racine :
#!/bin/bash
echo "=== Test de la toolchain ==="
echo ""
echo "1. GCC"
gcc --version | head -1
echo ""
echo "2. GDB"
gdb --version | head -1
echo ""
echo "3. CMake"
cmake --version | head -1
echo ""
echo "4. Valgrind"
valgrind --version
echo ""
echo "5. Make"
make --version | head -1
echo ""
echo "6. clang-format"
clang-format --version
echo ""
echo "7. cppcheck"
cppcheck --version
echo ""
echo "=== Tous les outils sont installés ! ==="
Créez src/main.c :
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
printf("=== Test de l'environnement ===\n");
// Test allocation mémoire
int *numbers = malloc(5 * sizeof(int));
if (numbers == NULL) {
fprintf(stderr, "Erreur d'allocation\n");
return EXIT_FAILURE;
}
for (int i = 0; i < 5; i++) {
numbers[i] = i * 10;
printf("numbers[%d] = %d\n", i, numbers[i]);
}
// Libération correcte
free(numbers);
printf("=== Test réussi ! ===\n");
return EXIT_SUCCESS;
}
Vérifications :
# Compiler avec GCC
gcc -Wall -Wextra -g -std=c17 src/main.c -o test_prog
# Exécuter
./test_prog
# Vérifier avec Valgrind
valgrind --leak-check=full ./test_prog
Symptôme : Erreur « ptrace: Operation not permitted »
Solution : Vérifiez que les runArgs sont présents dans devcontainer.json :
{
"runArgs": [
"--cap-add=SYS_PTRACE",
"--security-opt", "seccomp=unconfined"
]
}
Puis reconstruisez le conteneur : Ctrl+Shift+P → « Dev Containers: Rebuild Container »
Symptôme : « No CMAKE_C_COMPILER could be found »
Solution : Vérifiez que GCC est installé :
which gcc
gcc --version
Si non installé, ajoutez dans postCreateCommand :
{
"postCreateCommand": "apt-get update && apt-get install -y build-essential"
}
Symptôme : Beaucoup d’erreurs dans les bibliothèques système
Solution : Utilisez un fichier de suppression ou ignorez les erreurs systèmes :
valgrind --gen-suppressions=all ./programme 2>&1 | grep -v "==" > suppressions.txt
Symptôme : Pas d’auto-complétion, squiggles rouges partout
Solutions :
Générez compile_commands.json avec CMake :
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
Vérifiez .vscode/c_cpp_properties.json
Rechargez VS Code : Ctrl+Shift+P → « Developer: Reload Window »
Ă€ ce stade, vous avez :
Prochaine étape : Dans la section 2.5.4, nous verrons comment intégrer ce DevContainer avec VS Code et faciliter l’onboarding de nouveaux développeurs.
-Wall -Wextra -g en développement--cap-add=SYS_PTRACE dans DockerCMAKE_EXPORT_COMPILE_COMMANDS=ON pour IntelliSense--leak-check=full --track-origins=yes pour le maximum d’informationsdevcontainer.json.devcontainer/, .vscode/)