Comment créer un .exe entièrement lié de manière statique avec Visual Studio Express 2005?

109

Mon environnement C ++ préféré actuel est l'édition gratuite et largement excellente de Microsoft Visual Studio 2005 Express. De temps en temps, j'ai envoyé des fichiers .exe de version à d'autres personnes avec des résultats satisfaisants. Cependant, récemment, j'ai fait la découverte troublante que les résultats satisfaisants étaient basés sur plus de chance que je voudrais. Tenter d'exécuter l'un de ces programmes sur une vieille boîte XP (millésime 2001, pas scrupuleusement mis à jour) ne m'a donné qu'un message méchant "Le système ne peut pas exécuter x.exe" (ou similaire).

Certains googlages ont révélé qu'avec cet ensemble d'outils, même la spécification de liens statiques aboutissait à un simple hello-world.exe reposant en fait sur des fichiers .dll supplémentaires (msvcm80.dll etc.). Un système de schémas de version incroyablement élaboré (les fichiers manifestes n'importe qui?) Ne laissera alors pas le .exe fonctionner sans exactement les bonnes versions .dll. Je ne veux ni n'en ai besoin, je veux juste un .exe autonome à l'ancienne qui ne fait rien d'autre que les opérations Win32 du plus petit dénominateur commun et fonctionne sur n'importe quel ancien système d'exploitation win32.

Quelqu'un sait-il s'il est possible de faire ce que je veux faire avec mon ensemble d'outils existant?

Je vous remercie.

Bill Forster
la source

Réponses:

126

Pour le C-runtime, allez dans les paramètres du projet, choisissez C / C ++ puis 'Code Generation'. Modifiez le paramètre «bibliothèque d'exécution» en «multithread» au lieu de «dll multithread».

Si vous utilisez d'autres bibliothèques, vous devrez peut-être indiquer à l'éditeur de liens d'ignorer explicitement le CRT lié dynamiquement.

Rob Walker
la source
"Si vous utilisez d'autres bibliothèques, vous devrez peut-être dire à l'éditeur de liens d'ignorer explicitement le CRT lié dynamiquement." Récemment, j'ai rencontré ce problème. Je construisais une application wxWidgets, j'ai trouvé que j'avais besoin de reconstruire les bibliothèques wxWidgets avec la même modification de génération de code
Bill Forster
6
Les personnages de Man 300 ne sont pas nombreux. Dans le cas où le commentaire ci-dessus n'est pas clair, le problème est que vos fichiers .cpp et tous les fichiers de bibliothèque .cpp doivent avoir "multithread" au lieu de "dll multithread" sinon vous pourriez obtenir des erreurs de lien.
Bill Forster
Cela introduit de nombreux problèmes concernant la gestion du tas avec lesquels vous ne voulez probablement rien avoir à faire.
Edward Strange
Pour les bibliothèques CRT, le VS fournit les options / MD & / MT. Mais qu'en est-il de la liaison statique d'autres bibliothèques en général - disons, libX.lib (qui pourrait être ma propre bibliothèque ou une bibliothèque tierce)?
Kiran MN
4
Je reçois error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease'. Y a-t-il un autre endroit pour changer le type de build? Je construis l'application wxWigets, un peu comme @BillForster. Dois-je donc reconstruire wxWidgets? Comment je fais ça?
Tomáš Zato - Réintégrer Monica
18

Mon expérience dans Visual Studio 2010 est qu'il y a deux changements nécessaires pour ne pas avoir besoin de DLL. Depuis la page de propriétés du projet (clic droit sur le nom du projet dans la fenêtre Explorateur de solutions):

  1. Sous Propriétés de configuration -> Général, modifiez le champ «Utilisation de MFC» sur «Utiliser MFC dans une bibliothèque statique».

  2. Sous Propriétés de configuration -> C / C ++ -> Génération de code, modifiez le champ "Bibliothèque d'exécution" en "Multi-Threaded (/ MT)"

Je ne sais pas pourquoi les deux étaient nécessaires. J'ai utilisé ceci pour supprimer une dépendance sur glut32.dll.

Ajouté plus tard: Lorsque vous apportez ces modifications aux configurations, vous devez les apporter à "Toutes les configurations" --- vous pouvez le sélectionner en haut de la fenêtre Propriétés. Si vous apportez la modification uniquement à la configuration de débogage, elle ne s'appliquera pas à la configuration Release, et vice-versa.

Sam Buss
la source
1
Cela semble fonctionner dans Visual Studio 2013 avec un petit ajout: j'ai dû modifier les propriétés de configuration -> Général -> Jeu de caractères en "Utiliser le jeu de caractères Unicode".
gnovice
4

J'ai eu ce même problème de dépendance et je sais aussi que vous pouvez inclure les DLL VS 8.0 (version uniquement! Pas de débogage! --- et votre programme doit également être publié) dans un dossier du nom approprié, dans le dossier parent avec votre .exe:

Procédure: déployer à l'aide de XCopy (MSDN)

Notez également que les choses vont mal tourner si vous avez besoin d'avoir du code C ++ et C dans le même .exe lié statiquement, car vous obtiendrez des conflits de liens qui ne peuvent être résolus qu'en ignorant le bon libXXX.lib, puis en liant dynamiquement (DLL) .

Enfin, avec un ensemble d'outils différent (VC ++ 6.0), les choses "fonctionnent simplement", puisque Windows 2000 et les versions supérieures ont les DLL appropriées installées.

Jared Updike
la source
1

En ce qui concerne la réponse de Jared, avoir Windows 2000 ou mieux ne résoudra pas nécessairement le problème. La réponse de Rob fonctionne, mais il est possible que ce correctif introduit des problèmes de sécurité, car les mises à jour Windows ne seront pas en mesure de corriger les applications créées en tant que telles.

Dans un autre article, Nick Guerrera suggère d'empaqueter le Visual C ++ Runtime Redistributable avec vos applications, qui s'installe rapidement et est indépendant de Visual Studio.

plongée au bunker
la source
2
Bien que l'empaquetage du redistribuable semble être la solution préférée, vous avez besoin de privilèges d'administrateur pour exécuter le programme d'installation redistribuable. Ce n'est pas une option viable si vous avez des utilisateurs non administrateurs.
Kevin Condon