SlideShare une entreprise Scribd logo
1  sur  74
Modularisation
Applications C/C++
Bonnes pratiques
“Parce que nous avons tous...
...rencontré ce type d’application….
...peiné à comprendre un code illi-si-ble..
...cru être maudits pour avoir à maintenir ce type
d’applications
...pesé le pour et le contre
avant la modification d’une ligne de code...
Développons notre
armure savoir/faire et
nos armes outils pour
chasser développer mieux.
Level max 99
Plan de la formation
▧ Objectifs
▧ Structure d’une application C/C++
▧ Exemples d’applications OpenSource
▧ Gestion des headers
▧ Gestion des includes
▧ Outillage
Objectifs
Objectifs primaires :
▧ Structurer un projet C/C++
▧ Connaitre la différence entre include système et include
▧ Connaître l’interaction entre le chemin des includes et les instructions
CMake
▧ Savoir écrire un header C/C++ correct
Objectifs secondaires :
▧ Savoir exporter des définitions
▧ Optimiser les dépendances entre les fichiers
▧ Savoir pré-compiler des headers
▧ Définir les bonnes pratiques de modularisation pour une application C/C++
Que gagnons à
modulariser nos
applications ?
Modularisation
La programmation modulaire c’est l’art de concevoir
une application logicielle qui met en oeuvre
la séparation des fonctionnalités d’un programme
en des modules indépendants, interchangeables
et pour chaque module
que celui ne contienne uniquement ce qui est
nécessaire à son exécution et sa fonctionnalité.
Vocabulaire
Technologie Paquetage Module
Java package *.jar
C++ namespace *.dll, *.so, *.a
C# namespace *.dll, NuGet
Comment modulariser
notre application ?
(Prendre un accent
La recette
1.Prendre les sources de l’application
2.Récupérer les dépendances : Où ???
3.Décomposer en module : Comment ??
4.Construire les binaires
5.Et après ? Intégration continue
Structure d’une
application C/C++
Que trouve-t-on dans une
application codée en C/C++ ?
Bric à brac du codeur
▧ Scripts de compilation
▧ Ressources (images, fichiers de configuration)
▧ Documentation
Readme
ChangeLog
▧ Sources
▧ Headers
▧ Bibliothèques
▧ ...
Autopsie d’une application C/C++
Au niveau du source, un programme C/C++ est
une collection de :
● Fichiers en-têtes (headers) (fichier .h ou
.hpp)
● Fichiers sources (fichier .c ou .cpp)
Contenu des fichiers en-têtes
Contenu partagé entre plusieurs fichiers
sources :
▧ types de données comme les structs ou les
classes
▧ les protypes de fonction ( déclarations)
▧ les constantes (les déclarations)
▧ les templates
▧ les types énumérés
La notion de dépendances entre fichiers
Tout fichier peut utiliser la directive #include
afin insérer le contenu d’un autre fichier
Ex : Un fichier source peut inclure plusieurs
fichiers en-tête
Ex : Un fichier en-tête peut inclure plusieurs
fichiers en-tête
Exemple
Game.cpp inclut Game.h
Game.h inclut Item.h
Game.h et Item.h
sont visibles
dans Game.cpp Game.cpp
Game.h
Item.h
dépendances
transitives
Dépendances circulaires
Parent.cpp
Parent.hpp Enfant.hpp
Enfant.cpp
Les fichiers Parent.hpp
et Enfant.hpp
dépendent l’un de
l’autre
Solution pour corriger
Parent.cpp
Parent.hpp Enfant.hpp
Enfant.cpp
Les fichiers Parent.hpp
et Enfant.hpp
dépendent l’un de
l’autre
Bien gérer ses dépendances
Accéler le temps de compilation
Limiter le périmètre de régression /
modification
Faciliter les futures évolutions de l’application
Améliorer la compréhension de l’architecture
global de l’application
Dépendances dans un vrai programme...
La décomposition
d’une application
C/C++
Exemples de projets
C/C++
Projet NotePad++
Projet
src
Composant 1
Composant 2
Fichiers .h
Fichiers .cpp
Fichiers .h
Fichiers .cpp
Fichiers .h
Fichiers .cpp
Projet Wget
Projet
src
Fichiers .h
Fichiers .cpp
doc
po
Projet LibU
Projet
srcs Fichiers .cpp
include
example
test
Fichiers .h
Fichiers .cpp
Fichiers .h
Fichiers .cpp
Fichiers .h
LibEvent https://github.com/libevent/libevent
Projet Fichiers .cpp
include
sample
test
Fichiers .h
Fichiers .cpp
Fichiers .h
Fichiers .cpp
Fichiers .h
Fichiers .h
Google Flags
Projet
doc
src
test
Fichiers .cpp
Fichiers .h
Fichiers .cpp
Fichiers .h
Vorbis
Projet
doc
lib
test
Fichiers .cpp
Fichiers .h
Fichiers .cpp
Fichiers .h
examples
Fichiers .cpp
Fichiers .h
include Fichiers .h
Structure proposée
Projet
src
cpp
Fichiers .cpp
Fichiers .h
main
test
include
resources
cpp
resources
Fichiers .h
Fichiers .cpp
Fichiers .h
Structure projet classique
Mon Projet de
Bibliothèque
Projet plus complexe
Bibliothèque
Exemples
Exemple A
Exemple B
dépendances
Quel livrable souhaitez-vous ?
“Une archive pour la bibliothèque ?
les exemples sont dedans ou à coté ?
Une archive qui contient la bibliothèque et ses exemples
-> Utilisation d’un CMake Global
-> Les exemples réutilisent la bibliothèque via CMake
-> La Compilation globale est réalisée via CMake
Situation A
Une archive pour la bibliothèque et une archive par
exemple
-> Utilisation d’un CMake pour la bibliothèque
-> Utilisation d’un CMake par exemple
-> Les exemples réutilisent la bibliothèque via le
gestionnaire de dépendances
-> La Compilation globale est réalisée via Gradle
Situation B
Digression...
Quel outillage pour
le packaging ?
▧ Utilisation de CMake
Pour la compilation multi-plateforme
Pour l’utilisation dans Eclipse
▧ Ajout de Gradle
Pour gérer les dépendances inter-projets
Pour construire le packaging et l’uploader
Solution Pragmatique
URL : https://github.com/Tocea/gradle-cpp-plugin/
Fonctionnalités de base :
▧ Gestionnaire de dépendances
▧ Construction du livrable
Fonctionnalités supplémentaires :
▧ Lancement Scripts de compilation
▧ Analyse statique de code
Rappel plugin Gradle
Travaux pratiques
Pendant ce temps...
Utilisez :
● la notion de buildType CMake
● un autre sous-projet (et livrable)
Si vous avez besoin de recompiler un
fichier ou une bibliothèque avec des
flags différents
Vérifiez
● Que les projets ne soient pas indépendants
(release) et donc deux livrables différents
Utilisez :
L’option OBJECT de CMake
(http://www.cmake.org/pipermail/cmake-
developers/2012-March/003693.html)
Si vous devez réutilisez des .obj entre
deux sous-projets
Outillage pour gérer les dépendances
dump -H
<program>
AIX
hatr <program>
HP-UX
ldd <program> Linux, SunOS5X
$LIB_PATH AIX
SHLIB_PATH
HP-UX
$LD_LIBRARY_P
ATH
Linux, SunOS5X
Outillage pour analyser les dépendancs
Visual Studio
PC Lint
Visual Lint
Eclipse Includator
CLang Include what you use
Include File Dependency
JEtBrains IDE CLion
Précompilation d’entêtes (sous Unix +gcc)
stdafx.h:
#include <string>
#include <stdio.h>
a.cpp:
#include "stdafx.h"
int main(int argc, char**argv)
{
std::string s = "Hi";
return 0;
}
Then compile as:
> g++ -c stdafx.h -o stdafx.h.gch // Précompilation des headers
> g++ a.cpp > ./a.out
Headers,
includes et
companie
Les Headers : mais pourquoi ?
http://webstory.my/
▧ Accélérer le temps de
compilation
▧ Garder son code mieux
organisé
▧ Séparer proprement les
interfaces de
l’implémentation
▧ Prérequis pour la
développement de
bibliothèques
▧ Compilation en deux temps :
Chaque fichier est compilé avec l’ensemble de ses headers
L’ensemble des fichiers est assemblé (link) pour construire
le binaire final.
▧ Les fichiers sources peuvent inclure des fichiers headers
▧ Les fichiers headers peuvent inclure d’autres fichiers headers
Comment cela fonctionne ?
Compilation et includes
Compilation et includes
// maclasse.h
class MaClasse
{
void faitQuelquechose() {
}
};
Attention aux multiples inclusions
// main.cpp
#include "maclasse.h" // définir MaClasse
#include "maclasse.h" // Erreur de compilation -
MaClasse already defined
#ifndef __MACLASSE_H_INCLUDED__ // si maclasse.h n’a pas encore été inclus
#define __MACLASSE_H_INCLUDED__ // #define pour que le préprocesseur sache
que cela a été inclus
// maclasse.h
class MaClasse
{
void faireQuelquechose() { }
};
#endif
Attention aux multiples inclusions (solution)
▧ #include “filename”
Pour les headers maintenus par l’équipe / produit
▧ #include <filename>
Pour les headers fournis par les bibliothèques standard (pré-
définis)
Bibliothèques standard : (STL) + Packages installés sur la machine
▧ Sous GCC, la variable INCLUDE_PATH est exploitée pour retrouver
les fichiers headers (argument -I)
Includes systèmes / includes
Les fichiers headers doivent être auto-suffisants
//=================================
// include guard
#ifndef __MYCLASS_H_INCLUDED__
#define __MYCLASS_H_INCLUDED__
//=================================
// forward declared dependencies
class Foo;
class Bar;
//=================================
// included dependencies
#include <vector>
#include "parent.h"
//=================================
// the actual class
class MyClass : public Parent // Parent object, so #include
"parent.h"
{
public:
std::vector<int> avector; // vector object, so #include
<vector>
Foo* foo; // Foo pointer, so forward
declare Foo
void Func(Bar& bar); // Bar reference, so forward
declare Bar
};
#endif // __MYCLASS_H_INCLUDED__
N’incluez pas les dépendances transitives
// C.h
#include “b.h”
#include “a.h”
// C.cpp
#include “c.h”
#include “a.h” // USELESS
Positionnez l’include du source en premier
// C.cpp
#include “c.hpp”
#include <iostream>
...
Les fichiers
headers doivent
être
autosuffisants.
▧ Incluez uniquement le header du module, jamais ses
dépendances.
▧ Les fichiers headers ne doivent pas avoir d’instruction using::
▧ Le fichier header ne doit contenir que :
Structure et déclarations de classes
Prototypes de fonction
Déclaration de variables globales externes
▧ L’initialisation des variables doit être dans les fichiers
sources
▧ Enlevez les déclarations internes (invisibles de l’utilisateur) et
déplacez les dans les .cpp
Best practices Includes/Headers
▧ Incluez uniquement les fichiers nécessaires dans chaque
header
▧ Chaque header doit avoir des gardes contre l’inclusion
▧ Appliquez la règle : une structure, un fichier .h(pp) et un
fichier .c(pp)
class MyClass => MyClass.hpp, MyClass.cpp
▧ Ne confondez pas #includes systèmes et #includes.
▧ Utilisez les déclarations en avant (forward)
▧ Attention aux fonctions inline
▧ Bien gérer les déclarations externes et exportées
Best practices Includes/Headers
▧ Pas d’inclusion de fichiers .cpp
▧ Déclarez les includes systèmes aussi dans les .cpp
Best practices Includes/Headers
// a.h
#ifndef A_H
#define A_H
#include "b.h"
class A { B* b; };
#endif A_H
Dépendances circulaires
// b.h
#ifndef B_H
#define B_H
#include "a.h"
class B { A* a; };
#endif B_H
#include "a.h"
// start compiling a.h
#include "b.h"
// start compiling b.h
#include "a.h"
// compilation of a.h skipped because it's guarded
// resume compiling b.h
class B { A* a }; // <--- ERROR, A is undeclared
Dépendances circulaires
Pour les longues nuits d’hiver
▧ Modular programming : http://www.informit.com/articles/article.aspx?p=25003&seqNum=5
▧ Detect Unnecessary includes (discussion) : http://stackoverflow.com/questions/74326/how-should-i-
detect-unnecessary-include-files-in-a-large-c-project
▧ Clang Include what you use : https://code.google.com/p/include-what-you-use/
▧ Include File Dependency : http://www.mobile-mir.com/cpp/
▧ JetBrains CLion :
▧ Include et headers : http://www.cplusplus.com/forum/articles/10627/
▧ http://faculty.ycp.edu/~dhovemey/spring2011/cs320/lecture/lecture27.html
Vous pouvez me trouver :
https://about.me/sylvain_leroy
Merci

Contenu connexe

Tendances

Cleancode / Tocea / Introduction
Cleancode / Tocea / IntroductionCleancode / Tocea / Introduction
Cleancode / Tocea / IntroductionSylvain Leroy
 
Concept de l’Intégration Continue
Concept de l’Intégration ContinueConcept de l’Intégration Continue
Concept de l’Intégration ContinueFrédéric Sagez
 
Intégration Continue (Agile Nantes)
Intégration Continue (Agile Nantes)Intégration Continue (Agile Nantes)
Intégration Continue (Agile Nantes)Fabian Piau
 
La qualité logicielle et l'intégration continue - Cas concret du projet Cytomine
La qualité logicielle et l'intégration continue - Cas concret du projet CytomineLa qualité logicielle et l'intégration continue - Cas concret du projet Cytomine
La qualité logicielle et l'intégration continue - Cas concret du projet CytomineGeeks Anonymes
 
BBL - TDD pour les DevOps - Puppet
BBL - TDD pour les DevOps - PuppetBBL - TDD pour les DevOps - Puppet
BBL - TDD pour les DevOps - PuppetOlivier BAZOUD
 
20131024 qualité de code et sonar - mug lyon
20131024   qualité de code et sonar - mug lyon20131024   qualité de code et sonar - mug lyon
20131024 qualité de code et sonar - mug lyonClement Bouillier
 
JCertif 2012 : Integration continue avec Jenkins
JCertif 2012 : Integration continue avec JenkinsJCertif 2012 : Integration continue avec Jenkins
JCertif 2012 : Integration continue avec JenkinsRossi Oddet
 
Principes de L'intégration Continue
Principes de L'intégration ContinuePrincipes de L'intégration Continue
Principes de L'intégration ContinueXavier Warzee
 
Soirée du Test Logiciel - Démystifier les xDD - C. TARDIEU, Acp qualife
Soirée du Test Logiciel - Démystifier les xDD - C. TARDIEU, Acp qualifeSoirée du Test Logiciel - Démystifier les xDD - C. TARDIEU, Acp qualife
Soirée du Test Logiciel - Démystifier les xDD - C. TARDIEU, Acp qualifeTelecomValley
 
Soirée Qualité Logicielle avec Sonar
Soirée Qualité Logicielle avec SonarSoirée Qualité Logicielle avec Sonar
Soirée Qualité Logicielle avec SonarElsassJUG
 
Model de qualité @ msdevmtl
Model de qualité @ msdevmtlModel de qualité @ msdevmtl
Model de qualité @ msdevmtlMSDEVMTL
 
Avis d'expert : Les Tests Logiciels
Avis d'expert : Les Tests LogicielsAvis d'expert : Les Tests Logiciels
Avis d'expert : Les Tests LogicielsCloudNetCare
 
Conférence: L'assurance qualité au-delà de la qualité logicielle
Conférence: L'assurance qualité au-delà de la qualité logicielleConférence: L'assurance qualité au-delà de la qualité logicielle
Conférence: L'assurance qualité au-delà de la qualité logiciellegeosaa
 
Formation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifFormation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifkemenaran
 
Sonar 2.0 au JUG Genève
Sonar 2.0 au JUG GenèveSonar 2.0 au JUG Genève
Sonar 2.0 au JUG GenèveFreddy Mallet
 
L'integration continue pour tous
L'integration continue pour tousL'integration continue pour tous
L'integration continue pour tousAurelien Navarre
 
Soirée du Test Logiciel - Administration et orchestration des tests avec Refe...
Soirée du Test Logiciel - Administration et orchestration des tests avec Refe...Soirée du Test Logiciel - Administration et orchestration des tests avec Refe...
Soirée du Test Logiciel - Administration et orchestration des tests avec Refe...TelecomValley
 
Cas Client Bouygues Telecom - CloudNetCare
Cas Client Bouygues Telecom - CloudNetCareCas Client Bouygues Telecom - CloudNetCare
Cas Client Bouygues Telecom - CloudNetCareCloudNetCare
 

Tendances (20)

Cleancode / Tocea / Introduction
Cleancode / Tocea / IntroductionCleancode / Tocea / Introduction
Cleancode / Tocea / Introduction
 
Concept de l’Intégration Continue
Concept de l’Intégration ContinueConcept de l’Intégration Continue
Concept de l’Intégration Continue
 
Intégration Continue (Agile Nantes)
Intégration Continue (Agile Nantes)Intégration Continue (Agile Nantes)
Intégration Continue (Agile Nantes)
 
La qualité logicielle et l'intégration continue - Cas concret du projet Cytomine
La qualité logicielle et l'intégration continue - Cas concret du projet CytomineLa qualité logicielle et l'intégration continue - Cas concret du projet Cytomine
La qualité logicielle et l'intégration continue - Cas concret du projet Cytomine
 
BBL - TDD pour les DevOps - Puppet
BBL - TDD pour les DevOps - PuppetBBL - TDD pour les DevOps - Puppet
BBL - TDD pour les DevOps - Puppet
 
20131024 qualité de code et sonar - mug lyon
20131024   qualité de code et sonar - mug lyon20131024   qualité de code et sonar - mug lyon
20131024 qualité de code et sonar - mug lyon
 
JCertif 2012 : Integration continue avec Jenkins
JCertif 2012 : Integration continue avec JenkinsJCertif 2012 : Integration continue avec Jenkins
JCertif 2012 : Integration continue avec Jenkins
 
Principes de L'intégration Continue
Principes de L'intégration ContinuePrincipes de L'intégration Continue
Principes de L'intégration Continue
 
Soirée du Test Logiciel - Démystifier les xDD - C. TARDIEU, Acp qualife
Soirée du Test Logiciel - Démystifier les xDD - C. TARDIEU, Acp qualifeSoirée du Test Logiciel - Démystifier les xDD - C. TARDIEU, Acp qualife
Soirée du Test Logiciel - Démystifier les xDD - C. TARDIEU, Acp qualife
 
Soirée Qualité Logicielle avec Sonar
Soirée Qualité Logicielle avec SonarSoirée Qualité Logicielle avec Sonar
Soirée Qualité Logicielle avec Sonar
 
Model de qualité @ msdevmtl
Model de qualité @ msdevmtlModel de qualité @ msdevmtl
Model de qualité @ msdevmtl
 
Avis d'expert : Les Tests Logiciels
Avis d'expert : Les Tests LogicielsAvis d'expert : Les Tests Logiciels
Avis d'expert : Les Tests Logiciels
 
Conférence: L'assurance qualité au-delà de la qualité logicielle
Conférence: L'assurance qualité au-delà de la qualité logicielleConférence: L'assurance qualité au-delà de la qualité logicielle
Conférence: L'assurance qualité au-delà de la qualité logicielle
 
Formation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratifFormation Extreme Programming, Tests unitaires, travail collaboratif
Formation Extreme Programming, Tests unitaires, travail collaboratif
 
Sonar 2.0 au JUG Genève
Sonar 2.0 au JUG GenèveSonar 2.0 au JUG Genève
Sonar 2.0 au JUG Genève
 
Usine Logicielle 2013
Usine Logicielle 2013Usine Logicielle 2013
Usine Logicielle 2013
 
L'integration continue pour tous
L'integration continue pour tousL'integration continue pour tous
L'integration continue pour tous
 
Soirée du Test Logiciel - Administration et orchestration des tests avec Refe...
Soirée du Test Logiciel - Administration et orchestration des tests avec Refe...Soirée du Test Logiciel - Administration et orchestration des tests avec Refe...
Soirée du Test Logiciel - Administration et orchestration des tests avec Refe...
 
Valider par des tests - Blend
Valider par des tests - BlendValider par des tests - Blend
Valider par des tests - Blend
 
Cas Client Bouygues Telecom - CloudNetCare
Cas Client Bouygues Telecom - CloudNetCareCas Client Bouygues Telecom - CloudNetCare
Cas Client Bouygues Telecom - CloudNetCare
 

Similaire à Rappels Modularisation application C/C++

Open Recipes - hubs : du packaging en solo à l'industrialisation du packaging
Open Recipes - hubs : du packaging en solo à l'industrialisation du packaging Open Recipes - hubs : du packaging en solo à l'industrialisation du packaging
Open Recipes - hubs : du packaging en solo à l'industrialisation du packaging Anne Nicolas
 
20100221 my phingtool - blog
20100221   my phingtool - blog20100221   my phingtool - blog
20100221 my phingtool - blogPHPPRO
 
Docker nice meetup #1 construire, déployer et exécuter vos applications, ...
Docker nice meetup #1   construire, déployer et exécuter vos applications, ...Docker nice meetup #1   construire, déployer et exécuter vos applications, ...
Docker nice meetup #1 construire, déployer et exécuter vos applications, ...adri1s
 
Les règles de développement Angular
Les règles de développement AngularLes règles de développement Angular
Les règles de développement AngularHéla Ben Khalfallah
 
Spring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'tsSpring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'tsJulien Wittouck
 
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...Alexandre Touret
 
Docker en Production (Docker Paris)
Docker en Production (Docker Paris)Docker en Production (Docker Paris)
Docker en Production (Docker Paris)Jérôme Petazzoni
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPrestaShop
 
C2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieC2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieLoic Yon
 
Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)Martin Latrille
 
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...Alexandre Touret
 
