Dotyczy Visual Studio 2008 SP1 na Viście.
Ściągamy
źródła eMule. Wypakowujemy. Wchodzimy do katalogu
srchybrid i otwieramy
emule_vc9.sln. Upewniamy się, że mamy wybraną konfiguracje
Release. Budujemy (CTRL+SHIFT+B).
Cóż trzeba przyznać, że eMule coraz bardziej zauważa najnowsza wersję VS. Kiedyś kompilacja pod VS2008 to były prawdziwe przejścia. Teraz jest nawet solucja pod tą wersję, co daje nadzieje na w miarę bezproblemową kompilacje (to co jest niżej to jest właśnie w miarę bezproblemowa kompilacja).
Bardzo szybko możemy kompilacje przerwać, bo już lecą pierwsze błędy. Kiedyś do źródeł eMule był dołączany plik Readme.txt, który zawierał informacje o wszystkich zewnętrznych bibliotekach potrzebnych do kompilacji eMule. Trudno, trzeba sobie będzie poradzić bez niego.
Mamy błąd:
Error 1 fatal error C1083: Cannot open include file: 'ResizableLib\ResizableDialog.h': No such file or directory d:\programowanie\c++\emule 0.49c\emule 0.49c\srchybrid\traydialog.h 3 emule
Pobieramy
ResizableLib 1.3 i wypakowujemy do głównego katalogu źródeł. Dodajemy do solucji
ResizableLib.dsp. Upewniamy się, że dla konfiguracji
Release solucji jest wybrana konfiguracją
ReleaseStatic ResizableLib.
Dajemy rebuild dla samego
ResizableLib. Modyfikujemy odwołanie
do biblioteki ResizableLib w opcjach projektu eMule na
.\..\ResizableLib\Release_Static\ResizableLib.lib
:
Wybieramy właściwości solucji eMule i ustawiamy w zależnościach, że eMule zależy od
ResizableLib .
Modyfikacji tej zależności dokonujemy po dodaniu każdego nowego projektu do solucji.
Budujemy. Mamy błąd:
Error 1 fatal error C1083: Cannot open include file: 'crypto51/rsa.h': No such file or directory d:\programowanie\c++\emule 0.49c\emule 0.49c\srchybrid\ClientCredits.h 23 emule
Brakuje nam biblioteki
Crypto++ w wersji 5.2. Zjeżdżamy na stronie projektu do miejsca gdzie jest tabelka porównawcza zgodności wersji
Crypto++ z platformami. Jak widać wersji 5.2 nie ma, jest 5.2.1 i nie jest ona kompatybilna z VS2008. Co nie oznacza, że by nie działała, tylko z pewnością były potrzebne jakieś poprawki. Trochę się z tym kiedyś bawiłem, błędy brały się z tego, że VS2008, czy VS2005 (już nie pamiętam) nie potrafił skompilować poprawnie klas dość intensywnie korzystających z szablonów. Jakoś mi się nie marzy poprawianie tego rodzaju błędów - nie wiem nawet czy mi się udało. Kiedyś na stronie projektu
Crypto++ był dostępny patch dla jakiejś wersji VS, która usuwała te błędy z szablonami. W każdym razie używałem już parę wersji eMule kompilowanych zawsze z najnowszymi wersjami
Crypto++ nieuświadczając żadnych problemów i teraz zrobimy tak samo.
Czyli pobieramy wersje 5.6.0 i wypakowujemy w głównym katalogu do katalogu
CryptoLib. Dodajemy projekt
cryptlib.vcproj do solucji. Dla lepszego samopoczucia zmieniamy nazwę projektu na
CryptoLib. Przebudowujemy projekt CryptoLib. Dostajemy błędy:
Upewniamy się jak poprzednio, że w eMule ustawiona jest właściwie ścieżka do biblioteki
.\..\CryptoLib\Win32\Output\Release\CryptoLib.lib
. Teraz pozostaje nam tylko zmienić we wszystkich plikach (CTRL+SHIFT+H) :
Budujemy. Mamy błąd:
Error 30 fatal error C1083: Cannot open include file: 'dxtrans.h': No such file or directory C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\qedit.h 498 emule
.
Przeszukujemy nasz projekt pod kątem występowania
qedit.h i w
emule_site_config.h znajdujemy informacje, że jeśli chodzi o VS2008 to musimy zainstalować DirectX 9 SDK. Ściągamy sobie najnowsze SDK
(nie ściągać - czytać dalej) z marca 2009 i instalujemy je. Trochę to waży, ale czego nie robi się dla jednego głupiego pliku nagłówkowego. Pewnie dało by to się obejść, pobrać ten plik osobno, możemy także wyłączyć to
QEDIT czymkolwiek to jest. Na razie zainstalujmy samo DirectX SDK. Restartujemy Visual Studio i w opcjach VS upewniamy się, że ustawienia są prawidłowe.
No to kolejny rebuild na eMule. Bez sukcesu, ciągle ten sam błąd. No to szukamy tego plik
dxtrans.h. U mnie znalazłem go tylko w SDK na smartphony. No to
ściągamy go sobie z sieci i kopiujemy tutaj
C:\Program Files (x86)\Microsoft DirectX SDK (March 2009)\Include
. Rebuild. Teraz mamy błąd w
dxtrans.h:
Error 29 fatal error C1083: Cannot open include file: 'd3d.h': No such file or directory C:\Program Files (x86)\Microsoft DirectX SDK (March 2009)\Include\dxtrans.h 260 emule
Wygląda na to, że mamy złe SDK.
Tutaj radzą nam zainstalować SDK z sierpnia 2007. Czemu nie, deinstalujemy obecne, instalujemy tamto (najlepiej instalkę dwa razy wypakować). Restart VS i rebuild.
Swoją drogą, kiedyś kompilowałem jakiś projekt w Javie ze źródeł i pliku build.xml wykorzystującego ANT do kompilacji, w trakcie jej trwania jak brakowało jakiegoś projektu to był on ściągany z sieci. Bardzo eleganckie rozwiązanie. Ogólnie to uważam, że każdy projekt powinien być dostępny w postaci zdatnej do natychmiastowego zbudowania, albo powinna przynajmniej istnieć instrukcja (aktualizowana) jak to zrobić.
Znowu mamy stary błąd:
Error 29 fatal error C1083: Cannot open include file: 'dxtrans.h': No such file or directory C:\Program Files\Microsoft SDKs\Windows\v6.0A\include\qedit.h 498 emule
Musimy wejść do opcji VS i ręcznie poustawiać opcje. To SDK w przeciwieństwie do najnowszego nie wie co to VS2008.
Rebuild. No to teraz błąd tego rodzaju:
Error 115 fatal error C1083: Cannot open include file: 'zlib/zlib.h': No such file or directory d:\programowanie\c++\emule 0.49c\emule 0.49c\srchybrid\WebServer.h 3 emule
Brakuje nam biblioteki
ZLib. Pobieramy takową w wersji najnowszej 1.2.3 i wypakowujemy do głównego katalogu do katalogu
ZLib. Katalog taki istnieje, są w nim pliki projektów dla VS2003. Dodajemy do solucji
zlib_vc71.vcproj z głównego katalogu ZLib. Warto wiedzieć, że w katalogu
.\ZLib\contrib\vstudio\vc8
mamy pliki projektu dostarczone przez
ZLib. Zmieniamy nazwę projektu na ZLib (dla lepszego samopoczucia). Rebuild dla
ZLib. I dostajemy jakieś dziwne błędy z kompilacji pliku
inffas32.asm:
1>d:\Programowanie\C++\eMule 0.49c\eMule 0.49c\ZLib\contrib\masmx86\inffas32.asm(647) : error A2070:invalid instruction operands
1>d:\Programowanie\C++\eMule 0.49c\eMule 0.49c\ZLib\contrib\masmx86\inffas32.asm(649) : error A2070:invalid instruction operands
1>d:\Programowanie\C++\eMule 0.49c\eMule 0.49c\ZLib\contrib\masmx86\inffas32.asm(663) : error A2070:invalid instruction operands
1>d:\Programowanie\C++\eMule 0.49c\eMule 0.49c\ZLib\contrib\masmx86\inffas32.asm(720) : error A2070:invalid instruction operands
Tutaj mamy opis tego problemu. Zmieniamy wszędzie
movd mm4, [esp+0]
na
movd mm4, dword ptr [esp+0]
Upewniamy się, że ścieżki do źródeł
ZLib (są poprawne)
i do skompilowanej statycznie biblioteki (zmienić na
.\..\zlib\release\zlib_vc71.lib
) są właściwie poustawiane.
Budujemy. Mamy błąd:
Error 1 fatal error C1083: Cannot open include file: 'atlsmtpconnection.h': No such file or directory d:\Programowanie\C++\eMule 0.49c\eMule 0.49c\srchybrid\SendMail.cpp 22 emule
Po poszukiwaniach trafiamy
tutaj. Ściągamy potrzebne źródła. Wypakowujemy do głównego katalogu do katalogu
ATLServer. Dodajemy do dodatkowych źródeł projektu .\
..\ATLServer\include
.
Budujemy. Mamy błąd:
Error 466 error C2451: conditional expression of type 'void' is illegal d:\Programowanie\C++\eMule 0.49c\eMule 0.49c\srchybrid\PeerCacheFinder.cpp 672 emule
.
Cóż, pozostaje nam założyć, że
result.Encode()
zawsze zwraca
true.
Budujemy. Mamy błąd:
Error 1 fatal error LNK1181: cannot open input file '..\id3lib\libprj\release_vc9\id3lib.lib' emule emule
Dołączamy do solucji projekt
.\id3lib\libprj\id3lib_vc9.vcproj
. Dajemy rebuild na
id3lib. Nie powinno być błędów. Teraz tylko upewniamy się, że ścieżka do biblioteki jest dobrze ustawiona (nie trzeba zmieniać).
Budujemy. Mamy błąd:
Error 759 fatal error LNK1181: cannot open input file '.\cximage\release_vc9\cximage.lib' emule emule
Dołączamy do solucji projekt
.\srchybrid\CxImage\cximage_vc9
. Dajemy rebuild na
CxImage. I mamy błąd:
Error 1 fatal error C1083: Cannot open include file: '../libpng/png.h': No such file or directory d:\programowanie\c++\emule 0.49c\emule 0.49c\srchybrid\cximage\ximapng.h 25 CxImage
Przydałoby się pobrać
libpng. Wypakowujemy do głównego katalogu
lpng1235
, zmieniamy nazwe na
libpng
. Dołączamy do solucji projekt
.\..\libpng\projects\visualc71\libpng.vcproj
. Dajemy rebuild na
libpng. Wszystko powinno się skompilować.
Ponawiamy rebuild na
CxImage. Tym razem nie ma błędów. W opcjach projektu eMule sprawdzamy, że ścieżki do obu bibliotek
CxImage i
libpng (zmienić na
.\..\libpng\projects\visualc71\Win32_LIB_ASM_Release\libpng.lib
)
są poprawne i dajemy budowanie na eMule.
Kolejny błąd:
Error 1 fatal error LNK1181: cannot open input file '.\miniupnpc\release_vc9\miniupnpc.lib' emule emule
Robimy to samo co przy
CxImage.
Budujemy. Teraz mamy mnóstwo błędów od linkera.
Zmieniamy dla id3lib w ustawieniach:
Generalnie kiedy mieszamy biblioteki kompilowane w ANSI i w UNICODE to mogą pojawić się błędy linkera od próby użycia dwóch różnych wersji bibliotek MFC (to głównie tyczy się się fukcji systemowych). Jeśli błędy linkera pojawiają się dla funkcji bibliotecznych pomimo tego, że biblioteka jest właściwe podłączona oznacza to prawdopodobnie, że funkcje te nie zostały wyeksportowane z biblioteki z jakiegoś powodu.
Budujemy. Mamy błąd:
Error 1 error C2664: 'CreateFileW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR' d:\Programowanie\C++\eMule 0.49c\eMule 0.49c\id3lib\src\tag_file.cpp 60 id3lib
Zmieniamy
CreateFile()
na
CreateFileA()
.
Budujemy. Mamy mnóstwo błędów od linkera. Podobną zmianę jak dla
id3lib robimy dla
ResizableLib.
Budujemy. Mamy błędy od linkera.
Dla wszystkich projektów zmieniamy:
Podobnie jak mieszanie ANSI z UNICODE tak samo mieszanie MFC z Use Standard Windows Libraries może prowadzić do błędów linkowania.
Budujemy. I mamy błąd:
Error 1 error PRJ0019: A tool returned an error code from "Inserting Vista application icon..." eMule eMule
Zaglądamy do
Post-Build Event dla eMule. i widzimy coś takiego:
..\ReplaceVistaIcon\release\ReplaceVistaIcon "$(TargetPath)" "$(ProjectDir)\res\Mule_Vista.ico" AAAEMULEAPP
Dodajemy do solucji projekt
.\ReplaceVistaIcon\ReplaceVistaIcon_vc71.vcproj
. Zmieniamy nazwę projektu na
ReplaceVistaIcon. Nic nie zmieniamy w opcjach projektu. Ten projekt to samodzielny plik wykonywalny używany w
Post-Build Event. Budujemy eMule.
I w tym momencie powinniśmy dostać
exe.
Robimy jeszcze rebuild wszystkiego i starannie przekopujemy się przez
warningi. Ja mam ich 756, sortujemy je po nazwach dla łatwiejszej roboty. Wszystkie wydają się nieszkodliwe. Ale możemy je pousuwać.
Przeglądamy zawartość
output w poszukiwaniu jakiś nietypowych komunikatów. Np. takiego:
9>SelfTest.cpp
9>You may be using a weak algorithm that has been retained for backwards compatibility. Please '#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1' before including this .h file and prepend the class name with 'Weak::' to remove this warning.
9>SecRunAsUser.cpp
Przeszukujemy projekt jakie pliki (klasy) generują takie komunikaty. Porównujemy je z inkludami w
SelfTest.cpp.
Wychodzi na, że problem dotyczy
md4.h
. W
SelfTest.cpp
przed linijką
#include
dodajemy
#define CRYPTOPP_ENABLE_NAMESPACE_WEAK 1
. Zmieniamy
CryptoPP::MD4 md4;
na
CryptoPP::Weak::MD4 md4;
.
Kolejny to taki:
9>To compile qedit.h you must install the DirectX 9 SDK, to obtain the dxtrans.h header.
Po tych wszystkich przejściach trochę to irytuje. Ciągle jest coś nie tak. Po przeszukaniu naszej solucji okazuje się, że komunikat pochodzi z poza niej. Wpis taki znajdujemy w pliku
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Include\qedit.h
(przynajmniej u mnie). Wydaje mi się, że ten komunikat możemy olać, ten wpis pojawi się zawsze jak kompilator przeanalizuje plik
qedit.h.
I w ten oto sposób kompilacja dobiegła końca. Teraz tylko pozostaje sprawdzić czy wszystko nam działa. Jako, że dostępu do źródeł instalki nie mamy, pozostaje nam pobrać instalke (albo archiwum), zainstalować (albo wypakować) i podmienieć execa.