Wielkość pliku Exe - Lazarus

0

Witam,
znalazłem informację, że odnaczenie opcji "Generate info for the debugger (slower/increases exe-size)" w opcjach kompilatora (odpluskiwanie) znacząco zmniejsza wielkość pliku wynikowego.
U mnie wielkość pliku Exe po zmienia tej opcji nie zmieniła się nawet o bajt.

Ktoś to sprawdzał i może się wypowiedzieć?

1

Nie mam Lazarusa ale mam pytanie, kompilujesz projekt jako Release czy Debug, bo to zapewne tyczy tylko opcji Debug i tam zmniejsza wielkość pliku wynikowego?

9

To może przebuduj projekt i daj szansę kompilatorowi na obcięcie rozmiaru? :D

Zasada jest prosta. Domyśle generowany jest plik wykonywalny, który prócz kodu zawiera symbole debuggera — exe waży kilkanaście megabajtów. Można te symbole usunąć całkowicie (powodzenia przy debugowaniu), a można też je wydzielić do osobnego pliku, z rozszerzeniem .dbg.

Aby to zrobić, wystarczy wejść w ustawienia projektu, zaznaczyć gałąź Compiler Options i kliknąć w przycisk trzykropka:

project options.png

W okienku istniejących trybów znajduje się tylko domyślny. Kliknij w przycisk Create Debug and Release modes:

build modes.png

Wygenerowane zostaną dwa dodatkowe tryby.

new modes.png

Domyślny nie jest już potrzebny, więc możesz go wywalić. Na koniec zapisz zmiany. I teraz ustawienia kompilacji i debugowania będą zależeć od aktywnego trybu. Automatycznie wygenerowany tryb Release posiadać będzie typowe ustawienia kompilacji, tak aby nie używać symboli, do tego wyższe optymalizacje, brak asercji i testowania zakresów. Natomiast w tak wygenerowanym trybie Debug, symbole będą zapisywane w osobnym pliku, dzięki czemu plik wykonywalny będzie ważył średnio dwa megabajty.

debug.png

Jak będziesz chciał to sobie możesz wygenerować więcej trybów, z innymi ustawieniami — te są zapisywane automatycznie, podczas zmiany ustawień w oknie ustawień projektu. Jak będziesz chciał zmienić konfigurację któregoś trybu, to włącz okno ustawień, zaznacz gałąź Compiler Options i wybierz tryb z comboboksa, znajdującego się u góry okna.

Natomiast jeśli będziesz chciał szybko skompilować dany tryb, to możesz tryb wybrać w głównym oknie IDE. Ja tych przycisków nie używam, mam je ukryte, więc to se sam sprawdź. Jest też opcja kompilacji wielu trybów jeden za drugim — znajdziesz opcję w głównym menu IDE (sam mam ustawionego hotkeya do tego). IDE najpierw zapyta które tryby kompilować, więc zaznacz na liście te, które chcesz przebudować i potwierdź wybór.


Aaa, i nie przestrasz się, jak w trybie Debug, po zamknięciu programu wyskakiwać będzie okienko błędu. To nie jest błąd — w tym komunikacie są zawarte informacje na temat zużycia pamięci podczas sesji. Tak więc jeśli wyskoczy tylko jeden komunikat, to znaczy, że nie było wycieków pamięci. Przykład z mojego projektu:

heaptrc report.png

Jeśli tych komunikatów będzie dużo, to ubij apkę skrótem Ctrl+F2 (lub z poziomu menu głównego IDE), bo każdy wyciek będzie w nich zgłoszony i życia może Ci braknąć na zapoznanie się ze wszystkimi. W momencie wyskoczenia raportów o wyciekach spokojnie możesz ubić aplikację (przerwać debugowanie), bo cały kod projektu został już wykonany, tak więc jeśli jakiś kod jest wykonywany przy zamykaniu programu, to on najpierw zostanie wykonany (np. sekcje finalization czy cokolwiek z głównego pliku projektu), a dopiero na koniec HeapTrc będzie wyrzucał raporty o wyciekach.

Jeśli nie chcesz widzieć tych komunikatów, to odznacz opcję Use HeapTrc unit w ustawieniach projektu:

heaptrc.png

1

W nowej wersji upx.exe https://upx.github.io /upakujesz plik wykonywalny projektu lazarusa. Do tej pory kompilował delphi, dll z projektu delphi
upx.exe lazproject.exe --best --crp-ms=999999 --force --compress-resources=1 --strip-relocs=1 --compress-icons=0 --compress-exports=1 --lzma. Taką komendę wpisujesz w pliku .bat koło upx.exe. Antywirusy np. kasperski czy inne nie za bardzo doczepią się do crc32 i 64 - sumy kontrolnej pliku. = bardzo dobra kompresja pliku exe. Z 23 Mb z odpluskwiaczem do około 0,5 Mb na dysku nawet mniej. Co uzyskujesz tą kompresją? UPXO UPX1 to to, że masz mniejszy rozmiar pliku wykonywalnego exe a po UPXO UPX1 deszyfracja zachodzi w pamięci RAM. Niezauważalna okiem. Dla pliku w lazarusie np. 100Mb kompresja UPX 6Mb. Czy otworzysz 100 Mb plik czy 6 Mb nie odczujesz tego.

2
Mariusz Bruniewski napisał(a):

W nowej wersji upx.exe https://upx.github.io /upakujesz plik wykonywalny projektu lazarusa. Do tej pory kompilował delphi, dll z projektu delphi

Nie. UPX od zawsze potrafił i nadal potrafi pakować pliki wykonywalne, zaprogramowane w dowolnym języku programowania, o najróżniejszych formatach, a nie tylko te generowane przez kompilator Delphi.

Antywirusy np. kasperski czy inne nie za bardzo doczepią się do crc32 i 64 - sumy kontrolnej pliku. = bardzo dobra kompresja pliku exe.

Antywirusy mogą i bardzo często będą blokować takie pliki, ze względu na ich mechanizmy heurystyki. Dziś używanie UPX nie ma praktycznie żadnego sensu, a czas rozruchu programu nie jest wprost proporcjonalny do jego wagi. Poza tym dzisiejsze dyski twarde mają gigantyczne przestrzenie oraz nawet zwykli ludzie mają dostęp do łączy o przepustowości dziesiątek megabitów, więc to żadna różnica czy plik wykonywalny ma 1MB czy 50MB.

Nikt normalny nie będzie ryzykował zablokowania programu przez antywirusy tylko po to, by obciąć kilka megabajtów exeka. No chyba że oprogramowanie ma wiele plików wykonywalnych i miliony dll-ek, to wtedy można się zastanowić.

Z 23 Mb z odpluskwiaczem do około 0,5 Mb na dysku nawet mniej.

No jak się pakuje symbole do pliku wykonywalnego, to nie dziwota, że się 20MB robi. Bez symboli będzie to 2MB i uruchomienie programu z takiego pliku czy pobranie go z sieci i tak potrwa tyle samo, więc pakowanie i tak jest bezcelowe.

Jak ktoś nie ogarnia jak nie dołączać symboli do pliku wykonywalnego to wyżej podałem tutorial. A jak ktoś ma plik wykonywalny z symbolami i nie ma źródeł lub po prostu lubi konsolę, to może skorzystać z programu strip.exe i sobie te symbole usunąć (strip.exe jest częścią pakietu Lazarusa).

Co uzyskujesz tą kompresją?

Kolejne problemy na głowie i bezpodstawne przekonanie, że zrobiło się coś pożytecznego. :D

0

Dzięki za odpowiedzi.
Wypowiedzilibyście się na temat tego co znalazłem na tej stronie w sekcji "Używanie tylko niezbędnych unitów"?

https://www.dzyszla.pl/porada-17.html#uses

Czy to nie są bzdury? Czy podczas kompilacji nieużywane elementy nie są pomijane? Nie jest to sprawdzane? Bo tak wynikałoby z tej treści.

2