Drupal7 - Bonnes Pratiques (Partie 1)
Drupal7 - Bonnes Pratiques (Partie 1)Drupal7 - Bonnes Pratiques (Partie 1)
Drupal7 - Bonnes Pratiques (Partie 1)Alexandre Marie
 

Similaire à Rappels Modularisation application C/C++ (20)

openFrameworks
openFrameworksopenFrameworks
openFrameworks
 
Outils front-end
Outils front-endOutils front-end
Outils front-end
 
Open Recipes - hubs : du packaging en solo à l'industrialisation du packaging
Open Recipes - hubs : du packaging en solo à l'industrialisation du packaging Open Recipes - hubs : du packaging en solo à l'industrialisation du packaging
Open Recipes - hubs : du packaging en solo à l'industrialisation du packaging
 
20100221 my phingtool - blog
20100221   my phingtool - blog20100221   my phingtool - blog
20100221 my phingtool - blog
 
Docker nice meetup #1 construire, déployer et exécuter vos applications, ...
Docker nice meetup #1   construire, déployer et exécuter vos applications, ...Docker nice meetup #1   construire, déployer et exécuter vos applications, ...
Docker nice meetup #1 construire, déployer et exécuter vos applications, ...
 
Présentation1
Présentation1Présentation1
Présentation1
 
