2009-03-27

Kompilacja eMule 0.49c

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.

1 komentarz:

  1. Wielkie podziękowania. Sam jestem zawodowym programistą, ale przejście przez te wszystkie trudności związane z kompilacją może wyczerpać cierpliwość największego amatora Open Source.
    Kompilacja wg wskazówek była bezproblemowa.
    Dzięki raz jeszcze !

    OdpowiedzUsuń