Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C++: Windows-ohjelman koon pienennys

Sivun loppuun

BlueByte [31.12.2004 21:19:44]

#

kertokaas, tiedättekö mitä tapoja olisi pienentää (käännetyn) ohjelman kokoa.

Juice [31.12.2004 21:47:46]

#

Dev-C++: Tools > Compiler Options > Settings > Optimization ja Tools > Compiler Options > Settings > Linker ja debuggausinformaation OFF.

BlueByte [31.12.2004 22:26:51]

#

jea, mitä muita keinoja

Metabolix [31.12.2004 22:32:55]

#

Mitähän kaikkea mahdat siihen tunkea, ja miten pieneksi sen haluat? Minulla ainakin ohjelma, joka vain luo ikkunan, vie noin 50kb ilman sen kummempaa optimointia (debugit tietysti pois). Tuskin siitä enää hirveästä pääsee alemmaksi.

#define WIN32_LEAN_AND_MEAN vai miten se nyt kirjoitetaan... Tuo karsii vähän turhia pois. Kirjoitetaan ennen include-rivejä (tietenkin).

Edit: Olikos tämä nyt 2005-Demon koon pienentämiseen? :D

BlueByte [31.12.2004 22:34:42]

#

Metabolix kirjoitti:

Mitähän kaikkea mahdat siihen tunkea, ja miten pieneksi sen haluat? Minulla ainakin ohjelma, joka vain luo ikkunan, vie noin 50kb ilman sen kummempaa optimointia (debugit tietysti pois). Tuskin siitä enää hirveästä pääsee alemmaksi.

#define WIN32_LEAN_AND_MEAN vai miten se nyt kirjoitetaan... Tuo karsii vähän turhia pois. Kirjoitetaan ennen include-rivejä (tietenkin).
Edit: Olikos tämä nyt 2005-Demon koon pienentämiseen? :D

joo on tämä. Niin tämä oli kyllä opengl ohjelma mut ihan sama. :p
hmm vieläkin vie 254kt .. liian iso. (tyhjä ikkuna)

edit: hmm sain 137kt pienennettyy (ja vaihdoin C++ C:hen) kun oli jotain moskaa hmm.. vieläkin liian iso. pitäisi saada alle 50kt kun mulla on esimerkki tiedostoja samasta ohjelmasta käännettynä jollain VC++lla (44kt)

Metabolix [31.12.2004 23:15:30]

#

VC++:ssa on käsittääkseni sellainen kiva ominaisuus, että linkkeri karsii pois kaikki käyttämättömät funktiot. En ole ihan varma, muttä näin minä tuon manuaalin tekstin ymmärtäisin. Siihen tulokseen et tule Devillä pääsemään.

BlueByte [01.01.2005 00:30:00]

#

nooh.. ellei tosi tiukkaa tee niin ei sitten tarvitsekkaan.

thefox [01.01.2005 00:37:20]

#

Jos et tarvitse standardikirjastoja niin ne nappaamalla pois saat varmasti binäärin kokoa hivattua alas todella paljon, luulisin että tuollainen tyhjä ikkuna menee pariin kilotavuun. En tosin tiedä miten tuo temppu Dev-C++:lla tehdään.

Yksi juttu mitä voit kokeilla on jonkun PE-pakkerin (esim. UPX, google) käyttäminen, tästä ei tosin ole kilpailun kannalta mitään hyötyä koska kokorajoitus koskee ainoastaan paketin kokoa (ja PE-pakkerilla saatu hyöty "häviää" esim. zippiin pakatessa).

Masfonos [02.01.2005 01:54:43]

#

VC++:lla saa hyvin helpolla tavalla pieniä ohjelmia. Minulla käytössä v6.0

Release versio valitaan valikosta: Build -> Set Active Configuration. Sieltä Win32 Release. Tulee jokaisen uuden projektin mukana.

Seuraava ohjelma käännettynä (release versio):

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
	return 0;
}

small.exe: 36 864 tavua
UPX pakattu --best asetuksella: 12288 tavua

Nyt lisätään nopea pienennys. Valitaan Project -> Settings - C&C++ ja kategoria Code Generation. Use runtime library kohtaan valitaan Multithreaded DLL.

Seuraava sivu Link:

Project Optionsiin lisätään seuraava: /ALIGN:512 tai /opt:nowin98. Molemmilla on sama lopputulos.

Poistutaan projektin asetuksista ja käännetään uudestaan.

small.exe: 2 560 tavua

Aika pieni jo mutta pystymme parempaan.

Lisätään koodiin aivan ensimmäiseksi seuraava rivi:

#pragma comment(linker, "/MERGE:.data=.text /MERGE:.rdata=.text /SECTION:.text,EWR /IGNORE:4078")

small.exe: 1 536 tavua

Tuo on jo aika hyvin. UPX ei suostu pakkaamaan enään tuota.

Ohjelman saa vieläkin pienempään. Olen kääntänyt VC++:lla vajaa 500 tavun exen mutta en nyt muista kaikkia juttuja mitä siihen vaadittiin. Tietysti jos käyttää valmiita kirjastoja ohjelmassa sen koko nousee, tietenkin.

[edit] Pieni optimointi saatiin vielä tehtyä. Parempi, että tekee tuon yllä olevan ja sitten tekee tämän.

Valitaan Project -> Settings -> Link. Sieltä laitetaan ruksi Ignore all default libraries. Tämän jälkeen et voi käyttää perus C-kirjastoja koska niitä ei ole lisätty mukaan. Poistutaan asetuksista ja käännetään uudestaan. Huomaat, että kääntäjä valittaa puuttuvasta symbolista _WinMainCRTStartup. Muutetaan koodi seuraavaan muotoon.

// Pragma poistettu, sitä ei tässä versiossa tarvita
#define WIN32_LEAN_AND_MEAN
#include <windows.h>

int WINAPI WinMainCRTStartup()
{
    return 0;
}

Ohjelma on toiminnallisesti täysin sama kuin alkuperäinen mutta koko on pudonnut pyöreään kiloon. small.exe: 1024 tavua

Masfonos [02.01.2005 06:38:47]

#

Metabolix kirjoitti:

Mitähän kaikkea mahdat siihen tunkea, ja miten pieneksi sen haluat? Minulla ainakin ohjelma, joka vain luo ikkunan, vie noin 50kb ilman sen kummempaa optimointia (debugit tietysti pois). Tuskin siitä enää hirveästä pääsee alemmaksi.

Tuota minun ylläolevaa oppia käyttämällä tein juuri ohjelma joka avaa ikkunan ja avaa Direct3D8 liittymän, sen koko 3 584 tavua.

[edit] Pudotin kokoa 3 072 tavuun.

BlueByte [02.01.2005 15:33:19]

#

Niih.. harmi etten pitkällä kepilläkään suostu koskemaan mihinkään micro$oft kakka kääntäjiin, hyi helvetti.

rndprogy [02.01.2005 15:36:11]

#

BlueByte kirjoitti:

Niih.. harmi etten pitkällä kepilläkään suostu koskemaan mihinkään micro$oft kakka kääntäjiin, hyi helvetti.

Taitaa vaatia jonkinlaisia perusteluita.

Metabolix [02.01.2005 22:37:01]

#

BB voisi perustella kantaansa.

Masfonos kirjoitti:

lainaus:

Lisätään koodiin aivan ensimmäiseksi seuraava rivi:

#pragma comment(linker, "/MERGE:.data=.text /MERGE:.rdata=.text /SECTION:.text,EWR /IGNORE:4078")

Kummasti minun EXEni kasvoi 12 kiloa kun lisäsin tuon (VC++ 7.1). Alignin muuttaminen pienentää kokoa peräti 8 kt. Käytössä on Direct3D9. Ignore All Default Libraries on päällä, liitettynä projektiin "Winmm.lib d3dx9.lib d3d9.lib libc.lib" ja ilman noita ei toimi. Eliminate Unreferenced Data (/OPT:REF) pienensi ohjelman 1,21MB:stä 572kb:hen. Resursseista löytyy vain 32x32 ikoni. Saakos tästä vielä pienemmän? UPXia ei lasketa, jos ZIP pystyy samaan.

thefox [02.01.2005 23:49:49]

#

Kannattaa muistaa, että alignien ym. poistaminen ei ole tässä tapauksessa myöskään kovin järkevää, koska ZIP pakkaa juuri tuollaiset nollajonot hyvin. Tärkein optimointi mitä tällaisessa tapauksessa voi koon suhteen tehdä on jättää standardikirjastot pois. Siinäkin tapauksessa erot koossa ovat kuitenkin suhteellisen pieniä. En usko että kenenkään demoprojekti siihen kaatuu, että binääri (ilman grafiikoita, musiikkia yms tietysti) meinaa syödä koko yhden megatavun tilan :)

Metabolix [02.01.2005 23:58:15]

#

No tuossahan se on jo 580 kt. ZIP on onneksi vain 270 kt.

thefox [03.01.2005 00:31:12]

#

Ai, luulin että siinä oli jo grafiikkaa tai muuta taidetta mukana. Aika oudolta tuntuu, että Direct3D tuota noin paljon bloattaisi. Käyttäväthän esim. Farb-rauschin (ja monien muiden) 64K-introt DirectX:ää.