Les règles de développement Angular
Les règles de développement AngularLes règles de développement Angular
Les règles de développement Angular
 
Spring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'tsSpring Boot & Containers - Do's & Don'ts
Spring Boot & Containers - Do's & Don'ts
 
Django compressor
Django compressorDjango compressor
Django compressor
 
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
 
Docker en Production (Docker Paris)
Docker en Production (Docker Paris)Docker en Production (Docker Paris)
Docker en Production (Docker Paris)
 
introduction au CPP
introduction au CPPintroduction au CPP
introduction au CPP
 
Etude des Frameworks PHP
Etude des Frameworks PHPEtude des Frameworks PHP
Etude des Frameworks PHP
 
REX Ansible
REX AnsibleREX Ansible
REX Ansible
 
Performance et optimisation de PrestaShop
Performance et optimisation de PrestaShopPerformance et optimisation de PrestaShop
Performance et optimisation de PrestaShop
 
C2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partieC2 - Langage C - ISIMA 1 - Deuxieme partie
C2 - Langage C - ISIMA 1 - Deuxieme partie
 
Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)Présentation de Django @ Orange Labs (FR)
Présentation de Django @ Orange Labs (FR)
 
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
Checklist pour concevoir une application dans le cloud.10 conseils à l'attent...
 
De Java à .NET
De Java à .NETDe Java à .NET
De Java à .NET
 
Drupal7 - Bonnes Pratiques (Partie 1)
Drupal7 - Bonnes Pratiques (Partie 1)Drupal7 - Bonnes Pratiques (Partie 1)
Drupal7 - Bonnes Pratiques (Partie 1)
 

Rappels Modularisation application C/C++

  • 2. “Parce que nous avons tous...
  • 3. ...rencontré ce type d’application….
  • 4. ...peiné à comprendre un code illi-si-ble..
  • 5. ...cru être maudits pour avoir à maintenir ce type d’applications
  • 6. ...pesé le pour et le contre avant la modification d’une ligne de code...
  • 7. Développons notre armure savoir/faire et nos armes outils pour chasser développer mieux. Level max 99
  • 8. Plan de la formation ▧ Objectifs ▧ Structure d’une application C/C++ ▧ Exemples d’applications OpenSource ▧ Gestion des headers ▧ Gestion des includes ▧ Outillage
  • 9. Objectifs Objectifs primaires : ▧ Structurer un projet C/C++ ▧ Connaitre la différence entre include système et include ▧ Connaître l’interaction entre le chemin des includes et les instructions CMake ▧ Savoir écrire un header C/C++ correct Objectifs secondaires : ▧ Savoir exporter des définitions ▧ Optimiser les dépendances entre les fichiers ▧ Savoir pré-compiler des headers ▧ Définir les bonnes pratiques de modularisation pour une application C/C++
  • 10. Que gagnons à modulariser nos applications ?
  • 11. Modularisation La programmation modulaire c’est l’art de concevoir une application logicielle qui met en oeuvre la séparation des fonctionnalités d’un programme en des modules indépendants, interchangeables et pour chaque module que celui ne contienne uniquement ce qui est nécessaire à son exécution et sa fonctionnalité.
  • 12. Vocabulaire Technologie Paquetage Module Java package *.jar C++ namespace *.dll, *.so, *.a C# namespace *.dll, NuGet
  • 14. La recette 1.Prendre les sources de l’application 2.Récupérer les dépendances : Où ??? 3.Décomposer en module : Comment ?? 4.Construire les binaires 5.Et après ? Intégration continue
  • 16. Que trouve-t-on dans une application codée en C/C++ ?
  • 17.
  • 18. Bric à brac du codeur ▧ Scripts de compilation ▧ Ressources (images, fichiers de configuration) ▧ Documentation Readme ChangeLog ▧ Sources ▧ Headers ▧ Bibliothèques ▧ ...
  • 19. Autopsie d’une application C/C++ Au niveau du source, un programme C/C++ est une collection de : ● Fichiers en-têtes (headers) (fichier .h ou .hpp) ● Fichiers sources (fichier .c ou .cpp)
  • 20. Contenu des fichiers en-têtes Contenu partagé entre plusieurs fichiers sources : ▧ types de données comme les structs ou les classes ▧ les protypes de fonction ( déclarations) ▧ les constantes (les déclarations) ▧ les templates ▧ les types énumérés
  • 21. La notion de dépendances entre fichiers Tout fichier peut utiliser la directive #include afin insérer le contenu d’un autre fichier Ex : Un fichier source peut inclure plusieurs fichiers en-tête Ex : Un fichier en-tête peut inclure plusieurs fichiers en-tête
  • 22. Exemple Game.cpp inclut Game.h Game.h inclut Item.h Game.h et Item.h sont visibles dans Game.cpp Game.cpp Game.h Item.h dépendances transitives
  • 23. Dépendances circulaires Parent.cpp Parent.hpp Enfant.hpp Enfant.cpp Les fichiers Parent.hpp et Enfant.hpp dépendent l’un de l’autre
  • 24. Solution pour corriger Parent.cpp Parent.hpp Enfant.hpp Enfant.cpp Les fichiers Parent.hpp et Enfant.hpp dépendent l’un de l’autre
  • 25. Bien gérer ses dépendances Accéler le temps de compilation Limiter le périmètre de régression / modification Faciliter les futures évolutions de l’application Améliorer la compréhension de l’architecture global de l’application
  • 26. Dépendances dans un vrai programme...
  • 29. Projet NotePad++ Projet src Composant 1 Composant 2 Fichiers .h Fichiers .cpp Fichiers .h Fichiers .cpp Fichiers .h Fichiers .cpp
  • 31. Projet LibU Projet srcs Fichiers .cpp include example test Fichiers .h Fichiers .cpp Fichiers .h Fichiers .cpp Fichiers .h
  • 32. LibEvent https://github.com/libevent/libevent Projet Fichiers .cpp include sample test Fichiers .h Fichiers .cpp Fichiers .h Fichiers .cpp Fichiers .h Fichiers .h
  • 34. Vorbis Projet doc lib test Fichiers .cpp Fichiers .h Fichiers .cpp Fichiers .h examples Fichiers .cpp Fichiers .h include Fichiers .h
  • 37. Mon Projet de Bibliothèque Projet plus complexe Bibliothèque Exemples Exemple A Exemple B dépendances
  • 39. “Une archive pour la bibliothèque ? les exemples sont dedans ou à coté ?
  • 40. Une archive qui contient la bibliothèque et ses exemples -> Utilisation d’un CMake Global -> Les exemples réutilisent la bibliothèque via CMake -> La Compilation globale est réalisée via CMake Situation A
  • 41. Une archive pour la bibliothèque et une archive par exemple -> Utilisation d’un CMake pour la bibliothèque -> Utilisation d’un CMake par exemple -> Les exemples réutilisent la bibliothèque via le gestionnaire de dépendances -> La Compilation globale est réalisée via Gradle Situation B
  • 43.
  • 44.
  • 45.
  • 46.
  • 47. ▧ Utilisation de CMake Pour la compilation multi-plateforme Pour l’utilisation dans Eclipse ▧ Ajout de Gradle Pour gérer les dépendances inter-projets Pour construire le packaging et l’uploader Solution Pragmatique
  • 48. URL : https://github.com/Tocea/gradle-cpp-plugin/ Fonctionnalités de base : ▧ Gestionnaire de dépendances ▧ Construction du livrable Fonctionnalités supplémentaires : ▧ Lancement Scripts de compilation ▧ Analyse statique de code Rappel plugin Gradle
  • 51.
  • 52. Utilisez : ● la notion de buildType CMake ● un autre sous-projet (et livrable) Si vous avez besoin de recompiler un fichier ou une bibliothèque avec des flags différents
  • 53. Vérifiez ● Que les projets ne soient pas indépendants (release) et donc deux livrables différents Utilisez : L’option OBJECT de CMake (http://www.cmake.org/pipermail/cmake- developers/2012-March/003693.html) Si vous devez réutilisez des .obj entre deux sous-projets
  • 54. Outillage pour gérer les dépendances dump -H <program> AIX hatr <program> HP-UX ldd <program> Linux, SunOS5X $LIB_PATH AIX SHLIB_PATH HP-UX $LD_LIBRARY_P ATH Linux, SunOS5X
  • 55. Outillage pour analyser les dépendancs Visual Studio PC Lint Visual Lint Eclipse Includator CLang Include what you use Include File Dependency JEtBrains IDE CLion
  • 56. Précompilation d’entêtes (sous Unix +gcc) stdafx.h: #include <string> #include <stdio.h> a.cpp: #include "stdafx.h" int main(int argc, char**argv) { std::string s = "Hi"; return 0; } Then compile as: > g++ -c stdafx.h -o stdafx.h.gch // Précompilation des headers > g++ a.cpp > ./a.out
  • 58. Les Headers : mais pourquoi ? http://webstory.my/ ▧ Accélérer le temps de compilation ▧ Garder son code mieux organisé ▧ Séparer proprement les interfaces de l’implémentation ▧ Prérequis pour la développement de bibliothèques
  • 59. ▧ Compilation en deux temps : Chaque fichier est compilé avec l’ensemble de ses headers L’ensemble des fichiers est assemblé (link) pour construire le binaire final. ▧ Les fichiers sources peuvent inclure des fichiers headers ▧ Les fichiers headers peuvent inclure d’autres fichiers headers Comment cela fonctionne ?
  • 62. // maclasse.h class MaClasse { void faitQuelquechose() { } }; Attention aux multiples inclusions // main.cpp #include "maclasse.h" // définir MaClasse #include "maclasse.h" // Erreur de compilation - MaClasse already defined
  • 63. #ifndef __MACLASSE_H_INCLUDED__ // si maclasse.h n’a pas encore été inclus #define __MACLASSE_H_INCLUDED__ // #define pour que le préprocesseur sache que cela a été inclus // maclasse.h class MaClasse { void faireQuelquechose() { } }; #endif Attention aux multiples inclusions (solution)
  • 64. ▧ #include “filename” Pour les headers maintenus par l’équipe / produit ▧ #include <filename> Pour les headers fournis par les bibliothèques standard (pré- définis) Bibliothèques standard : (STL) + Packages installés sur la machine ▧ Sous GCC, la variable INCLUDE_PATH est exploitée pour retrouver les fichiers headers (argument -I) Includes systèmes / includes
  • 65. Les fichiers headers doivent être auto-suffisants //================================= // include guard #ifndef __MYCLASS_H_INCLUDED__ #define __MYCLASS_H_INCLUDED__ //================================= // forward declared dependencies class Foo; class Bar; //================================= // included dependencies #include <vector> #include "parent.h" //================================= // the actual class class MyClass : public Parent // Parent object, so #include "parent.h" { public: std::vector<int> avector; // vector object, so #include <vector> Foo* foo; // Foo pointer, so forward declare Foo void Func(Bar& bar); // Bar reference, so forward declare Bar }; #endif // __MYCLASS_H_INCLUDED__
  • 66. N’incluez pas les dépendances transitives // C.h #include “b.h” #include “a.h” // C.cpp #include “c.h” #include “a.h” // USELESS
  • 67. Positionnez l’include du source en premier // C.cpp #include “c.hpp” #include <iostream> ... Les fichiers headers doivent être autosuffisants.
  • 68. ▧ Incluez uniquement le header du module, jamais ses dépendances. ▧ Les fichiers headers ne doivent pas avoir d’instruction using:: ▧ Le fichier header ne doit contenir que : Structure et déclarations de classes Prototypes de fonction Déclaration de variables globales externes ▧ L’initialisation des variables doit être dans les fichiers sources ▧ Enlevez les déclarations internes (invisibles de l’utilisateur) et déplacez les dans les .cpp Best practices Includes/Headers
  • 69. ▧ Incluez uniquement les fichiers nécessaires dans chaque header ▧ Chaque header doit avoir des gardes contre l’inclusion ▧ Appliquez la règle : une structure, un fichier .h(pp) et un fichier .c(pp) class MyClass => MyClass.hpp, MyClass.cpp ▧ Ne confondez pas #includes systèmes et #includes. ▧ Utilisez les déclarations en avant (forward) ▧ Attention aux fonctions inline ▧ Bien gérer les déclarations externes et exportées Best practices Includes/Headers
  • 70. ▧ Pas d’inclusion de fichiers .cpp ▧ Déclarez les includes systèmes aussi dans les .cpp Best practices Includes/Headers
  • 71. // a.h #ifndef A_H #define A_H #include "b.h" class A { B* b; }; #endif A_H Dépendances circulaires // b.h #ifndef B_H #define B_H #include "a.h" class B { A* a; }; #endif B_H
  • 72. #include "a.h" // start compiling a.h #include "b.h" // start compiling b.h #include "a.h" // compilation of a.h skipped because it's guarded // resume compiling b.h class B { A* a }; // <--- ERROR, A is undeclared Dépendances circulaires
  • 73. Pour les longues nuits d’hiver ▧ Modular programming : http://www.informit.com/articles/article.aspx?p=25003&seqNum=5 ▧ Detect Unnecessary includes (discussion) : http://stackoverflow.com/questions/74326/how-should-i- detect-unnecessary-include-files-in-a-large-c-project ▧ Clang Include what you use : https://code.google.com/p/include-what-you-use/ ▧ Include File Dependency : http://www.mobile-mir.com/cpp/ ▧ JetBrains CLion : ▧ Include et headers : http://www.cplusplus.com/forum/articles/10627/ ▧ http://faculty.ycp.edu/~dhovemey/spring2011/cs320/lecture/lecture27.html
  • 74. Vous pouvez me trouver : https://about.me/sylvain_leroy Merci

Notes de l'éditeur

  1. Améliorer de manière significative le temps de construction des applications Meilleure séparation entre les interfaces et les implémentations Trouver les bugs plus rapidement Maîtriser/Limiter les régressions lors d’évolution sur des composants critiques Réutiliser les composants /bibliothèque les plus utiles Responsabiliser les fournisseurs d’API
  2. Améliorer de manière significative le temps de construction des applications Meilleure séparation entre les interfaces et les implémentations Trouver les bugs plus rapidement Maîtriser/Limiter les régressions lors d’évolution sur des composants critiques Réutiliser les composants /bibliothèque les plus utiles Responsabiliser les fournisseurs d’API
  3. Améliorer de manière significative le temps de construction des applications Meilleure séparation entre les interfaces et les implémentations Trouver les bugs plus rapidement Maîtriser/Limiter les régressions lors d’évolution sur des composants critiques Réutiliser les composants /bibliothèque les plus utiles Responsabiliser les fournisseurs d’API