Outils

Exécuter du code depuis Visual Studio Code

Avec un tel nom, il est évident que Visual Studio Code permet de lancer du code… mais comment faire pour exécuter mon fichier ?

Installer le plugin Code Runner

J’utilise depuis quelques temps le plugin Code Runner et il fait bien le taff. Il permet d’exécuter un snippet ou un fichier et la liste des langages supportés est longue comme le bras :

Run code snippet or code file for multiple languages: C, C++, Java, JavaScript, PHP, Python, Perl, Perl 6, Ruby, Go, Lua, Groovy, PowerShell, BAT/CMD, BASH/SH, F# Script, F# (.NET Core), C# Script, C# (.NET Core), VBScript, TypeScript, CoffeeScript, Scala, Swift, Julia, Crystal, OCaml Script, R, AppleScript, Elixir, Visual Basic .NET, Clojure, Haxe, Objective-C, Rust, Racket, Scheme, AutoHotkey, AutoIt, Kotlin, Dart, Free Pascal, Haskell, Nim, D, Lisp, Kit, V, and custom command

Rappel pour installer un plugin : dans la barre de gauche, il suffit cliquer sur le bouton des plugins dans la barre de gauche (c’est celui avec des carrés façon puzzle, hein) et de chercher le nom du plugin (ici code runner). Vous sélectionner votre plugin dans la liste et vous faites Install :

Exécuter du code

Voilà, c’est bon ! Vous pouvez exécuter du code ! La documentation nous dit qu’il y a plusieurs façons de faire :

To run code:

  • use shortcut Ctrl+Alt+N
  • or press F1 and then select/type Run Code,
  • or right click the Text Editor and then click Run Code in > editor context menu
  • or click Run Code button in editor title menu
  • or click Run Code button in context menu of file explorer

Exemple avec Python

Vous écrivez un fichier main.py, vous faites Crtl+Alt+N (ou une autre technique de votre choix) et c’est tout !

Vous vous demandez d’où vient cette commande python -u pour éxecuter mon fichier ? C’est tout simple : Code Runner a une liste de commandes pour les différents langages supportés et c’est comme ça qu’il réussit à exécuter mon fichier main.py.

A noter : il faut sélectionner votre fichier pour pouvoir l’exécuter (en cliquant dessus dans l’éditeur). Son extension est importante puisque Code Runner s’en sert pour déterminer le langage utilisé et donc comment l’exécuter.

Exemple avec C++

Essayons maintenant avec un petit main.cpp :

#include <iostream>

template <typename... Args>
void all_true(Args... args)
{
    auto ok = (args and ...);
    std::cout << (ok ? "OK" : "Nope") << '\n';
}

int main()
{
    all_true(true, 12 == 3 * 4, 6 * 111 / 66 == 11);
    all_true(42, 1 + 1 == 2);
}

Résultat :

[Running] cd "c:\Users\z19100018\Desktop\temp\article_visual_studio_code\"
          && g++ main.cpp -o main
          && "c:\Users\z19100018\Desktop\temp\article_visual_studio_code\"main
main.cpp: In function 'void all_true(Args ...)':
main.cpp:6:25: warning: fold-expressions only available with -std=c++1z or -std=gnu++1z
    auto ok = (args and ...);
                        ^~~
Nope
OK

[Done] exited with code=0 in 1.066 seconds

Ben oui : mon code utilise une fold expression de C++17, la commande par défaut pour le C++ ne précise pas le standard, et il est probable que mon MinGW64 n’utilise pas cette version du standard par défaut.

Accessoirement, je n’ai pas exactement envie de compiler sans les options -Wall -Wextra

Mais, alors ? Je fais quoi ? Et bien je modifie la commande par défaut !

Personnaliser les commandes de Code Runner

La commande par défaut peut ne pas vous convenir :

  • Pour Python, ça prend la version qui est dans le PATH mais je peux vouloir choisir d’utiliser la 3 plutôt que la 2.
  • Pour C++, je n’ai pas mes flags préférés.
  • Et ça sera peut-être / sans doute pareil pour d’autres langages…

