I am new to gcc - and working on a mingw installation with gcc version
4.4.0.
When using the command-line
\mingw\bin\g++ -Wall -std=gnu++0x -O3 -o test \cpp_test\test.cpp
for compiling the following little test program, I get an enormous
executable: test.c has two executable lines but the binary test.exe
has more than 3 Megabytes!!!
And the file test.exe is not even self-contained: When starting, it
requires the DLL libgcc_s_dw2-1.dll. I can only use the executable by
adding the mingw\bin path to the PATH variable. This is not what I
would expect!
How can I use g++ to generate an executable which is
a) self-contained (I don't want the users having to install a ton of
extra DLL's, it's enough that I have them on my machine!) and
b) of reasonable size (i.e.: simple tasks generate a simple-size
binary. When I start test.exe, only a handful of bytes will actually
be processed by the CPU. The executable should consist of precisely
these bytes) ?
Thanks and regards,
Rüdiger
//-------------------------------------------------------------------------------
#include <iostream>
#include <unordered_map>
using namespace std;
typedef unordered_map<int,double> umap;
int main()
{
umap m;
m[5] = 17;
cout << m[5];
}
//-------------------------------------------------------------------------------
You are sure the .exe _only_ needs libgcc?
Did you already tried to strip your program?
Is it better with _less_ optimization? (Say -O1 instead of -O3)
I guess your excutable includes the complete GCC libstc++, the C++ standard
library, statically linked in. And this monster is big to fullfill all the C++
stuff. It's 2.2MB on my Linux machine.
To my knowledge, the reason is that gcc is not compatible with VC with respect
to C++ (Name mangeling, exection handling, and so on). GCC can use the MS
standard C lib (the C part in the msvcrNN.dll), but not the VC C++ standard lib.
VC compiled C++ programms normaly have to install the "Visual Studio C++ Runtime
redistributable". But most programs silently expect the .dll already to be
installed in the Windows dir, by some other (MS) program.
Maybe the linker can help you, but i don't know how. Note that the linker is not
part of GCC, but binutils. You can pass options through GCC to the linker with
"-Wl,--option", see the GCC handbook.
Maybe you want to have a look at:
<http://www.mingw.org/wiki/Large_executables>
> How can I use g++ to generate an executable which is
>
> a) self-contained (I don't want the users having to install a ton of
> extra DLL's, it's enough that I have them on my machine!) and
>
static linking.
But since Windows first searches the path direct to the executable, you only
need to lay the needed .dll into the same directory as the executable.
> b) of reasonable size (i.e.: simple tasks generate a simple-size
> binary. When I start test.exe, only a handful of bytes will actually
> be processed by the CPU. The executable should consist of precisely
> these bytes) ?
>
Wrong language, say no to C++ bloat.
> Thanks and regards,
> Rüdiger
>
It's funny, i cross compiled several simple programs written in C by mingw, They
where not fancy, but fullfilled a real purpose, way above a hello world. I never
needed a extra .dll (libgcc, mingw, anything) to run them on Windows.
Bottom line: do not use C++
Greetings
Jan
[snip]
--
Shift happens.
-- Doppler
thanks for your reply.
> Did you already tried to strip your program?
Good suggestion, thank you. Adding option -s to the options, reduced
the size from 3MB to 400KB:
\mingw\bin\g++ -Wall -std=gnu++0x -O3 -s -o test \cpp_test\test.cpp
Changing the optimizing level from O3 to O1, had almost no effect. I
assume that there would be an effect for programs having more than two
executable statements...
> [Dependency on dynamic linking to gcc]
The DLL missing was libgcc_s_dw2-1.dll. After some googling, I found
the following quote of the gcc 4.4.0 release notes:
[Quote]
- Dynamic linking with libgcc_s_dw2-1.dll
Dynamic linking with libgcc_s_dw2-1.dll is necessary to throw
exceptions between different modules, such as between two DLLs or a
DLL and an EXE. Consequently, it is the default for all languages
other than C. To disable this dynamic linking, use -static-libgcc.
To enable this dynamic linking in C, use -shared-libgcc.
[/Quote]
My problem was solved with the following command line:
\mingw\bin\g++ -Wall -std=gnu++0x -O3 -s -static-libgcc -o test
\cpp_test\test.cpp
Now the test.exe doesn't rely on the DLL any more, but of course the
binary size increased by 87 KB (which is still moderate compared to
the 3MB I started with).
> Maybe you want to have a look at:
> <http://www.mingw.org/wiki/Large_executables>
Good link, thank you.
> Wrong language, say no to C++ bloat.
In my current project "AstroPatterns" (http://
astropatterns.sourceforge.net/), I would be happy to take advantage of
polymorphism and inheritance.
For this reason, I decided to use C++.
In other circumstances, however, I have made some promising
experiments with Fabrice Bellard's Tiny C Compiler (http://bellard.org/
tcc/). These guys are definitely aware of things like binary size...
Another reason for choosing particularly "-std=gnu++0x" - I wanted to
experiment a bit with the new built-in features like hash tables and
regular expression. But it is possible to use good substitutes when
working with pure C: The PCRE (http://www.pcre.org/pcre.txt) does a
good job for regular expression, and I remember vaguely that in the
Windows kernel somewhere is an object like "Dictionary" which can be
used for hashs.
Thank you for your help in this problem!
- Rüdiger
Ahh, good.
There should also be a stand alone strip.exe in your mingw-package. This way you
get an unstripped .exe for debugging and can strip it afterwards for release.
> Changing the optimizing level from O3 to O1, had almost no effect. I
> assume that there would be an effect for programs having more than two
> executable statements...
>
More than one statemant?
You are dealing with C++.
What do you think happens behind the scenes in so inocent looking lines like:
m[5] = 17;
with all the typedef-templete mabo-jumbo you dropped there?
My idea was that the compiler tried to resolv much of this (basically only doing
"print 17") at compile time but didn't suceeded at eleminating all of it.
So i concluded that this way suddenly much more of the libstd++ was needed than
either with no/low optimization or every thing successful constant folded.
[snip]
> In other circumstances, however, I have made some promising
> experiments with Fabrice Bellard's Tiny C Compiler (http://bellard.org/
> tcc/). These guys are definitely aware of things like binary size...
>
Hmmm, maybe i missed something, but was the purpose of tcc not to be the
smallest/fasted compiler? AFAIK there is no priority generating a good and/or
small executable (sacrificed for speed/size).
[snip]
> Thank you for your help in this problem!
> - Rüdiger
Greetings
Jan
--
"Remember: With great power comes great current squared times resistence."
Ohm never forgot his dying uncle's advice.
xkcd.com/643/
> > In other circumstances, however, I have made some promising
> > experiments with Fabrice Bellard's Tiny C Compiler (http://bellard.org/
> > tcc/). These guys are definitely aware of things like binary size...
> Hmmm, maybe i missed something, but was the purpose of tcc not to be the
> smallest/fasted compiler? AFAIK there is no priority generating a good and/or
> small executable (sacrificed for speed/size).
I don't know the goals of the tcc project in detail. But if they
really sacrifice size
for speed, then they are using this freedom it with extreme caution.
The obligate
"hello world" exe needs only 1536 Bytes (I mean Bytes, not K- or MB!).
And
in TCC this is not exceptional.
- Best regards,
Rüdiger
I like tcc, but this is a C compiler. You said g++, which is a C++
compiler.
Remember that a C program will be smaller than its C++ equivalent, because C
libraries do not carry the additional code to handle function overloading
that C++ libraries do.
So if you want small, write in C, rather than C++, and then you can use tcc.
Unfortunately some GNU programs are written in GNU C, which does not
compile on non-GNU compilers. I wish they would change the file
extensions so that we could differentiate between C code and GNU C code:
.c = traditional portable C
.c99 = revised ansi C
.cpp = C++ source code
.gcc = gcc source code
.gpp = g++ source code
http://markhobley.yi.org/standards/extensions.html
Mark.
--
Mark Hobley
Linux User: #370818 http://markhobley.yi.org/
thanks for your answer. I know about the difference between C and C++
code,
and for my current project I want to use C++, as I wrote:
>In my current project "AstroPatterns" (http://
>astropatterns.sourceforge.net/), I would be happy to take advantage of
>polymorphism and inheritance.
>
>For this reason, I decided to use C++.
The tcc note was only an addendum after Jan's advice to change the
language.
Thanks and Regards,
Rüdiger