Exe wird zu groß...



  • Allo, ich habe hier nen kleines Programm angefangen. Es läuft auch, jedoch ist die Exe 643kb groß! Hat jemand eine Idee wie sich das verkleinern lässt?

    Compiler : DJGPP mit der IDE RHIDE

    Code:

    #include <iostream>
    #include <conio.h>
    #include <stdio.h>
    
    // Setzen des Carets (=Textcursor) an eine bestimmte Position:
    
    void gotoxy (unsigned short int row, unsigned short int column)
    {
    	std::cerr << "\033[" << row << ';' << column << 'f';
    }
    // Relatives Setzen des Carets:
    
    void caretUp (unsigned short int rows)
    {
    	std::cerr << "\033[" << rows << 'A';
    }
    void caretDown (unsigned short int rows)
    {
    	std::cerr << "\033[" << rows << 'B';
    }
    void caretLeft (unsigned short int columns)
    {
    	std::cerr << "\033[" << columns << 'D';
    }
    void caretRight (unsigned short int columns)
    {
    	std::cerr << "\033[" << columns << 'C';
    }
    // Speichern und Laden einer Caretoition:
    void saveCaret ()
    {
    	std::cerr << "\033[s";
    }
    void loadCaret ()
    {
    	std::cerr << "\033[u";
    }
    // Wechseln der Vorder- und Hintergrundfarbe
    
    void color (unsigned short int fgcol, unsigned short int bgcol)
    {
    	if(fgcol > 7 || bgcol > 7)
    	return;
    	std::cerr << "\033[3" << fgcol << ";4" << bgcol << 'm';
    }
    // L”schen der derzeitigen Zeile ab Zeilenanfang
    
    void clearLine ()
    {
    std::cerr << "\033[2K";
    }
    // L”schen der dereitigen Zeile ab Zeilenanfang bis zur Caretposition
    void clearLineBegin ()
    {
    std::cerr << "\031[k";
    }
    // Lschen der derzeitigen Zeile ab Caretposition bis zum Zeilenende
    void clearLineEnd ()
    {
    std::cerr << "\033[0K";
    }
    // Lschen des gesamten Bildschirms:
    
    void clrscr2 ()
    {
    std::cerr << "\033[2J";
    }
    
    main()
    {
    int i=0;
    unsigned char chr;
    clrscr();
    do
    	{
    	chr=getch();
    	printf("%i ",chr);
    	if ((chr==224) || (chr==0))
    		{
    		chr=getch();
    		printf("%i ",chr);
    		switch(chr)
    		{
    
    		case 80:
    		printf("Pfeil nach unten");
    		break;
    
    		case 13:
    		printf("ENDE!");
    		i=1;
    		break;
    		}
    	     }
    
           }while(true);
           return 0;
    }
    


  • builde es im release-, nicht im debug-modus 😉
    wenn das nichts hilft, schmeiss die std::cerr's raus (sowie alles andere, was den iostream-header braucht) und benutze stattdessen fprintf (stderr, ...).
    🙂



  • Hmmm und wie schalte ich den Debugmodus ab?



  • Hojo schrieb:

    Hmmm und wie schalte ich den Debugmodus ab?

    musst du das manual zu deinem compiler/linker lesen.
    da steht drin, wie man eine exe ohne debug-informationen erzeugt usw...
    🙂



  • Du könntest auch einen anderen Compiler ausprobieren. Der lcc-win32 z.B. macht ganz kompakte, kleine exe Dateien.
    🙂



  • proggingmania schrieb:

    Der lcc-win32 z.B. macht ganz kompakte, kleine exe Dateien.
    🙂

    gute idee. damit sind die doofen std::cerr aufrufe automatisch hinfällig. 😉



  • Soll das ein Programm für eine Embedded-Umgebung werden oder warum ist das "zu groß"? Das letzte Mal als ich geschaut habe wurden Rechner mit 200 GB Festplatten von der Stange verkauft.



  • Nun kein Embedded, aber es soll schon noch auf eine Diskette passen. Das soll mal ein Menü werden, welches über PXE als Disketten Image gestartet wird. Wenn jetzt schon über 600 kb verbraten sind, möchte ich nicht wissen wie groß das Programm is, wenn es fertig ist. Ich werd mal den anderen Compiler ausprobieren.

    EDIT: Der lcc-win32 erzeugt leider 32-Bit Programme. Die laufen nicht auf dem guten alten Ms-Dos oder FreeDos. 😞



  • #include <iostream>
    #include <conio.h>
    #include <stdio.h>
    

    das sind drei recht umfangreiche bibliotheken. brauchst du wirklich alle drei? schmeiss raus, was nicht unbedingt nötig ist.



  • Ich habe nun mal ein einfaches Hello World Programm compiliert.

    #include <stdio.h>
    
    int main(void)
    {
      printf("Hello, world!\n");
      return 0;
    }
    

    Hello.c = 81 Byte
    Hello.exe = 69.869 Byte

    Da kann doch was nicht stimmen oder?



  • Hojo schrieb:

    Ich habe nun mal ein einfaches Hello World Programm compiliert.

    #include <stdio.h>
    
    int main(void)
    {
      printf("Hello, world!\n");
      return 0;
    }
    

    Hello.c = 81 Byte
    Hello.exe = 69.869 Byte

    Da kann doch was nicht stimmen oder?

    Hängt komplett davon ab welche Libraries Du einbindest und welche Optimierungsoptionen Du einstellst.



  • Na, die C-Runtime wird ja auch dazu gelinkt. Schreib mal ein weiteres printf rein. Oder 20 weitere... was passiert? Nichts großartiges. Weil die C-Runtime einmal drin ist und gut.



  • @Artchi: Hast Recht! mit 20 printf() Anweisungen ist die Exe jetzt 70.381 Byte groß. Also ne Differenz von 512 Byte. Aber wie bekomme ich denn nun mein Hauptrogramm kleiner? Werden denn beim Compilieren denn alle Funktionen einer Bibliothek reingepackt oder nur die verwendeten Funktionen?



  • Wie du das Prog mit dem DJGPP kleiner bekommst, wird dir hier niemand sagen können. Das hat nichts mit C++ zu tun, sondern mit dem Compiler.

    Übrigens habe ich ja schon gesagt, das in deinem Mini-Programm die C-Runtime den Löwenanteil hat. Und mir scheint, das du nicht weißt, was eine C-Runime ist. Sonst hättest du gesagt "Achso, das klingt logisch!".

    Wenn du es auf z.B. 9 KByte runter kriegen willst, mußt du den MSVC8.0 Compiler benutzen, der linkt die C-Runtime dynamisch dazu.

    Beim kompilieren wird das erzeugt, was du geschrieben hast. Entscheidend ist das Linken, ob ungenutzte Funktionen weg gelassen werden. Und das wiederrum hängt vom Linker ab, wie gut der ist.



  • Die C Runtime wird unter Windows/DOS statisch gelinkt. Daher hast du immer einen festen Overhead. Du kannst natürlich versuchen eine kleinere Standard Bib zu bekommen, so was wie die diet libc (gibt es aber nur für Windows).

    (-Os -s -fomit-frame-pointer als Compile-Optionen sollte ein bisschen helfen)



  • wenn die echse zu groß wird, weniger füttern!



  • rüdiger schrieb:

    Die C Runtime wird unter Windows/DOS statisch gelinkt. Daher hast du immer einen festen Overhead. Du kannst natürlich versuchen eine kleinere Standard Bib zu bekommen, so was wie die diet libc (gibt es aber nur für Windows).

    (-Os -s -fomit-frame-pointer als Compile-Optionen sollte ein bisschen helfen)

    Wie gesagt: MSVC8 linkt auch dynamisch (sogar per default!). Dann ist ein Helloworld nur 9 KByte klein.



  • Artchi schrieb:

    rüdiger schrieb:

    Die C Runtime wird unter Windows/DOS statisch gelinkt. Daher hast du immer einen festen Overhead. Du kannst natürlich versuchen eine kleinere Standard Bib zu bekommen, so was wie die diet libc (gibt es aber nur für Windows).

    (-Os -s -fomit-frame-pointer als Compile-Optionen sollte ein bisschen helfen)

    Wie gesagt: MSVC8 linkt auch dynamisch (sogar per default!). Dann ist ein Helloworld nur 9 KByte klein.

    Nee, weil du ja noch die DLL brauchst...



  • Eben! dynamisch bedeutet DLL. Nur das die DLL meistens schon auf dem Windows-System installiert ist. Wenn nicht (in der gewünschten Version, eine ist aber mind. immer drauf), kann man ein offizielles entsprechendes C-Runtime-Archiv von der MS-Website downloaden (einmal für alle nutzenden Programme und gut ist).



  • Wenn Du eine kleine EXE willst, dann:
    - verwendet niemals die STL
    - verwende keine MFC/ATL

    wenn Du sie dann noch kleiner haben willst, dann
    - verwende niemals die CRT!

    Damit bekommst Du 2048 Bytes (kleiner geht es nicht; siehe PE-Format):

    #include <windows.h>
    #include <tchar.h>
    #pragma comment(linker, "/entry:entry")
    
    void entry()
    {
      TCHAR szText[] = _T("Hello world\n");
      DWORD dwWritten;
      WriteConsole(GetStdHandle(STD_OUTPUT_HANDLE), szText, lstrlen(szText), &dwWritten, NULL);
    }
    

    Compilieren mit:

    cl /c /O1 /GS- CPP_VS2005.cpp

    und linken mit:

    link /subsystem:console CPP_VS2005.obj kernel32.lib

    Dies ergibt dann im PE:

    Microsoft (R) COFF/PE Dumper Version 8.00.50727.762
    Copyright (C) Microsoft Corporation.  All rights reserved.
    
    Dump of file CPP_VS2005.exe
    
    PE signature found
    
    File Type: EXECUTABLE IMAGE
    
    FILE HEADER VALUES
                 14C machine (x86)
                   2 number of sections
            4694EBC1 time date stamp Wed Jul 11 16:40:01 2007
                   0 file pointer to symbol table
                   0 number of symbols
                  E0 size of optional header
                 103 characteristics
                       Relocations stripped
                       Executable
                       32 bit word machine
    
    OPTIONAL HEADER VALUES
                 10B magic # (PE32)
                8.00 linker version
                 200 size of code
                 200 size of initialized data
                   0 size of uninitialized data
                1000 entry point (00401000)
                1000 base of code
                2000 base of data
              400000 image base (00400000 to 00402FFF)
                1000 section alignment
                 200 file alignment
                4.00 operating system version
                0.00 image version
                4.00 subsystem version
                   0 Win32 version
                3000 size of image
                 400 size of headers
                   0 checksum
                   3 subsystem (Windows CUI)
                 400 DLL characteristics
                       No structured exception handler
              100000 size of stack reserve
                1000 size of stack commit
              100000 size of heap reserve
                1000 size of heap commit
                   0 loader flags
                  10 number of directories
                   0 [       0] RVA [size] of Export Directory
                2020 [      28] RVA [size] of Import Directory
                   0 [       0] RVA [size] of Resource Directory
                   0 [       0] RVA [size] of Exception Directory
                   0 [       0] RVA [size] of Certificates Directory
                   0 [       0] RVA [size] of Base Relocation Directory
                   0 [       0] RVA [size] of Debug Directory
                   0 [       0] RVA [size] of Architecture Directory
                   0 [       0] RVA [size] of Global Pointer Directory
                   0 [       0] RVA [size] of Thread Storage Directory
                   0 [       0] RVA [size] of Load Configuration Directory
                   0 [       0] RVA [size] of Bound Import Directory
                2000 [      10] RVA [size] of Import Address Table Directory
                   0 [       0] RVA [size] of Delay Import Directory
                   0 [       0] RVA [size] of COM Descriptor Directory
                   0 [       0] RVA [size] of Reserved Directory
    
    SECTION HEADER #1
       .text name
          3C virtual size
        1000 virtual address (00401000 to 0040103B)
         200 size of raw data
         400 file pointer to raw data (00000400 to 000005FF)
           0 file pointer to relocation table
           0 file pointer to line numbers
           0 number of relocations
           0 number of line numbers
    60000020 flags
             Code
             Execute Read
    
    RAW DATA #1
      00401000: 55 8B EC 83 EC 14 56 57 BE 10 20 40 00 8D 7D EC  U.ì.ì.VW¾. @..}ì
      00401010: A5 A5 6A 00 8D 45 FC A5 50 8D 45 EC 50 A4 FF 15  ¥¥j..Eü¥P.EìP¤ÿ.
      00401020: 04 20 40 00 50 8D 45 EC 50 6A F5 FF 15 00 20 40  . @.P.EìPjõÿ.. @
      00401030: 00 50 FF 15 08 20 40 00 5F 5E C9 C3              .Pÿ.. @._^ÉÃ
    
    SECTION HEADER #2
      .rdata name
          92 virtual size
        2000 virtual address (00402000 to 00402091)
         200 size of raw data
         600 file pointer to raw data (00000600 to 000007FF)
           0 file pointer to relocation table
           0 file pointer to line numbers
           0 number of relocations
           0 number of line numbers
    40000040 flags
             Initialized Data
             Read Only
    
    RAW DATA #2
      00402000: 68 20 00 00 78 20 00 00 58 20 00 00 00 00 00 00  h ..x ..X ......
      00402010: 48 65 6C 6C 6F 20 77 6F 72 6C 64 0A 00 00 00 00  Hello world.....
      00402020: 48 20 00 00 00 00 00 00 00 00 00 00 84 20 00 00  H ........... ..
      00402030: 00 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00  . ..............
      00402040: 00 00 00 00 00 00 00 00 68 20 00 00 78 20 00 00  ........h ..x ..
      00402050: 58 20 00 00 00 00 00 00 99 03 57 72 69 74 65 43  X ........WriteC
      00402060: 6F 6E 73 6F 6C 65 41 00 B9 01 47 65 74 53 74 64  onsoleA.¹.GetStd
      00402070: 48 61 6E 64 6C 65 00 00 CC 03 6C 73 74 72 6C 65  Handle..Ì.lstrle
      00402080: 6E 41 00 00 4B 45 52 4E 45 4C 33 32 2E 64 6C 6C  nA..KERNEL32.dll
      00402090: 00 00                                            ..
    
      Section contains the following imports:
    
        KERNEL32.dll
                    402000 Import Address Table
                    402048 Import Name Table
                         0 time date stamp
                         0 Index of first forwarder reference
    
                      1B9 GetStdHandle
                      3CC lstrlenA
                      399 WriteConsoleA
    
      Summary
    
            1000 .rdata
            1000 .text
    

Anmelden zum Antworten