Page 1 of 1
Any way to strip C/C++ locale stuff out of the binary?
Posted: Fri Jul 06, 2018 11:05 pm
by jens.alfke
When I run "make size-files" (with CONFIG_OPTIMIZATION_LEVEL_RELEASE) I see that a lot of the top contributors to the binary size are related to C/C++ locale handling:
Code: Select all
Per-file contributions to ELF file:
Object File DRAM .data & .bss IRAM Flash code & rodata Total
...
locale-inst.o 0 144 0 25655 7235 33034
wlocale-inst.o 0 144 0 25462 7395 33001
...
cxx11-wlocale-inst.o 0 96 0 10420 4731 15247
cxx11-locale-inst.o 0 96 0 10376 4667 15139
Just the above four files contribute nearly 100KB!
I'm not doing anything related to locales, so I assume this code is transitively included by functions like "sprintf" and classes like "std::ostream". Is there any way to get rid of this locale overhead?
Re: Any way to strip C/C++ locale stuff out of the binary?
Posted: Sat Jul 07, 2018 12:38 am
by kolban
It is my understanding that code that is not references is stripped at link time through the use of the linker flag `--gc-sections` which is explicitly already part of the linkage. What that means is that if object files remain in the resulting binary, at least one function or symbol is referenced from that file by something else in the linkage chain. If you really want to remove these files, we'll have to walk through the usage graphs and arrange for them to not be referenced which may not be possible.
While 100K seems like a lot, it is only 2.5% of the 4MByte of flash available. If I may ask, what is the thinking behind reducing the size of the binary to the smallest possible?
Re: Any way to strip C/C++ locale stuff out of the binary?
Posted: Sat Jul 07, 2018 1:11 am
by WiFive
@kolban we still haven't gotten through to you on importance of memory optimization on embedded platforms?
Re: Any way to strip C/C++ locale stuff out of the binary?
Posted: Sat Jul 07, 2018 2:37 pm
by kolban
I'm always super keen to learn from the wealth of knowledge of others. In my travels, I haven't come close to seeing applications that are squeezed on flash memory. As I try and think it through, there would appear to be two dimensions on the reduction of flash utilization.
1. We are running low on flash and can't fit our applications (code and data) in the 4MB available or the 2MB OTA partition (assuming 2).
2. We are going to be relatively frequently be bringing in new versions of our application over the network and to give the users the best possible experience and reliability, we want to reduce the time for network transmission to the lowest possible which would mean transmitting smaller size images.
Are there other considerations beyond these? What prompted me to ask the original poster was an attempt to determine which (maybe neither, maybe both) of the above was in poster's mind. When I see a good technical question like this one, what I want to do is try and learn more by seeing what is behind the question so that I can put it in perspective.
I'm also very interested in your own thinking on this topic. You are most definitely one of the luminaries on this forum with an extensive wealth of knowledge. Are the two bullet items listed above your own belief on the reasons for shrinking flash usage? Are there others?
Re: Any way to strip C/C++ locale stuff out of the binary?
Posted: Thu Jul 12, 2018 12:00 pm
by jamesparker2000
Hey guys,
I have been working on an embedded C++ project recently on another platform - still GCC but on ARM. However, I hope I can share some wisdom on the subject as we had exactly the same problems.
We found std::locale and std::money type stuff in our linked binary - yet we could not work out what was causing this to be included.
Now, use of std::ostream or std::istream may have something to do with it - and you can accidentally use these without knowing - but this was not our issue.
Use of standard C library does not include these so don't worry about them.
We had been using the boost C++ library for the "boost::optional" (we are using C++11 so not in standard yet!). Although this was fine, it turned out that someone had made use of another part of boost - boost::trim() - which strips white space characters of the start and end of a string.
boost::trim was using locale information to understand what a "white space" character was in our locale.
By removing a single use of boost:trim() we saved nearly 20% of our firmware size.
"How did we find out it was boost trim?" I hear you ask....
The technique I employed was simply to ensure I had an IDE with source code indexing correctly configured so that I could see the reference trees. You can do this in Visual Studio (see: View Call Hierarchy) but I was using Eclipse (see: Open Call Hierarchy). Find the name of the symbol that you are struggling to get rid of and then use a call hierarchy on that symbol - i.e. "What functions reference this symbol?" You *must* ensure that your source indexing includes everything that goes into your project including the toolchain include folders.
When I did that I could see what was referencing std::locale and could then remove the offending code.
Hope that helps!
Re: Any way to strip C/C++ locale stuff out of the binary?
Posted: Fri Mar 25, 2022 7:56 am
by mark.jeronimus
- "Find the name of the symbol that you are struggling to get rid"
How do I find such symbol name? I only know the locale object files that I'm trying to get rid of. I naively looked in the IDF for files with 'locale' in the name and came up blank. Turns out they are part of the cpp library. When I searched around, everyone having this issue seemed to use stringstream, but I don't.