Komfortabler Dateimanager mit vielen Funktionen

VS 2008: MFC selbst kompilieren

By Sven on 01.12.2007 - 11:02 in MFC, Visual Studio 2008

Gestern hatte ich darüber berichtet, wie man der WinSxS-Hölle entkommt und eine eigene Version der C/C++-Laufzeit kompiliert. Nun kompilieren wir uns noch eine MFC ohne Manifest und können in Zukunft die C/C++-Laufzeit sowie die MFC unseren Anwendungen beilegen, ohne uns mit Manifestproblemen herumquälen zu müssen.

1. Anpassen der Dateien

Die nötigen Änderungen an den MFC-Dateien halten sich in Grenzen. Zuerst schnappen wir uns die Datei atlmfc\include\MFCassem.h und kommentieren das Manifest ab Zeile 25 bis zum Ende aus. In atlmfc\include\afx.h ersetzen wir die Zeilen 81 bis 97 durch folgende:

#ifndef _UNICODE
#ifdef _DEBUG
#pragma comment(lib, "MyMfc90d.lib")
#pragma comment(lib, "MyMfc90sd.lib")
#else
#pragma comment(lib, "MyMfc90.lib")
#pragma comment(lib, "MyMfc90s.lib")
#endif
#else
#ifdef _DEBUG
#pragma comment(lib, "MyMfc90ud.lib")
#pragma comment(lib, "MyMfc90sud.lib")
#else
#pragma comment(lib, "MyMfc90u.lib")
#pragma comment(lib, "MyMfc90su.lib")
#endif
#endif

Damit legen wir fest, dass unsere Anwendungen dynamisch gegen die MyMfc90(u).dll gelinkt werden.

2. Vorbereitung der .DEF-Dateien

In atlmfc\src\mfc\intel und atlmfc\src\mfc\intel befinden sich jeweils vier .DEF-Dateien, deren Modulnamen ebenfalls angepasst werden müssen:

mfc90.def -> MyMfc90
mfc90d.def -> MyMfc90d
mfc90u.def -> MyMfc90u
mfc90ud.def -> MyMfc90ud

Im Gegensatz zur C/C++-Laufzeit werden aber nur die Modulnamen in den .def-Dateien angepasst, die Dateinamen selbst dürfen nicht geändert werden.

3. Anpassung des Makefiles

Die Änderung in der Datei atlmfc\src\atlmfc.mak beschränkt sich darauf, die Erstellung der statischen MFC sowie der WinForms-Komponenten auszuklammern. Dazu löschen wir in Zeile 123 die Einträge MFC_STATIC und MFCM_DLL.

4. Kompilieren

Nun kopieren wir unsere bereits erstellten Batchdateien mit den Umgebungsvariablen aus dem Ordner crt in den Ordner atlmfc\src. Zusätzlich erstellen wir in diesem Verzeichnis eine Datei makemfc_x86.bat mit dem Inhalt

nmake -f atlmfc.mak MFC LIBNAME=MyMfc90 PLATFORM=INTEL MP_BUILD=1

sowie makemfc_amd64.bat mit

nmake -f atlmfc.mak MFC LIBNAME=MyMfc90 PLATFORM=AMD64 MP_BUILD=1

Anschließend öffnen wir eine Eingabeaufforderung und starten

vcvars_x86.bat
makemfc_x86.bat

sowie anschließend

vcvars_amd64.bat
makemfc_amd64.bat

Nach ein paar Minuten sollte der Compiler seine Arbeit erledigt haben und wieder das Befehlsprompt erscheinen.

5. Kopieren der Lib-Dateien

Der letzte Schritt ist das Kopieren der lib-Dateien nach atlmfc\lib, damit der Linker diese später auch findet. Die Lib-Dateien für die 32-bit Version werden bei der MFC-Erstellung in atlmfc\lib\Intel abgelegt und müssen deshalb manuell nach atlmfc\lib kopiert werden. Die Lib-Dateien für die x64-Version landen dagegen direkt im richtigen Verzeichnis (atlmfc\lib\amd64).

Die MFC-Dlls finden wir in atlmfc\src\mfc\intel bzw. atlmfc\src\mfc\amd64. Zusammen mit den Dlls der C/C++-Laufzeit sowie den jeweiligen PDB-Dateien kopieren wir sie in einen Ordner, der in die PATH-Umgebungsvariable eingetragen wird. Somit ist sichergestellt, dass Visual Studio 2008 beim Debuggen auch alle nötigen Dateien findet.

6. Kontrolle

Zur Kontrolle erstellen wir uns ein Testprojekt und prüfen, ob gegen die richtigen Dateien gelinkt wird. Dazu lassen wir uns vom AppWizard eine einfache MFC-Anwendung erstellen und kompilieren diese. Mit Hilfe der Schnellansicht von SpeedCommander lässt sich leicht ermitteln, ob die Programmdatei an die richtigen Module gebunden wurden. Wenn es so ausschaut, dann ist alles in bester Ordnung:

Importe von Test.exe

Die gleiche Aktion führen wir noch einmal für die MyMfc90(ud).dll durch, diese sollten ebenfalls gegen die MyVcr90(d).dll gelinkt sein.

7. Letzte Worte

Zum Abschluss sei nochmals erwähnt, dass sich diese beiden Artikel wirklich nur an den nativen Entwickler richten, der vollständigen Einfluss auf die von ihm verwendeten Komponenten hat. Dazu gehört, dass alle Fremdkomponenten im Quellcode vorliegen und somit gegen die angepasste C/C++-Laufzeit bzw. die MFC kompiliert werden können. Verwendet man dagegen zusätzliche Managed Code-Erweiterungen oder fertige Libs/Dlls, die bereits gegen die originale MsVcr90.dll gelinkt sind, dann sollte man um die manifestlose Lösung einen großen Bogen machen.

Es gibt 5 Kommentare zu diesem Beitrag

Trackback URL | RSS-Feed für Kommentare

Folgende Seiten verlinken zu diesem Beitrag:

  1. VS2008: Manifeste, deployment, vcredist etc | hilpers | 18.01.2009
  1. Bernd Wagemann sagt:

    Super Idee. Das Bauen der Runtime library hat auch einwandfrei funktioniert. Beim Bauen der MFC ging
    Schritt 4 leider schief. Erst dachte ich man muesste nur in den DEF Dateien die LIBRARY von mfc90(u,d).dll auf MyMfc90(u,d).dll anpassen. Aber das resultat war identisch. Hat irgendwer eine Idee ?

    Anbei mein Log:
    ——————————————————————————————
    C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src>”C:\Program Files\Mic
    rosoft Visual Studio 9.0\VC\atlmfc\src\makemfc_x86.bat”

    C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src>nmake -f atlmfc.mak M
    FC LIBNAME=MyMfc90 PLATFORM=INTEL MP_BUILD=1

    Microsoft (R) Program Maintenance Utility Version 9.00.21022.08
    Copyright (C) Microsoft Corporation. All rights reserved.

    if not exist ..\lib\INTEL md ..\lib\INTEL
    cd MFC
    “C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe” /
    /f mfcdll.mak LIBNAME=MyMfc90 debug=0 _OD_EXT= PLATFORM=INTEL

    Microsoft (R) Program Maintenance Utility Version 9.00.21022.08
    Copyright (C) Microsoft Corporation. All rights reserved.

    NMAKE : fatal error U1073: don’t know how to make ‘INTEL\MFC90.DEF’
    Stop.
    NMAKE : fatal error U1077: ‘”C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN
    \nmake.exe”‘ : return code ‘0x2’
    Stop.
    C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src>”C:\Program Files\Mic
    rosoft Visual Studio 9.0\VC\atlmfc\src\vcvars_x86.bat”
    Setting environment for using Microsoft Visual Studio 2008 x86 tools.
    C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src>”C:\Program Files\Mic
    rosoft Visual Studio 9.0\VC\atlmfc\src\makemfc_x86.bat”

    C:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\src>nmake -f atlmfc.mak M
    FC LIBNAME=MyMfc90 PLATFORM=INTEL MP_BUILD=1

    Microsoft (R) Program Maintenance Utility Version 9.00.21022.08
    Copyright (C) Microsoft Corporation. All rights reserved.

    if not exist ..\lib\INTEL md ..\lib\INTEL
    cd MFC
    “C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN\nmake.exe” /
    /f mfcdll.mak LIBNAME=MyMfc90 debug=0 _OD_EXT= PLATFORM=INTEL

    Microsoft (R) Program Maintenance Utility Version 9.00.21022.08
    Copyright (C) Microsoft Corporation. All rights reserved.

    cl @C:\DOCUME~1\Wagemann\LOCALS~1\Temp\nm4D6.tmp
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80×86
    Copyright (C) Microsoft Corporation. All rights reserved.

    cl /Ycstdafx.h /FpINTEL\$DLL.W\stdafx.pch /D_X86_ /FoINTEL\$DLL.W\ /W4 /WX /Zl
    /EHsc /GR /GS /Gm- /O1 /GyF /MD /D_DLL /GF /D_MT /Wp64 /Zc:wchar_t /GL /D_A
    FX_CORE_IMPL /D_AFX_OLE_IMPL /D_AFX_DB_IMPL /D_AFX_NET_IMPL /D_AFX_MONOLITHIC /D
    _MFC_DLL_BLD /D_WINDLL /D_AFXDLL /D_MBCS /D_AFX_DISABLE_DEPRECATED /D_AFX_NOFORC
    E_MANIFEST /D_ATL_NOFORCE_MANIFEST /D_CRT_NOFORCE_MANIFEST /D_ATL_ENABLE_PTM_WAR
    NING /c objcore.cpp
    cl : Command line warning D9035 : option ‘Wp64’ has been deprecated and will be
    removed in a future release

    objcore.cpp
    NMAKE : fatal error U1073: don’t know how to make ‘INTEL\MFC90.DEF’
    Stop.
    NMAKE : fatal error U1077: ‘”C:\Program Files\Microsoft Visual Studio 9.0\VC\BIN
    \nmake.exe”‘ : return code ‘0x2’
    Stop.
    —————————————————————

  2. Sven sagt:

    Ich habe mich wohl etwas ungenau ausgedrückt. Es müssen nur die Namen IN den .def-Dateien angepasst werden, die Dateinamen selbst dürfen NICHT geändert werden.

  3. Bernd Wagemann sagt:

    Danke, manchmal habe ich einfach ein Brett vorm Kopf.

  4. Peter sagt:

    Äh ich glaub das muss ich mir nochmal genauer durchlesen das klingt ein bischen nach der lösung meines problems :o)

Top