Gå til innhold

Forskjell i kompilert filstørrelse i windows og linux


Anbefalte innlegg

Er ikke så dreven i c++, men prøver nå å lære meg det litt mer grundig. Bruker Code::Blocks, både i windows og linux, og den bruker mingw kompilatoren igjen såvidt jeg vet.

 

Bare en liten observasjon jeg har gjort, i windows blir filstørreslen ganske mye større. Eks, et lite program hvor sourcen er <2 kB, blir kompilert til 499 kB i windows, men bare 28 kB i linux. Kun et konsoll-program (har ikke lært noe om grafikk ennå). Hva kommer dette av? Vil dette utjevne seg når prosjektene blir større?

Lenke til kommentar
Videoannonse
Annonse

Det var det da, aner desverre ikke hva du prater om :blush: Ctrl+ F9 i code::blocks (= "compile current file"), så lager den en .exe i windows, og en, eh, "fil" i linux (må visst kjøre den ved å skrive ./filnavn i terminal - mener jeg det var). I windows kjører jeg den fra cmd.exe konsollen.

 

Eneste jeg kan tenke meg er at det burde være en liten forskjell i fileheaderen til de forskjellige operativsystemene, men at forskjellen blir så stor skjønner jeg ikke. Ikke at det er så "farlig", 499 kB har man da plass til i dag, men det skulle vært interessant å visst hvorfor og hvordan unngå det, hvis mulig. Kan virke som om windows-versjonen av gcc/mingw inkluderer noe som linux-versjonen ikke gjør/trenger?

 

Hva er CRT? Og dynamic link? Vet det er noe som heter en linker i forbindelse med kompilering av c++, som lager såkalte objektfiler. Eller er det make det heter? Men jeg har aldri gjort det manuellt selv. Burde kanskje gjort det noen ganger også før jeg hopper inn i et IDE?

 

Takker for svar.

Lenke til kommentar

C/C++ -> Obj (.o i linux, .obj i windows) -> Linkeren -> programfil

 

I Windows kalles obj filene for COFF som står for Common Object File Format etter det jeg husker.

 

Windows sine .exe/.dll filer heter PE som står for Portable Executable

Linnux sitt programfil format heter ELF som står for Executable and Linkable Format.

 

Begge disse to må inkludere alt som brukes av programmet på en eller annen måte, og det finnes 3 forskjellige måter å gjre det på:

static link (koden legges inn sammen med programfilen)

dynamic link (koden ligger utenfor programmet, .dll eller .so og blir lastet når programmet starter)

delayed dynamic link (koden ligger utenfor programmet, men blir kun lastet dersom det blir tatt i bruk)

Den siste er blitt mer og mer vanlig i det siste, blant annet bruker D, C# og Java denne metoden, og det er mulig å få til i C++ også (ihvertfall med Visual C++)

 

Windows programmer har noe som kalles en jump table. Dette er rett og slett en liste med "jmp" instruksjoner som blir byttet ut med adressene til funksjoner som ligger i forskjellige DLL filer når programmet blir lastet. grunnen til at denne er der er fordi det er enklere å fylle inn jump tabellen med instruksjoner enn å bytte ut disse instruksjonene gjennom hele programmet, så dersom et kall skal føres til en ekstern modul, ser det kanskje slik ut:

hopp til nummer 4 i jump tabellen->hopp til LoadLibrary funksjonen i kernel32.dll

 

Når funksjonene er statisk lenket, så er det ingen slike oppføringer i jump tabellen, fordi alle funksjonene som brukes uansett vil ha samme relative adresse uansett hvor programmet lastes. Dette fører dog også til at programfilens størrelse øker siden flere kopier av samme kode vil ligge i minnet (som er poenget med .dll filer: én kode skal kun ligge i minnet étt sted, og en .dll blir kun lastet ut av minnet dersom ingen programmer har brukt den i ett kvarter eller noe)

 

Men det finnes også sannsynligvis debug data i .exe filen din som kanskje ikke er nødvendig. Dette er en liste over linjenummer for forskjellige deler av koden samt debug informasjon som exceptions eller meldinger.

 

Men jeg synes fortsatt at 499 KB er latterlig mye :S så jeg tror kanskje det kan ha noe med cygwin å gjøre, jeg har laget masse programmer i Windows som tar langt mindre enn 499 KB, faktisk så kan jeg ikke huske å noensinne hatt en så stor programfil før :/

Lenke til kommentar

Takker for utfyllende svar!

 

Jeg har ikke akkurat lekt så mye med compiler innstillinger, og aner ikke hvordan jeg skal linke dynamisk. Muligens dette som skjer i linux? Testet litt kjapt nå i windows, fant ingenting om linking, men blandt en lang liste innstillinger fant jeg "strip all symbols from binary", og da nesten halverte størrelsen seg. Men er jo fortsatt stort rom for forbedringer. Prøvde også "optimize for size" i tillegg, men den hjalp ikke så mye.

 

Men får vel først konsentrere meg om å lære mer C++ :)

Lenke til kommentar

i linux heter vel linkeren ld.

I Windows er det ingen standard linker, men Visual C++ har en egen linker med i bin mappa, men som regel klarer compilere å linke på egenhånd. Å linke manuelt er for de mest interesserte da ofte dette kun er nødvendig når du skriver deler av programmet i et annet språk. (assembly er vel det mest nærliggende i C++, selv om mange C++ compilere støtter inline assembly)

 

De fleste compilere må du vel tilogmed be eksplisitt om å ikke linke automatisk.

 

Men når en bruker IDE-er så blir det som regel brukt en ekstern linker, fordi det gjør at IDE-et får en del flere muligheter (for eksempel blande flere språk i et program)

 

Men uansett så er ikke størrelsen på programfilen viktig når du skal lære deg C++, du vil kanskje etterhvert lære deg bedre hva de forskjellige switchene du har er til og hvilke biblioteker du trenger, og kanskje størrelsen faller drastisk når du får litt bedre kontroll over hva du gjør :)

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...