Nyt taisinkin huomata: käytät D3DX:ää, se epäilemättä kasvattaa tuon binäärin kokoa.

Masfonos [05.01.2005 01:58:48]

#

Pientä päivitystä....Sain pudotettua kokoa alle 500 tavuun käyttämällä VC++ 6.0. Tässä koko koodi.

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#pragma comment(linker, "/FILEALIGN:16")
#pragma comment(linker, "/ALIGN:16")
#pragma comment(linker, "/MERGE:.rdata=.text")
#pragma comment(linker, "/MERGE:.text=.text")
#pragma comment(linker, "/MERGE:.reloc=.text")
#pragma comment(linker, "/NODEFAULTLIB")
#pragma optimize("gsy", on)

int WinMainCRTStartup()
{
	return 42;  // Douglas Adams ;)
}

Käännä release-versio ja tuloksena on 496 tavua pieni exe. Huom. siis VC++ 6.0.

thefox [05.01.2005 11:11:34]

#

Minulle tuli kyllä ihan yllätyksenä että tuo binääri vielä toimi kun filealign oli 16 (ainakin XP:llä) :) Voisiko joku jolla on Windows 98 ja Windows 2000 -käyttöjärjestelmät testata toimiiko tuollainen binääri niilläkin?

Binäärin saa täältä jos ei satu omistamaan MSVC:tä:
http://personal.inet.fi/viihde/sivut/fuchs/SmallBinary.exe

Gaxx [05.01.2005 11:22:46]

#

Mulla on 98 ja kun yritän ajaa tuon binäärin, se herjaa seuraavaa:

"Tiedosto SMALLBINARY.EXE on linkitetty väärin kohdistuksen ollessa alle 0x1000. Korjaa virhe ja linkitä tiedosto sitten uudelleen."

Lisäksi se herjaa: "Unknown file format!"

Linkku [05.01.2005 11:52:51]

#

Debuggerin mukaan tuo tiedosto ei sisällä muuta kuin

push ebp
mov ebp, esp
push 2A ; 42, palautusarvo
pop eax ; pistetään palautusarvo eaxiin?
pop abp
retn

Kuva http://koti.mbnet.fi/linkku-/schei%dfet/img/smallbin.png

Metabolix [05.01.2005 12:03:26]

#

Windows98 ei taida tosiaan tukea noita tiedostoja, joita on viritelty liikaa. Alignin muutoksen piti kai vain hidastaa toimintaa (vaikka kai silläkin on rajansa... 16b?), mutta kokonaisuutena tuo taitaa mennä Win98:lta yli.

Suurin osa tuon ohjelman koosta tulee tosiaan siitä, mitä debuggeri ei näytä: Heksaeditori tietää, että tiedostossa lukee "This program cannot be run in DOS mode." Lisäksi taitaa löytyä kyseisen tekstin näyttämiseen tarvittava koodi ja se, millä selvitetään ollaanko DOSissa.

ZIP-pakkaus sai tuon ohjelman kooksi 328 tavua.

thefox [05.01.2005 12:25:38]

#

Linkku: debuggeri näyttää tietenkin vain senhetkisen suoritettavan koodin.

Win98:lle taitaa 512 olla pienin kelpaava file-align. Tuolla sektioalignilla ei taas ole mitään merkitystä binäärin kokoon.

Ihan ilman heksaeditorin käyttöä tuota saisi vielä viilattua pienemmäksi määrittelemällä oman DOS-stubin /stub-switchillä linkkerillä ja vielä sitäkin pienemmäksi väsäämällä koko PE-headerin käsin uusiksi. Tällöin tosin saattaisi tulla edelleen uusia yhteensopivuusongelmia.

rutkis [05.01.2005 15:37:57]

#

Muistaakseni tiedosto pienenee vielä silläkin kun kikkailee exestä .com päätteisen ajettavan tiedoston.

Muiselen joskus lukeneeni jotain opasta missä oli ohjeistusta exen pienennykseen esim 4k-intro kisaa varten.

thefox [05.01.2005 21:35:14]

#

Tarkoittanet tapaa, jossa Win32-binääri liitetään pienen DOS COM-stubin perään. COM-ohjelma tallentaa binäärin johonkin väliaikaistiedostoon ja ajaa sen. COM-tiedosto pakataan jollain COM-pakkerilla, esim. APACK:lla. Tällöin saadaan parempi ratio kuin Win32-pakkerilla, koska myös headeri pakataan eikä tarvitse huolehtia mm. sektioneista.

rutkis [08.01.2005 13:47:08]

#

Juurikin tuota.


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta