Bien que je pense que l'utilisation du système de construction pour gérer les fichiers multiplateformes soit la meilleure, il est possible d'écrire simplement votre source pour la gérer via le préprocesseur. Cependant, la méthode très courante, rapide et sale de faire cela, où vous saupoudrez les contrôles de la plate-forme partout dans le code est problématique et devrait être évitée. A la place, vous devriez utiliser une méthode plus structurée pour organiser le code spécifique à la plate-forme afin d'éviter les problèmes au fur et à mesure que le projet prend de l'ampleur.
Le code spécifique à la plateforme doit être clairement identifié au niveau du fichier: Par exemple, utilisez une structure de répertoires avec des répertoires pour chaque plate-forme et placez tous les fichiers source spécifiques à la plate-forme dans le répertoire approprié. Les fichiers source ne doivent pas contenir de code pour plusieurs plates-formes ou pour toute vérification de plate-forme de préprocesseur (sauf pour une exception). En outre, la source spécifique à la plate-forme ne doit généralement pas être directement construite ou #include
d. Au lieu de cela, le code spécifique à la plate-forme ne doit être utilisé que de manière indirecte, via des fichiers source non spécifiques à la plate-forme qui ne contiennent rien d'autre que les vérifications de plate-forme et les fichiers spécifiques à la plate-forme.
Exemple organisation source:
src/
main.cpp
foo.h
foo.cpp
windows/
foo.cpp.inc
posix/
foo.cpp.inc
Exemple contenu de la source:
// main.cpp
#include "foo.h"
int main() {
foo();
}
// foo.h
void foo();
// foo.cpp
#if defined(_WIN32)
# include "windows/foo.cpp.inc"
#elif __has_include(<unistd.h>)
# include<unistd.h>
# if defined(_POSIX_VERSION)
# include "posix/foo.cpp.inc"
# endif
#else
# error Unknown platform
#endif
// windows/foo.cpp.inc
#include "foo.h"
#include <iostream>
#include <Windows.h>
void foo() {
std::cout << "Windows\n";
}
// posix/foo.cpp.inc
#include "foo.h"
#include <iostream>
#include <unistd.h>
void foo() {
std::cout << "POSIX\n";
}
versions Windows et la sortie:
cl.exe /EHsc /W4 /WX src\main.cpp src\foo.cpp
main
de Windows
Linux build et sortie:
g++ -Wall -Wextra -Werror -Isrc src/main.cpp src/foo.cpp
./a.out
Posix
La méthode illustrée dans l'exemple ci-dessus fonctionne plutôt bien lorsque le code de différentes plates-formes peut raisonnablement partager la même organisation de fichier. Si le code pour différentes plates-formes est suffisamment différent pour que vous souhaitiez différentes structures de fichiers pour chaque plate-forme, il est plus difficile d'utiliser cette technique, et passer à l'utilisation du système de build pour gérer le code pour différentes plates-formes devient nettement supérieur.
Il est également possible de mélanger cette technique avec le système de construction; Le code qui partage la structure de fichiers entre les plates-formes peut l'utiliser, tandis que les modules uniques à différentes plates-formes peuvent être gérés par le système de construction.
Cela ne gère pas, y compris les différents fichiers source dans la construction, cependant. L'utilisation de CMake entraîne généralement le paramétrage approprié, mais vous pouvez également inclure des fichiers source spécifiques à la plate-forme. C'est l'une des (bonnes) raisons d'utiliser cmake en premier lieu. –
C'est une de ces techniques qui est facile et qui fonctionne bien pour les petits projets, mais qui devient problématique lorsque les projets prennent de l'ampleur. _Large Scale C++ Software Design_ recommande de ne pas arroser la totalité de votre source. Je pense que l'utilisation du système de build pour gérer le code spécifique à la plate-forme est la meilleure, mais si vous voulez le faire dans la source elle-même, il est conseillé d'utiliser un [organisation hautement structurée] (http://stackoverflow.com/a/31304341/365496). – bames53