Comment utiliser correctement SDL2 dans mes programmes?
Je souhaite créer un jeu en SDL2, mais je ne parviens pas à compiler et / ou exécuter mon code, aidez-moi!
SDL2 est notoirement difficile à mettre en place, et c'est souvent la première bibliothèque que les développeurs de jeux en herbe essaient d'utiliser.
Cet article est conçu comme un doublon canonique pour les problèmes courants liés à la configuration de SDL2.
Réponses
Cette réponse traite de MinGW / GCC et non de Visual Studio.
Cette réponse concerne principalement Windows. Les choses sont plus faciles sur les autres OS, voir le bas de la réponse pour un résumé.
J'ai essayé de garder cette réponse simple, de sorte que même un débutant puisse l'utiliser.
Erreurs courantes
Les erreurs courantes que vous pouvez obtenir sont:
SDL.h: No such file or directory(lors de la compilation)undefined reference todiverses fonctions (lors de la liaison).dllErreurs mystérieuses liées (lors de l'exécution de votre programme).
Cette liste est triée de mauvais à bon. Si vous changez quelque chose et obtenez une erreur différente, utilisez cette liste pour savoir si vous avez amélioré ou empiré les choses.
Voir la réponse ci-dessous pour savoir comment résoudre tous ces problèmes.
Le préambule
Voici certaines choses que je souhaite vous dire avant de corriger les erreurs.
0. Ne suivez pas les mauvais conseils.
Certaines ressources vous suggéreront de faire #define SDL_MAIN_HANDLEDou #undef main. Ne fais pas ça. Ces solutions diffèrent de la façon dont SDL2 est censé être utilisé, et avec la bonne configuration, elles ne sont JAMAIS nécessaires.
Certains soutiennent que ceux-ci sont meilleurs que la manière prévue, mais je suggère d'abord d'apprendre la manière prévue, puis de savoir quelle est la différence, puis de prendre une décision éclairée.
1. Découvrez comment compiler directement à partir de la console, vous pouvez commencer à utiliser un IDE plus tard. Si vous utilisez un IDE, je suggère de vous assurer d'abord que vous êtes en mesure de compiler votre programme directement à partir de la console, pour exclure tout problème de configuration IDE. Une fois que vous avez compris cela, vous pouvez utiliser les mêmes options de compilateur dans votre IDE.
Je suggère également d'éviter CMake si vous venez de commencer, pour exclure tout problème lié à CMake. Vous pouvez commencer à l'utiliser plus tard.
2. Téléchargez les bons fichiers SDL2 . Assurez-vous d'avoir les bons fichiers. Vous avez besoin de l'archive appelée à SDL2-devel-2.0.x-mingw.tar.gzpartir d' ici .
Décompressez-le dans n'importe quel répertoire, de préférence quelque part près de votre code source. Déballer directement dans le répertoire du compilateur est souvent considéré comme une mauvaise pratique.
3. Connaissez la différence entre les indicateurs du compilateur et les indicateurs de l'éditeur de liens . Un "drapeau" est une option que vous spécifiez dans la ligne de commande lors de la construction de votre programme. Lorsque vous utilisez une seule commande, comme g++ foo.cpp -o foo.exe, tous vos indicateurs sont ajoutés au même endroit (à cette commande unique).
Mais lorsque vous construisez votre programme en deux étapes, par exemple:
g++ foo.cpp -c -o foo.o(compilation)g++ foo.o -o foo.exe(mise en relation)
vous devez savoir à laquelle des deux commandes ajouter un indicateur. Les indicateurs qui doivent être ajoutés à la première commande sont des «indicateurs de compilateur» et les indicateurs qui doivent être ajoutés à la seconde sont des «indicateurs de l'éditeur de liens». Dans la réponse ci-dessous, lorsque vous vous demandez d'ajouter un indicateur, je spécifierai s'il s'agit d'un indicateur de compilateur ou d'un indicateur de lien.
La plupart des IDE vous demanderont de spécifier séparément les indicateurs du compilateur et de l'éditeur de liens, donc même si vous utilisez une seule commande maintenant , il est bon de savoir quel indicateur va où.
Sauf indication contraire, l'ordre des indicateurs n'a pas d'importance.
SDL.h: No such file or directory
Ou toute erreur similaire liée à l'inclusion de SDL.hou SDL2/SDL.h.
Vous devez indiquer à votre compilateur le répertoire où se SDL.htrouve. Il se trouve dans les fichiers SDL que vous avez téléchargés (voir préambule).
Ajoutez ce qui suit à vos indicateurs de compilateur:, -Isuivi d'un répertoire.
Exemple: -IC:/Users/HolyBlackCat/Downloads/SDL2-2.0.12/x86_64-w64-mingw32/include/SDL2. (Les chemins relatifs fonctionnent aussi, par exemple -ISDL2-2.0.12/x86_64-w64-mingw32/include/SDL2.)
Notez que l'indicateur peut être différent selon la façon dont vous écrivez le #include:
- Si vous le faites
#include <SDL.h>, le chemin devrait se terminer par.../include/SDL2(comme ci-dessus). C'est la méthode recommandée. - Si vous le faites
#include <SDL2/SDL.h>, le chemin devrait se terminer par.../include.
undefined reference to diverses fonctions
Le message d'erreur mentionnera diverses SDL_...fonctions (souvent celles que vous utilisez dans votre programme), et / ou WinMain. S'il le mentionne SDL_main, consultez la section « undefined reference to SDL_mainseulement» ci-dessous.
Vous devez ajouter l' éditeur de liens suivants drapeaux: -lmingw32 -lSDL2main -lSDL2. L'ordre compte. Les drapeaux doivent apparaître APRÈS tous les fichiers .c/ .cpp/ .o.
L' écriture -lSDL2main -lSDL2indique l'éditeur de liens vers des fichiers d'utilisation appelés libSDL2main.a, libSDL2.a(ou libSDL2.dll.a) qui sont inclus dans les fichiers SDL téléchargés. Vous avez besoin d'un indicateur supplémentaire pour indiquer à l'éditeur de liens où rechercher ces .afichiers. Ajoutez ce qui suit à vos indicateurs de l'éditeur de liens:, -Lsuivi du répertoire.
Exemple: -LC:/Users/HolyBlackCat/Desktop/SDL2-2.0.12/x86_64-w64-mingw32/lib. (Les chemins relatifs fonctionnent aussi, par exemple -LSDL2-2.0.12/x86_64-w64-mingw32/lib.)
J'ai ajouté tous ces drapeaux et rien n'a changé:
Si vous avez fait cela et que vous obtenez toujours les mêmes undefined referenceerreurs, vous utilisez probablement les mauvais .afichiers SDL . L'archive que vous avez téléchargée contient deux ensembles de fichiers: i686-w64-mingw32(32 bits) et x86_64-w64-mingw32(64 bits). Vous devez utiliser les fichiers correspondant à votre compilateur, qui peuvent également être 32 bits ou 64 bits. Imprimez (8*sizeof(void*))pour voir si votre compilateur est 32 bits ou 64 bits. Même si vous pensez utiliser les bons fichiers, essayez les autres pour être sûr.
Quelques-unes des versions de MinGW peuvent basculer entre les modes 32 bits et 64 bits à l'aide des indicateurs -m32et -m64(ceux-ci doivent probablement être ajoutés aux indicateurs du compilateur et de l'éditeur de liens). Vous pouvez aussi les essayer.
J'arrive undefined referenceà une fonction spécifique:
• undefined reference to WinMainseulement
Il existe trois possibilités, qui ont toutes été couvertes dans la section précédente:
- Vous avez oublié le
-lSDL2maindrapeau. - Le
libSDL2main.afichier que vous utilisez ne correspond pas à votre compilateur (fichier 32 bits avec un compilateur 64 bits, ou vice versa). - Vous placez le
-lSDL2maindrapeau à gauche de certains fichiers.c/.cpp/.o. Il doit toujours être à droite.
Essayez d'éviter #define SDL_MAIN_HANDLEDou #undef mainlorsque vous résolvez ce problème, consultez le préambule pour obtenir des explications.
• undefined reference to SDL_mainseulement
Vous devez avoir une mainfonction. Votre mainfonction doit ressembler à int main(int, char **). PAS int main() et PAS void main() . C'est l'une des bizarreries SDL2.
L'ajout de tout nom de paramètre est autorisé, par exemple int main(int argc, char **argv). De plus , le second paramètre peut être écrit char *[]ou avec un nom: char *argv[]. Aucun autre changement n'est autorisé.
Essayez d'éviter #define SDL_MAIN_HANDLEDou #undef mainlorsque vous résolvez ce problème, consultez le préambule pour obtenir des explications.
.dll- erreurs liées
Vous avez réussi à construire un .exe, mais vous ne pouvez pas l'exécuter en raison d'erreurs mystérieuses mentionnant certains .dlls. Tu y es presque!
Le que .exevous avez fait a besoin de quelques .dlls pour fonctionner. S'il ne les trouve pas, il vous le dira et refusera de courir. C'est facile. Il peut également trouver de mauvaises versions laissées par certains autres programmes que vous avez installés, puis vous obtiendrez des erreurs très cryptiques.
Votre programme recherchera les .dlls à différents endroits, mais la solution la plus fiable consiste à les placer dans le même répertoire que le .exe. Ce répertoire est recherché en premier, donc les autres versions des .dlls que vous pourriez avoir ailleurs n'interféreront pas.
Vous devez savoir quel .dllest vos besoins du programme et les mettre dans le répertoire où vous .exeest - (sauf pour le système .dlls, que vous n'avez pas besoin de copier).
Vous pouvez obtenir deux types d'erreurs:
Une erreur qui vous indique simplement ce qui
.dllmanque.SDL2.dllest manquant. - C'est dans les fichiers SDL que vous avez téléchargés.Sachez que les fichiers contiennent deux
SDL2.dlls différents : un 32 bits (dans lei686-w64-mingw32répertoire) et un 64 bits (dansx86_64-w64-mingw32). Obtenez le bon, si nécessaire, essayez les deux.Il en
.dllmanque un autre. - Il est livré avec votre compilateur. Regardez dans le répertoire où vous vous trouvezgcc.exe.Si vous en copiez un
.dllet qu'il en demande plus, c'est normal, vous devrez peut-être répéter cela ~ 3 fois.
Une
.dllerreur cryptique . - Votre programme a trouvé une mauvaise version d'un.dllquelque part dans votre système.Vous devez copier tous les non-systèmes dont
.dllil a besoin dans le répertoire où vous vous trouvez.exe.Copiez d'abord
SDL2.dll(voir la section «SDL2.dllmanque» ci-dessus pour savoir où le trouver).Ensuite, copiez les
.dlls suivants de votre répertoire de compilateur (le répertoire oùgcc.exese trouve):libgcc_s_seh-1.dll(le nom peut varier en fonction de votre version MinGW, mais commencera toujours parlibgcc)libstdc++-6.dll(pour C ++ uniquement, ignorez si vous écrivez en C)libwinpthread-1.dll(le nom peut varier en fonction de votre version MinGW, mais sera toujours mentionnéthread; certaines versions ne l'utilisent pas du tout)
Cela devrait corriger toutes vos erreurs. Si vous voulez en savoir plus ou que cela n'a pas aidé:
Plus d'informations sur le .dlls
Il est possible de créer un .exequi ne dépend d'aucun (non-système) .dlls en utilisant le -staticdrapeau de l' éditeur de liens, c'est ce qu'on appelle "liaison statique". Cela est rarement fait et vous ne devriez pas avoir besoin de le faire si vous avez correctement suivi les étapes ci-dessus. Cela nécessite des indicateurs de l'éditeur de liens différents que d'habitude (environ 20 d'entre eux), voir le sdl2.pcfichier livré avec SDL pour les indicateurs exacts (ils sont dans la Libs.privatesection).
Dans la section précédente, je vous ai dit de quoi .dlldépend votre programme. Comment ai-je su? Il existe plusieurs façons de le découvrir par vous-même:
La manière brute:
Ouvrez la console,
cddans le répertoire où vous vous trouvez.exe, puis tapezset PATH=(ne vous inquiétez pas, cela ne change pas lesPATHparamètres de votre système et n'affecte que la session de console en cours).Supprimez tous les
.dlls que vous y avez peut-être déjà copiés.Maintenant, si vous exécutez le à
.exepartir de cette console, il ne pourra trouver que les systèmes.dll. Il ne recherchera les fichiers non-système que dans le répertoire courant (qui n'en a pas). Vous obtiendrez maintenant des messages d'erreur clairs indiquant ce qui.dllest requis et vous pouvez les copier un par un jusqu'à ce que cela commence à fonctionner. De cette façon, vous saurez tous les non-systèmes que.dllvotre programme utilise.Notez que cette méthode n'est pas totalement infaillible.
C:\Windowset certains des répertoires imbriqués sont toujours recherchés, même dans ce cas. Normalement, peu importe si les seuls.dlls là-dedans sont ceux du système, mais si un installateur de merde a copié une coutume.dlllà-dedans, cette méthode ne fonctionnera pas correctement.C'est une bonne idée de rechercher dans
C:\Windowsles répertoires imbriqués les.dlls qui ne devraient pas être là et de les supprimer. RecherchezSDL2.dllet recherchez tous les.dlls qui sont également fournis avec votre compilateur (dans le répertoire où vous vous trouvezgcc.exe).La voie civilisée:
Utilisez un outil comme Dependency Walker ou
ntldd. Vous devrez passer par leur sortie et déterminer si chacun.dllest un système ou non. Si a.dllest livré avec votre compilateur ou appartient à une bibliothèque que vous utilisez (SDL2.dll), alors c'est une bibliothèque non système. Tous les.dlls restants sont ceux du système, ignorez-les.
D'autres problèmes
Q: Mon programme ouvre toujours une fenêtre de console lorsque je l'exécute, en plus de toutes les fenêtres que j'ouvre à l'aide de SDL. Comment m'en débarrasser?
- R: Ajoutez
-mwindowsaux indicateurs de l'éditeur de liens.
- R: Ajoutez
Q: Mon programme a l'icône de fichier par défaut , mais je veux une icône personnalisée.
R: Votre icône doit être au
.icoformat. Créez un fichier avec l'.rcextension (disonsicon.rc), tapez ce qui suit:MAINICON ICON "icon.ico"(la première partie est un nom arbitraire, vous pouvez le changer; la deuxième partie doit toujours l'êtreICON, la troisième partie est le chemin vers l'icône). Convertissez le fichier en.outilisantwindres -i icon.rc -o icon.o(lewindresprogramme est livré avec votre compilateur). Spécifiez le.ofichier résultant lors de la liaison, par exempleg++ foo.cpp icon.o -o foo.exe.Les versions récentes de SDL2 ont une belle propriété d'utiliser la même icône que l'icône de la fenêtre, vous n'avez donc pas à utiliser
SDL_SetWindowIcon.
Q: J'obtiens une erreur
'SDL_VideoMode' wasn't declared in this scope.- R:
SDL_VideoModeexistait dans SDL1.2, mais ne fait pas partie de SDL2. Votre code a été écrit pour le SDL1.2 obsolète. Trouvez un meilleur didacticiel qui traite du nouveau SDL2.
- R:
Je ne suis pas sous Windows, que dois-je faire différemment?
L'ensemble de la réponse ci-dessus est principalement destiné à MinGW et Windows. Si vous n'êtes pas sous Windows, les choses deviennent plus faciles:
Aucun
.dllproblème lié.Pas besoin de télécharger manuellement SDL2, il devrait être dans votre gestionnaire de paquets.
Pas besoin de penser aux indicateurs de compilateur ou d'éditeur de liens à utiliser:
pkg-config --cflags sdl2vous indiquera les drapeaux du compilateur.pkg-config --libs sdl2vous indiquera les indicateurs de l'éditeur de liens. Ajoutez--staticsi vous voulez des indicateurs pour la liaison statique.
Vous n'en avez pas besoin
-lSDL2mainet il n'y a aucun problème lié àSDL_main.
D'autre part:
Distribuer vos programmes à d'autres personnes devient plus difficile, vous ne pouvez pas simplement envoyer un tas de
.dllprogrammes avec votre programme.Le processus de définition d'une icône personnalisée est différent.
Approche alternative: utilisez un environnement de type Linux sous Windows
La partie de la section précédente sur l'installation des bibliothèques et la détermination des indicateurs de compilateur semble-t-elle automatiquement pratique? Vous pouvez également l'avoir sur Windows.
Téléchargez MSYS2. Vous aurez un gestionnaire de packages (à partir duquel vous pouvez installer SDL), des compilateurs à jour et un ensemble d'utilitaires courants portés depuis Linux (y compris pkg-config). Cela résout la plupart des problèmes spécifiques à Windows.
Sur Mac, voici ce que je suis pour XCode (il faut installer g ++):
liaison sdl:
g++ main.cpp -o main $(sdl2-config --cflags --libs)
Étapes du projet XCODE:
application de terminal ouverte (macOS)
PARAMÈTRES DE CONSTRUCTION (sélectionnez «tous» et la barre de recherche «combinée» entrez: «recherche»)
cliquez sur "chemins de recherche d'en-tête (chemin clic droit)
ajouter:
/usr/local/includePHASES DE CONSTRUCTION -> LIER LES BIBLIOTHÈQUES BINAIRES (cliquez sur plus)
tapez
SDL-> cliquez sur "ajouter un autre"appuyez sur: command+ SHIFT+ g(pour amener la barre de recherche)
tapez:
usr/local/Cellaraccédez à: SDL2 -> 2.0.8 -> lib -> libSDL2-2.2.0.dylib (assurez-vous qu'il n'y a pas de raccourci)
Une solution pour Visual Studio:
Pourquoi ne pas utiliser un gestionnaire de packages? J'utilise vcpkg , et il est très facile de consommer des bibliothèques tierces. Récupérez la source de vcpkg et extrayez-la dans un endroit sûr, comme C:/, puis exécutez son script d'amorçage bootstrap-vcpkg.bat, cela générera un vcpkgexécutable. Ensuite, exécutez vcpkg integrate installpour rendre les bibliothèques installées avec vcpkg disponibles dans Visual Studio.
Recherchez la bibliothèque dont vous avez besoin:
vcpkg search sdl
imgui[sdl2-binding] Make available SDL2 binding
libwebp[vwebp-sdl] Build the vwebp viewer tool.
magnum[sdl2application] Sdl2Application library
sdl1 1.2.15#12 Simple DirectMedia Layer is a cross-platform development library designed to p...
sdl1-net 1.2.8-3 Networking library for SDL
sdl2 2.0.12-1 Simple DirectMedia Layer is a cross-platform
...
Installez - le avec: vcpkg install sdl2.
Il ne vous reste plus qu'à inclure les en-têtes SDL2, et tout fonctionnera immédiatement. La bibliothèque sera liée automatiquement.
Vous pouvez en savoir plus sur vcpkg ici .