Code bloat when linking against full PropWare library
DavidZemon
Posts: 2,973
If I link my basic "Hello, world!" program against the full PropWare library, I get massive code bloat (9k download). If I take only the necessary code from PropWare's cpp files and drop it in a file "extra.cpp" and then archive extra.cpp into libextra.a and link against that, it works perfectly (5k download).
How do I go about determining what extra code is getting linked into my executable?
Thanks,
David
How do I go about determining what extra code is getting linked into my executable?
Thanks,
David
Comments
I used ld's verbose option and found some differences between the compilations.
Here's a colorful screenshot of the diff
Here's the specific lines that only show up when I link against PropWare's full library:
When I disable floating point support during compilation of the library, it remains disabled when compiling my executable. This part is even more confusing to me. What am I missing here?
http://stackoverflow.com/questions/27221559/static-library-unused-symbols-definitions-in-header
Do you mean you'd like to use preprocessor defines in printer.h to control what's already been compiled into the PropWare library? That's not how things work. Once the code is compiled into a library, whatever options were in effect at that time are frozen into the object file. If floating point was enabled at library compilation time, then the floating point symbols are in the library (and will always be in the library, unless you recompile the entire library).
If you are, in fact, recompiling the library every time rather than linking against it, then using the preprocessor will work. But otherwise, you'll have to use the linker to control things, not the preprocessor. For example, you could have two versions of PropWare, one with floating point and one without, and then select at link time which one to use.
I tried playing with the prepocessor so that, when compiling the library, only method prototypes (and no prototypes using floats) are given. Unfortunately, that didn't work either. Dietmar from SO has suggested a new class structure that doesn't require any preprocessor magic though. I'm liking that a lot and will give it a try tonight (but it will ruin CLion's beautiful syntax highlighting and parameter inspections inside the format string )
Anyway, upon attempting to use templates, I'm getting a new error:
That seems so odd to me. I've switch to using g++. I tried removing the "-fno-rtti" flag.
This simple program functions correctly:
Any ideas?
Code:
https://gist.github.com/DavidZemon/f29e4a76093cc39ee4ef
Hopefully I can find the extern "C" culprit by the end of the day...
The files are long. If you want to take a look, I'd encourage the use of a diff tool.
I am open to any ideas out there!
Somehow the lines inserted by the preprocessor must implicitly be tracking whether a file was C or C++; possibly using the C++ form: automatically triggers C++ mode, versus using:
Is it possible that your original sources differed in how they did the includes?
(Looking at the gcc documentation, in the discussion of preprocessor output it does mention that the preprocessor has a flag, 4, which is put on # lines "to indicate that the following text should be wrapped in an implicit extern "C" block"). That flag is present on all the lines relating to printer.h in the failing example, but not in the example that works. So there's something different about how the #include of printer.h happened in those two examples.)
WOH! That's not something I was expecting.
I brought this on myself. I'd set the PropWare directory to be included via "-isystem". For whatever reason, that was setting the directory to C-only. According to this SO thread, it looks like the problem could also be resolved by patching PropGCC - but I've switched away from using "-isystem" in propware for the moment and that's fixed the problem!!! Finally! Now to see if all this trouble pays off in terms of code-size...
PropWare's sits at 5,908 kB.
vs. Simple's sits at 4,872 kB.
However, simplifying it by removing the variable parameters yields 4,124 kB for PropWare using printf, 3,736 kB using Simple's putStr, and 4,828 kB using Simple's printi. Pretty cool I think - especially when this same Printer class can be easily used for printing on LCDs, I2C implementations, or anything else that implements the put_char and puts methods