La solution est d’utiliser de modifier le fichier settings.json de Visual Studio Code, le fichier magique qui contient les paramètres de Visual Studio Code. Appuyez sur F1 (la touche magique pour chercher partout), tapez « Settings » et choisissez « Preferences: Open Settings (JSON) » :

Ca ouvre votre settings.json et si vous n’avez pas encore rien configuré, il devrait juste contenir deux accolades : du JSON avec rien dedans.

Pour chaque langage que Code Runner supporte, vous pouvez ajouter une entrée dans code-runner.executorMap. Voici mon fichier avec ma commande pour C++ :

{
    "code-runner.executorMap": {
        "cpp": "cd $dir && g++ -std=c++17 -Wall -Wextra $fileName 
               -o $fileNameWithoutExt && $dir$fileNameWithoutExt"
    },
    "files.autoSave": "afterDelay"
}

Si vous vous demandez à quoi sert l’autre ligne, c’est simplement pour activer la sauvegarde automatique des fichiers. Oui, j’aime pas passer mon temps à faire Crtl+S.

Remarquez que la commande contient la variable $fileName : c’est pour ça qu’il faut sélectionner votre fichier pour pouvoir l’exécuter.

Si je refais Crtl+Alt+N sur mon fichier main.cpp, c’est évidemment bien mieux :

[Running] cd "c:\Users\z19100018\Desktop\temp\article_visual_studio_code\" 
         && g++ -std=c++17 -Wall -Wextra main.cpp -o main 
         && "c:\Users\z19100018\Desktop\temp\article_visual_studio_code\"main
Nope
OK

[Done] exited with code=0 in 1.291 seconds

Pour plus de détails

Je pense que l’essentiel a été dit. Pour plus de détails, je vous laisse parcourir la La documentation officielle.

Allez, faut que je vous laisse, j’ai du code à exécuter !


Quelques trucs avec CMake

CMake, c’est bien, c’est puissant, c’est utilisé partout sur GitHub. Seulement, passés les tutoriels simples, CMake, c’est un mur pas vraiment évident à escalader. J’ai créé ce blog pour ne pas oublier les trucs et astuces qui pourraient me resservir, alors quoi de plus naturel que de faire un article avec quelques trucs sur CMake ? Parce qu’il y a certains trucs que j’ai mis très longtemps à trouver…

CMake est un outil qui évolue vite. En cherchant comment réaliser une action particulière, on trouve des tas de solutions différentes sur le net et beaucoup sont obsolètes. J’ai essayé de lister ici les techniques modernes mais malheureusement elles seront peut-être obsolètes dans quelques temps… D’ici là, enjoy  : )

Choisir les versions des langages C et C++

La solution simple moderne est de définir les variables dédiées : CMAKE_C_STANDARD et CMAKE_CXX_STANDARD. Par exemple pour utiliser C++11 :

set(CMAKE_CXX_STANDARD 11)

Vous pouvez lire cet article pour plus de détails et de manière de choisir les versions des langages : Enabling C++11 And Later In CMake par Craig Scott.

Attention ! Par défaut, GCC compilera avec les extensions ! Si ce n’est pas ce que vos voulez, dites à CMake que vous en voulez pas d’extensions :

set(CMAKE_CXX_EXTENSIONS OFF)

Ajouter des options de compilations

La solution la plus simple et portable est d’utiliser add_compile_options(). Par exemple pour utiliser l’option -Wall :

add_compile_options(-Wall)

-Wall sera ajouté pour le C et le C++, pour tous les cibles, pour toutes les configurations.

Si vous ne souhaitez ajouter cette option qu’à une seule cible, il faut utiliser target_compile_options() à la place. Certains, comme Boost, pensent qu’on ne devrait utiliser que target_compile_options().

