Unnecessary stuff from library linked in

Working libraries, libraries being ported and related hardware
arpruss
Posts: 153
Joined: Sat Sep 30, 2017 3:34 am

Unnecessary stuff from library linked in

Post by arpruss » Sun Feb 04, 2018 3:05 pm

If I include a single header file from a library, as far as I can tell all the code and data from the library gets linked in, even stuff that's completely irrelevant.

For instance:

Code: Select all

#include "usb_generic.h"
void setup() {}
void loop() {}
will link in everything from my USBHID library, even stuff I have no need for. This means not only that code space is taken up with unnecessary code, but more importantly that RAM is taken up with unnecessary global/static variables.

This happens on both Fastest and Smallest optimizations. It even happens on Smallest+LTO.

How do I fix this? Is there something I can do on the library side to prevent it? Or is there something wrong with the compiler options?

I am attaching the map file from the elf file.
Attachments
map.txt
(26.51 KiB) Downloaded 4 times

arpruss
Posts: 153
Joined: Sat Sep 30, 2017 3:34 am

Re: Unnecessary stuff from library linked in

Post by arpruss » Sun Feb 04, 2018 4:19 pm

OK, I figured out what is happening. When a library defines an instance of a class, the constructor code for the instance is linked in, even if that instance is never referenced by anything else, and this constructor code can pull a bunch of other stuff in. My USBHID library defines a lot of convenience instances (e.g., Keyboard, CompositeSerial, etc.). I am not sure what the best way around this is.

victor_pv
Posts: 1864
Joined: Mon Apr 27, 2015 12:12 pm

Re: Unnecessary stuff from library linked in

Post by victor_pv » Sun Feb 04, 2018 4:28 pm

Perhaps leave the instances out of the class files, so the user defines in the sketch if they are going to be used?

arpruss
Posts: 153
Joined: Sat Sep 30, 2017 3:34 am

Re: Unnecessary stuff from library linked in

Post by arpruss » Sun Feb 04, 2018 4:33 pm

victor_pv wrote:
Sun Feb 04, 2018 4:28 pm
Perhaps leave the instances out of the class files, so the user defines in the sketch if they are going to be used?
That would work, but I want to make this as friendly as possible to the user, and to mimic how the core works. The core defines lots of such convenience instances like Serial, Serial1, etc.

User avatar
mrburnette
Posts: 2201
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Unnecessary stuff from library linked in

Post by mrburnette » Sun Feb 04, 2018 4:36 pm

The answer you will not like, use only C for everything.
arpruss wrote:
Sun Feb 04, 2018 4:33 pm
That would work, but I want to make this as friendly as possible to the user, and to mimic how the core works. The core defines lots of such convenience instances like Serial, Serial1, etc.
I suspect ease-of-use for end-users of Arduino was why C++ was elected for Arduino, but they still argue about it over on Arduino.cc

If you go searching around the Internet, avoid anything that was pre-Arduino 1.5.8 because the 1.5.8 version fundamentally changed much of the back-end methodology. https://www.arduino.cc/en/Main/OldSoftw ... ases#1.5.x October 2014

But, it is not a STM32 issue, even the Teensy dudes/dudettes have issues.

Ray

stevestrong
Posts: 2059
Joined: Mon Oct 19, 2015 12:06 am
Location: Munich, Germany
Contact:

Re: Unnecessary stuff from library linked in

Post by stevestrong » Sun Feb 04, 2018 5:35 pm

You may try to edit the platform.txt by adding the "-specs" compiler directives:

Code: Select all

compiler.c.elf.extra_flags="-L{build.variant.path}/ld" -specs=nosys.specs -specs=nano.specs 
I use it in my repo, it reduces considerably the code size with no side issues so far.

arpruss
Posts: 153
Joined: Sat Sep 30, 2017 3:34 am

Re: Unnecessary stuff from library linked in

Post by arpruss » Sun Feb 04, 2018 5:46 pm

stevestrong wrote:
Sun Feb 04, 2018 5:35 pm
You may try to edit the platform.txt by adding the "-specs" compiler directives:
Yeah, that does reduce size.

I still would like to solve the library class instance linking issue. It would be nice if there were some way to define an instance of a class that would only get linked in if the class is referenced. But C++ standards presumably require that if the instance is created, then its constructor is called, and hence at least the constructor needs to get linked in. And then any virtual functions also need to be linked in along with constructor.

Is there a way to split an Arduino library, so depending on which header files you include, only a part of the library gets included?

User avatar
mrburnette
Posts: 2201
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Unnecessary stuff from library linked in

Post by mrburnette » Mon Feb 05, 2018 4:19 am

arpruss wrote:
Sun Feb 04, 2018 5:46 pm
...
Is there a way to split an Arduino library, so depending on which header files you include, only a part of the library gets included?
You can put any library into you local sketch folder .... .h and .cpp files become tabs. You reference them in #include "./file.xxx" rather than using the braces <...>

Depending on how you do things, the Arduino auto-prototyping may fail, you may need to do a forward declaration.

Ray

arpruss
Posts: 153
Joined: Sat Sep 30, 2017 3:34 am

Re: Unnecessary stuff from library linked in

Post by arpruss » Mon Feb 05, 2018 4:38 am

It seems that the issue was that the constructor for a class that contains virtual function forces the virtual functions to be linked in even if they are never called by the code. Since the classes that I had convenience instances for had virtual functions, that meant that a lot of unnecessary code was getting linked. I ended up rewriting without virtual functions, and a lot of RAM and flash has been saved.

User avatar
mrburnette
Posts: 2201
Joined: Mon Apr 27, 2015 12:50 pm
Location: Greater Atlanta
Contact:

Re: Unnecessary stuff from library linked in

Post by mrburnette » Mon Feb 05, 2018 1:37 pm

stevestrong wrote:
Sun Feb 04, 2018 5:35 pm
...
I use it in my repo, it reduces considerably the code size with no side issues so far.
NOOB warning:
The GCC compiler and associated software tools are remarkably complex... which is why ArduinoIDE keeps this mess hidden from the average user. Please understand, if you deviate from the defaults, you are (in my opinion) on your own for support. For those inquisitive, a list of options is available here: https://gcc.gnu.org/onlinedocs/gcc/Option-Index.html


Ray

Post Reply