FPC podczas kompilacji listuje nieużywane moduły, a IDE wyrzuca te informacje w oknie Messages. Ale nie są zgłaszane wszystkie nieużywane unity, a tylko te, które nie są używane i jednocześnie nie mają kodu w sekcjach initialization i finalization. Jeśli chcesz widzieć wszystkie komunikaty zgłaszane przez FPC to w oknie Messages wyłącz ich filtrowanie:

screenshot-20210512210123.png

Wtedy po przebudowie/kompilacji projekty, powinieneś widzieć ich więcej, w tym te bezużyteczne (dlatego domyślnie schowane):

screenshot-20210512210240.png

W razie czego IDE jest wyposażone w narzędzie do wyszukiwania nieużywanych modułów i ono listuje wszystkie nieużywane moduły (a przynajmniej takie wrażenie sprawia):

screenshot-20210512205844.png

Skrót klawiszowy może być inny, bo sam dawno temu przemapowałem je sobie tak, aby było mi wygodnie i już nawet nie pamiętam jak wyglądają skróty domyślne do różnych funkcji. W każdym razie sprawdź w menu głównym.

0

@furious programming: Dzięki za wyjaśnienie. Jednak chodzi mi nie o pomijanie całych modułów a ich nieużywanych w kodzie elementów (funkcji, procedur, zmiennych - czegokolwiek w zasadzie bez jakichkoliwek referencjui w kodzie). To tak odnoście wspomnianego artykułu.

1

Wspomniany artykuł zawiera wiedzę jeszcze z epoki brązu, dotyczącą jakiegoś starego Delphi — to nie jest dobre źródło wiedzy, a tym bardziej, jeśli używasz Lazarusa/FPC (a na to wskazuje tytuł ten wątku).

Nie będę się tutaj wypowiadał o nowych Delphi, tych środowisk nie widziałem na oczy od lat, ale FPC nie dołącza do binarek nieużywanych globalnych procedur, funkcji, typów, zmiennych i stałych. A tym bardziej przy włączonych silnych optymalizacjach.

Tak mi się przynajmniej wydaje, choć nawet jeśli nie, to dla mnie to nie jest problem, bo sam dbam o to, aby w źródłach nie mieć elementów nieużywanych. W razie czego zapytaj na forum Lazarusa, tam praktycznie codziennie przesiadują deweloperzy FPC, więc z chęcią odpowiedzą na takie pytania. Ewentualnie przegrzeb dokumentację, bo tam też takie informacje powinny być podane.

0
darekdarek napisał(a):

Dzięki za odpowiedzi.

Wypowiedzilibyście się na temat tego co znalazłem na tej stronie w sekcji "Używanie tylko niezbędnych unitów"?

https://www.dzyszla.pl/porada-17.html#uses

Czy to nie są bzdury?

Nie.

Czy podczas kompilacji nieużywane elementy nie są pomijane?

Co do zasady, są pomijane.

Nie jest to sprawdzane? Bo tak wynikałoby z tej treści.

Jest to sprawdzane.

Czy moje odpowiedzi są sprzeczne?
Otóż nie są.

Zastanów się...

Załóżmy, że masz w uses moduł którego nie używasz jawnie, ale który ma w sekcji initalization kod który stawia na nogi połowę bibliotek obcych, co spowoduje dołączenie kolejnych modułów. Nawet niejawnie (ale jest do tego stosowny warning).
Czy kompilator (a de-facto linker) powinien go automatycznie odrzucić?

No więc właśnie...
Podobnie jest z zasobami, są dołączane do pliku wynikowego - w końcu możesz mieć moduł bez kodu, ale z definicją zasobów wykorzystywanych przez inne moduły - również przez biblioteki ładowane dynamicznie, czyli poza kontrolą kompilatora na poziomie jednego projektu (EXE, BPL, DLL - aczkolwiek DLL to jeszcze zupełnie inna bajka pod tym kątem; co do zasady każda DLL ma własną wkompilowaną kopię RTLa. Każda DLL!).
I jak widzisz teraz, rozumowanie na poziomie modułów nie ma większego sensu, ale ma sens na poziomie konkretnych "kawałków kodu" - jak napisał @furious programming

1 użytkowników online, w tym zalogowanych: 0, gości: 1