Si vous ne souhaitez que cette option que pour le C ou que pour C++, vous pourriez être tentés de modifier directement les variables CMAKE_lang_FLAGS_config, comme par exemple :

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -Wsuggest-override")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Og")

Il est toutefois possible d’utiliser une generator expression pour faire ça (et c’est visiblement le style CMake moderne) :

# uniquement en C++
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wsuggest-override>)

# uniquement en debug
add_compile_options($<$<CONFIG:Debug>:-Og>)

# uniquement en C++ en debug
add_compile_options($<$<AND:$<COMPILE_LANGUAGE:CXX>,$<CONFIG:Debug>>:-Og>)

NOTE : Chaque fois que vous devez modifier une variable interne de CMake, pensez à ajouter à sa valeur courante et non pas simplement à l’écraser (voir l’item 1 de cet article) ! Sauf si c’est vraiment ce que vous voulez faire…

NOTE : Chaque fois que vous ajoutez des options spécifiques à un compilateur, n’oubliez pas que vous casser la possible d’utiliser votre projet avec un autre compilateur. Si vous voulez continuer à supporter plusieurs compilateurs, il faudrait tester le compilateur choisi et s’adapter, soit avec des if() / endif() soit directement avec des generator expressions.

Spécifier le type de build

Vous avez un projet CMake et vous faites :

cmake -G "Unix Makefiles" .

Vous obtenez un jeu de makefiles répondant au type de build par défaut, mais lequel ? Debug ou Release ? Et bien, rien… Il n’y a pas de mode par défaut, ce qui signifie que la variable CMAKE_BUILD_TYPE est vide ! Cela implique que les variables comme CMAKE_CXX_FLAGS_DEBUG n’est pas utilisées, qu’une générateur expression comme $<CONFIG:Debug> sera égale à 0, etc. Cela signifie aussi que CMake n’ajoute pas automatiquement des options comme -g ou -O2 pour gcc.

N’oubliez donc pas de choisir !

cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug .
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release .

Ajouter des options particulières à certains fichiers ou dossiers

Il est possible d’ajouter des options de compilations pour un fichier en particulier grâce à set_source_files_properties(). C’est très utile pour optimiser un fichier en particulier :

set_source_files_properties(chemin/vers/mon_fichier.cpp PROPERTIES COMPILE_FLAGS -O3)

Attention ! Il s’agit bien d’ajouter une option, pas de remplacer les options déjà appliquées. Si vous voulez par exemple ne plus avoir les warnings générés par -Wconversion, ajoutez l’option -Wno-conversion pour l’annuler.

Il est possible de passer une liste de fichiers et on peut ainsi ruser pour modifier un dossier :

