Is it possible to link Arduino (and other) libraries dynamically?

According to LGPL license, to avoid exposing the .o files of my source code, it is a must to link all LGPL (e.g. Arduino and arduinoWebSocket) dynamically rather than statically.

Checking the build folder under .pio shows that we have .a files (which are statically linked).

Is it somehow possible to build Arduino and other LGPL libraries and then link them dynamically in PlatoformIO for Arduino platform, ESP8266 hardware?

Dynamic linking requires a run-time linker and an operating system with a file system. Additionally, the executable code must be loaded into RAM so it can be changed at run-time. These features aren’t available on the Arduino platform, and they aren’t feasible due to the limited amount of RAM and flash.


Thank you Manuel, that makes sense. But why the code must be loaded into the RAM to be changed? why not only reading different parts of the flash (just like other typical flash code)?

If your code is dynamically linked to a library, the addresses of the functions and variables in the library are not known at compile time. Instead placeholders are created in the calling code. Once the library has been loaded and the addresses are known, the placeholders have to be filled with the effective address.

That’s the typical approach. There are other approach that limit the RAM requirement to a jump table but are less efficient at run-time.

1 Like

I am not a lawyer, as a pretext. But I do think the Arduino license text regarding the linking exception and this explanation and this is logical.

Q2a: What is the implication of static linking?
A2a: You need to comply with the license requirements. Eban Moglen in
Xfree86 Forum — Re: Mission statement and 1.1 license issues
indicates that you are producing a “derivative work” of the code in
the library. In the United States the US Copyright Office states at
A ?derivative work,? that is, a work that is based on (or derived
from) one or more already existing works … [copyright statements].
Both of those statements are pretty clear so section 6 of the LGPL
applies. Note that you can distribute (6a)
… [your work] as object code and/or source code, so that the user
can modify the Library and then relink to produce a modified
executable containing the modified Library
You can thus distribute object files (and protect your source code)
and still comply with the requirements of the LGPL.

Also per Frequently Asked Questions about the GNU Licenses - GNU Project - Free Software Foundation

For the purpose of complying with the LGPL (any extant version: v2, v2.1 or v3):

(1) If you statically link against an LGPLed library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.
(2) If you dynamically link against an LGPLed library already present on the user’s computer, you need not convey the library’s source […]

The .pio\build\<environment> folder contains the files which are used for the final linking. For example, a simple project for an Uno that only has src\main.cpp and is using the Arduino framework and no other sub-libraries will be linked as (see final lines of “Verbose Build” project task)

avr-g++ -o .pio\build\uno\firmware.elf -Os -mmcu=atmega328p -Wl,–gc-sections -flto -fuse-linker-plugin .pio\build\uno\src\main.cpp.o -L.pio\build\uno -Wl,–start-group .pio\build\uno\libFrameworkArduinoVariant.a .pio\build\uno\libFrameworkArduino.a -lm -Wl,–end-group

So you can see that the object file(s) of the firwmare (only src\main.cpp.o in this case) is staticaly linked with the previously compiled archive files libFrameworkArduino.a (the core) and libFrameworkArduinoVariant.a (code in the variant folder). So by providing the content of that folder users can also exchange the two latter files for a new variants and re-link the aplication with the command above (which is specific to this library).

1 Like

Thank you Max! I am not familiar with Linker command line, but could you tell me in few words what determines which parts of my firmware (main.cpp.o and other o files) are statically linked with the archive files?

Just for an example, let us say that my code uses arduinoWebSocket library, will this be statically linked only to the files in my project, whose headers use that arduinoWebSocket header?