Wie erstelle ich eine vollständig statisch verknüpfte EXE-Datei mit Visual Studio Express 2005?

109

Meine derzeit bevorzugte C ++ - Umgebung ist die kostenlose und weitgehend ausgezeichnete Microsoft Visual Studio 2005 Express Edition. Von Zeit zu Zeit habe ich Release-EXE-Dateien mit erfreulichen Ergebnissen an andere Personen gesendet. Vor kurzem machte ich jedoch die beunruhigende Entdeckung, dass die erfreulichen Ergebnisse auf mehr Glück beruhten, als ich gerne hätte. Der Versuch, eines dieser Programme auf einer alten XP-Box (Jahrgang 2001, nicht sorgfältig aktualisiert) auszuführen, gab mir nur die böse Meldung "System kann x.exe nicht ausführen" (oder eine ähnliche Meldung).

Einige Google-Versuche haben ergeben, dass mit diesem Toolset sogar die Angabe einer statischen Verknüpfung zu einer einfachen hallo-world.exe führt, die tatsächlich auf zusätzlichen DLL-Dateien (msvcm80.dll usw.) basiert. Ein unglaublich ausgeklügeltes Versionsschemasystem (Manifestdateien?) Lässt die EXE-Datei dann nicht ohne genau die richtigen DLL-Versionen laufen. Ich möchte oder brauche dieses Zeug nicht, ich möchte nur eine altmodische, in sich geschlossene EXE-Datei, die nur Win32-Operationen mit dem kleinsten gemeinsamen Nenner ausführt und auf jedem alten Win32-Betriebssystem ausgeführt wird.

Weiß jemand, ob es möglich ist, mit meinem vorhandenen Toolset das zu tun, was ich möchte?

Danke dir.

Bill Forster
quelle

Antworten:

126

Für die C-Laufzeit gehen Sie zu den Projekteinstellungen, wählen Sie C / C ++ und dann 'Code Generation'. Ändern Sie die Einstellung 'Laufzeitbibliothek' in 'Multithreaded' anstelle von 'Multithreaded DLL'.

Wenn Sie andere Bibliotheken verwenden, müssen Sie den Linker möglicherweise anweisen, die dynamisch verknüpfte CRT explizit zu ignorieren.

Rob Walker
quelle
"Wenn Sie andere Bibliotheken verwenden, müssen Sie den Linker möglicherweise anweisen, die dynamisch verknüpfte CRT explizit zu ignorieren." Kürzlich bin ich auf dieses Problem gestoßen. Ich habe eine wxWidgets-App erstellt und festgestellt, dass ich die wxWidgets-Bibliotheken mit derselben Änderung der Codegenerierung neu erstellen muss
Bill Forster,
6
Mann 300 Zeichen ist nicht viele. Falls der obige Kommentar unklar ist, besteht das Problem darin, dass sowohl Ihre CPP-Dateien als auch alle CPP-Dateien der Bibliothek "Multithreaded" anstelle von "Multithreaded DLL" haben müssen, da sonst möglicherweise Linkfehler auftreten.
Bill Forster
Dies führt zu zahlreichen Problemen bei der Heap-Verwaltung, mit denen Sie wahrscheinlich nichts zu tun haben möchten.
Edward Strange
Für die CRT-Bibliotheken bietet der VS die Optionen / MD & / MT. Aber was ist mit der statischen Verknüpfung anderer Bibliotheken im Allgemeinen - beispielsweise libX.lib (dies könnte meine eigene Bibliothek oder eine Bibliothek eines Drittanbieters sein)?
Kiran MN
4
Ich verstehe error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MD_DynamicRelease' doesn't match value 'MT_StaticRelease'. Gibt es einen anderen Ort, um den Typ des Builds zu ändern? Ich erstelle eine wxWigets-Anwendung, ähnlich wie @BillForster. Muss ich also wxWidgets neu erstellen? Wie mache ich das?
Tomáš Zato - Wiedereinsetzung Monica
18

Ich habe in Visual Studio 2010 die Erfahrung gemacht, dass zwei Änderungen erforderlich sind, um keine DLLs zu benötigen. Auf der Projekteigenschaftsseite (klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf den Projektnamen):

  1. Ändern Sie unter Konfigurationseigenschaften -> Allgemein das Feld "Verwendung von MFC" in "MFC in einer statischen Bibliothek verwenden".

  2. Ändern Sie unter Konfigurationseigenschaften -> C / C ++ -> Codegenerierung das Feld "Laufzeitbibliothek" in "Multithreaded (/ MT)".

Ich bin mir nicht sicher, warum beide benötigt wurden. Ich habe dies verwendet, um eine Abhängigkeit von glut32.dll zu entfernen.

Später hinzugefügt: Wenn Sie diese Änderungen an den Konfigurationen vornehmen, sollten Sie sie unter "Alle Konfigurationen" vornehmen. Sie können dies oben im Eigenschaftenfenster auswählen. Wenn Sie die Änderung nur an der Debug-Konfiguration vornehmen, gilt dies nicht für die Release-Konfiguration und umgekehrt.

Sam Buss
quelle
1
Dies scheint in Visual Studio 2013 mit einem kleinen Zusatz zu funktionieren: Ich musste die Konfigurationseigenschaften -> Allgemein -> Zeichensatz in "Unicode-Zeichensatz verwenden" ändern.
Gnovice
4

Ich hatte das gleiche Abhängigkeitsproblem und weiß auch, dass Sie die VS 8.0-DLLs (nur Release! Nicht debuggen! --- und Ihr Programm muss auch Release sein) in einen Ordner mit dem entsprechenden Namen in der übergeordneter Ordner mit Ihrer EXE-Datei:

Gewusst wie: Bereitstellen mit XCopy (MSDN)

Beachten Sie auch, dass die Dinge garantiert schief gehen, wenn Sie C ++ und C-Code in derselben statisch verknüpften EXE-Datei benötigen, da Sie Linkerkonflikte erhalten, die nur gelöst werden können, indem Sie die richtige libXXX.lib ignorieren und dann dynamisch verknüpfen (DLLs). .

Mit einem anderen Toolset (VC ++ 6.0) funktionieren die Dinge "einfach", da in Windows 2000 und höher die richtigen DLLs installiert sind.

Jared Updike
quelle
1

In Bezug auf Jareds Antwort wird Windows 2000 oder besser das Problem nicht unbedingt beheben. Robs Antwort funktioniert, es ist jedoch möglich, dass dieses Update Sicherheitsprobleme mit sich bringt, da Windows-Updates keine als solche erstellten Anwendungen patchen können.

In einem anderen Beitrag schlägt Nick Guerrera vor, die Visual C ++ Runtime Redistributable mit Ihren Anwendungen zu verpacken, die schnell installiert werden und von Visual Studio unabhängig sind.

Bunkerdive
quelle
2
Während das Packen der weiterverteilbaren Datei die bevorzugte Lösung zu sein scheint, benötigen Sie Administratorrechte, um das weiterverteilbare Installationsprogramm auszuführen. Dies ist keine praktikable Option, wenn Sie Benutzer haben, die keine Administratoren sind.
Kevin Condon