file(GLOB_RECURSE MON_DOSSIER chemin/vers/mon/dossier/*.cpp)
set_source_files_properties(${MON_DOSSIER} PROPERTIES COMPILE_FLAGS -O3)

Afficher la taille de l’exécutable après le build

Vous avez sans doute envie garder un œil sur la taille de votre exécutable. C’est particulièrement le cas si vous travaillez sur un projet embarqué. Une solution simple est d’appeler size (ou un programme équivalent de votre toolchain) grâce à add_custom_command() en tant que post build action. Voici un exemple avec une toolchain GCC pour ARM :

add_custom_command(TARGET program.out
                   POST_BUILD
                   COMMAND arm-none-eabi-size program.out)

Créer un fichier fichier hex à partir de l’exécutable elf et supprimer ce hex quand ‘clean’ est invoquée

Cette astuce (très spécifique pour des projets embarqués, je l’avoue) est aussi basé sur add_custom_command() :

add_custom_command(TARGET program.out
                   POST_BUILD
                   COMMAND arm-none-eabi-objcopy.exe -I elf32-little -O ihex
                           program.out program.hex)

Si besoin, j’ai écrit il y a longtemps un article sur (arm-none-eabi-)objcopy et les paramètres à utiliser pour réaliser une telle conversion.

Ce fichier n’est bien sûr pas supprimé quand vous faites appel à la cible clean puisque CMake n’est pas vraiment au courant de ce fichier program.hex… Je ne n’ai pas trouvé de solution portable pour le supprimer mais si vous utilisez make derrière CMake, vous pouvez utiliser la variable ADDITIONAL_MAKE_CLEAN_FILES :

set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${PROJECT_NAME}.hex)

Exclure des éléments du build quand on utilise GLOB_RECURSE

Utiliser file(GLOB_RECURSE …) est souvent considéré comme une mauvaise pratique en CMake. Mais bon, des fois c’est pratique… Si voulez exclure certains fichiers ou dossiers, il faut ensuite modifier la liste obtenue. Voici un exemple :

# Lister les fichiers dans 'source/'
file(GLOB_RECURSE SOURCE_FILES source/*.cpp source/*.hpp source/*.c source/*.h)

# Enlever le dossier 'source/stm32f4xx'
list(FILTER SOURCE_FILES EXCLUDE REGEX ${CMAKE_SOURCE_DIR}/source/stm32f4xx/*)

# Enlever le fichier 'source/debug/Hardfault.c'
list(REMOVE_ITEM SOURCE_FILES ${CMAKE_SOURCE_DIR}/source/debug/Hardfault.c)

pthread

Si votre projet sous Linux utilise des pthreads et si vous vous mangez des undefined references vers des fonctions de pthread lors de l’édition des liens, alors commencez par vérifier que la bibliothèque est bien installée sur votre système puis regardez du côté du module FindThreads. Voici un bout de code à rajouter à votre CMakeLists.txt :

find_package (Threads)
add_executable (myapp main.cpp ...)
target_link_libraries (myapp ${CMAKE_THREAD_LIBS_INIT})

 


Outils Markdown pour Notepad++

Il y a très longtemps, j’avais parlé des outils XML pour Notepad++. Parlons aujourd’hui des outils Markdown !

Coloration syntaxique

Il n’y a pas de coloration syntaxique pour ce langage par défaut…

npp md avant

Avant…

On va commencer par remédier à ce défaut ! Notepad++ permet de définir des langages utilisateurs pour permettre la coloration syntaxique des langages non supportés nativement. On parle de « User Defined Language« .  Le dépôt GitHub markdown-plus-plus fournit plusieurs fichiers XML contenant des définitions de « User Defined Languages » pour le markdown. La section Usage du README explique comment importer ces fichiers.

Il est ensuite possible de sélectionner ce nouveau langage depuis le menu Langage. Il est sélectionné automatiquement si votre fichier porte l’une des extensions indiquer dans la configuration du langage importée. Il est possible d’en rajouter si jamais vous le souhaitez.

npp md apres

À mi-chemin

Visualisation

Maintenant que le texte est correctement coloré, il ne reste plus qu’avoir une visualisation du rendu ! Il existe un autre dépôt GitHub avec tout ce qu’il faut : MarkdownViewerPlusPlus ! Comme précédemment, le README vous explique tout ce que vous devez savoir.

Une fois le plugin installé et Notepad++ redémarré, un petit bouton avec un M blanc sur fond noir apparaît dans la barre d’outils. Il permet d’ouvrir la fenêtre de visualisation.

npp md apercu

Fini !

Aide-mémoire

En bonus, n’oublie pas de mettre ce Markdown Cheatsheet dans vos marque-pages !


Mes plugins Eclipse

Cela fait des années que j’utilise Eclipse, par choix ou par obligation. On dira ce qu’on voudra, c’est quand même un IDE très puissant et la multitude de plugins disponibles contribue à sa versatilité quand tu travailles avec plusieurs langages pour un même projet. Cet article présente quelques plugins que j’utilise et s’enrichira au fil des découvertes 🙂

Eclipse logo

CMake Editor

CMake Editor rajoute un éditeur dédiés aux fichiers CMake. Il propose bien sûr la coloration syntaxique et l’autocomplétion :

eclipse-plugin-cmake-editor-autocompletion

Une entrée est créée dans Windows / Preferences / CMakeEd pour configurer la coloration syntaxique et pour gérer ses templates, qui sont accessibles via l’autocomplétion.

Enfin, l’éditeur est par défaut associé aux fichiers CMake :

eclipse-plugin-cmake-editor-association

CMake Editor est disponible sur le marketplace.

Eclox

Eclox permet une intégration rapide de Doxygen dans Eclipse. Vous pouvez le configurer dans Windows / Preferences / Doxygen :

Il est aussi très utile de choisir Doxygen comme outil de documentation dans les options de l’éditeur C/C++. Ainsi, quand taperez /** (ou /*! ou peut-être d’autres débuts de commentaire Doxygen valide) juste avant le corps d’une fonction, d’une énumération, d’une variable, un bloc de documentation Doxygen sera automatiquement créé.

Le plugin offre aussi un éditeur pour les fichiers Doxygen :

Enfin, un bouton avec un @ bleu apparaît dans la barre d’outils pour générer la documentation en un clic !

Eclox est disponible sur le martketplace.

JSON Editor Plugin

On a toujours besoin d’un éditeur JSON. JSON Editor Pluging fait bien le taf. Une entrée dans les préférences permet de configurer le formatage et la coloration syntaxique. Le plus est que la structure du fichier JSON est montrée dans la vue Outline :

JSON Editor Plugin est disponible sur le marketplace.

On a toujours besoin d’un éditeur de **Markdown**.

Markdown Text Editor

Markdown, what else? Idéal pour faire des README et autres petites documentations.

le plugin apporte un éditeur avec deux onglets; Le premier est l’éditeur en mode texte, avec un rendu un peu WYSIWYG :

eclipse markdown 1 texte

Le second est une prévisualisation du rendu :

eclipse markdown 2 preview

Malheureusement, il ne semble pas possible d’afficher les deux onglets en même temps, pour voir le rendu quand on tape du texte…

Des soft wraps sont fait l’éditeur pour s’adapter à la largeur de la vue et ça c’est cool.

Enfin, la vue Outline affiche la table des matières du fichier. On peut cliquer sur un titre pour le sélectionner dans l’éditeur.

eclipse markdown 3 outline

_Markdown Text Editor_ est disponible sur le [marketplace](http://marketplace.eclipse.org/content/markdown-text-editor).

QuickImage

Quand vous travaillez sur des GUI, vous avez souvent des images à gérer. Le plugin Quick Image est une simple visionneuse d’images, indiquant quelques informations basiques, suffisante pour ce que j’avais à faire :

eclipse-plugin-quick-image

QuickImage est disponible sur le marketplace.


Lister les répertoires présents dans le path

J’étais (malheureusement) déjà grand quand j’ai découvert awk :

Bien qu’il soit rebutant aux premiers abords, on arrive assez rapidement à faire des choses sympathiques !

Cet article vous montre une ligne simple pour lister les répertoires présents dans le path grâce à awk. La première chose à faire est d’envoyer le contenu de la variable d’environnement PATH à awk grâce à un pipe. Le programme awk commence  par changer le séparateur de champ (FS pour Field Separator) dans BEGIN puis boucle pour afficher les champs.

Voici la commande complète pour Unix :

echo $PATH | awk 'BEGIN {FS=":"} { for(i = 1; i <= NF; i++) print $i}'

Sous Windows, le séparateur est différent et la récupération de la valeur de la variable d’environnement est différente. De plus, Cmder (la ligne de commande que j’utilise depuis près d’un an et demi sous Windows) n’aime pas les chevrons donc j’utilise une boucle while à la place de la boucle for :

echo %PATH% | awk 'BEGIN {FS=";"} { i = 0; while(i++ != NF) print $i}'

Pour finir, notez que la boucle commence à l’indice 1 et termine à l’indice NF (pour Number of Fields) inclus puisque $0 est l’argument entier et que $1 à $n correspondent aux morceaux de l’argument découpé selon FS.