Sloeber / arduino-eclipse-plugin

A plugin to make programming the arduino in eclipse easy
https://eclipse.baeyens.it/
416 stars 131 forks source link

optional Library option dot_a_linkage not taken into account #1126

Open JAndrassy opened 4 years ago

JAndrassy commented 4 years ago

The build invokes linker with the .o from from libraries. This creates a different build result then invoking the linker with .a or .ar files for libraries, because files listed on linker command line are 'starting points' of compilation while objects from archives are added only if they are required by .o files from linker command line.

To reproduce, build for AVR the ImprovedKeyboard example of HID-Project library with Arduino IDE and with Sloeber. Then compare the size. Generate a .map file and you will see that the elf file created by Sloeber includes classes for all HID devices of the library while the elf file build by ArduinoIDE only contains the ImprovedKeyboard. (Additional problem is that in the sketch built by Sloeber all singeltons for HID devices are present and register themselves as USB endpoints, but there is space only for 3 endpoints. https://github.com/NicoHood/HID/issues/199)

The build process should create archives (.a or .ar) for libraries and then add this archives on linker command line instead of listing the .o files.

To fix this, the makefile generation must be enhanced. I have Sloeber running from source code for debugging. I see that the makefile system is adaptation of the CDT makefile system, but before going deeper I thought I open an issue to discuss this.

jantje commented 4 years ago

I'm impressed with your research :-) This is a tricky one though. Yes the makefile generator is a adaptation from the CDT one (which is both experimental and about to get deprecated :-s ).

But the makefile generator processes according to the extentionpoint org.eclipse.cdt.managedbuilder.core.buildDefinitions

In that extentionpoint you will see that there is a definition for archived links AR_OBJ inputs that states the output is .o (for C C++ and assembly) https://github.com/Sloeber/arduino-eclipse-plugin/blob/master/io.sloeber.core/plugin.xml#L214

The same AR_OBJ is then available for input and again tagged as .o files. https://github.com/Sloeber/arduino-eclipse-plugin/blob/master/io.sloeber.core/plugin.xml#L339

It could be that simply changing the o to a or ar in the input type definition solves your issue.

But it will do so for all cases so that would need extensive testing. For which there is a junit test :-)

jantje commented 4 years ago

Och I think I misunderstood. You are talking about libraries, not the arduino platform stuff. Here you will need to mod the name providers The name providers of the output type act like filters (this is one of the mods I did to the CDT gnu make file generator) By having 2 output types for the same input type sloeber triages the files to the archiver or the linker. So the LinkNameProvider and the ArchiveNameProvider must be mutually exclusive. At this point in time ArchiveNameProvider returns null for library related files and LinkNameProvider returns valid names. Switching that should do the trick.

https://github.com/Sloeber/arduino-eclipse-plugin/blob/master/io.sloeber.core/src/io/sloeber/core/toolchain/LinkNameProvider.java#L29 https://github.com/Sloeber/arduino-eclipse-plugin/blob/master/io.sloeber.core/src/io/sloeber/core/toolchain/ArchiveNameProvider.java#L30

JAndrassy commented 4 years ago

thank you Jantje. we are on the right path. I added

 } else if (primaryInputNames[curPath].toString().startsWith("libraries") && (bUseArchiver)) {
  outputNames[curPath] = Helpers.GetOutputName(primaryInputNames[curPath]).addFileExtension("o"); //$NON-NLS-1$

in ArchieveNameProvider and the same if condition with return null in LinkNameProvider.

the build is a success, but all .o files from libraries are in arduino.ar. it would be nicer if every library had own .ar

JAndrassy commented 4 years ago

even the Arduino builder doesn't build .ar for libraries at default. it is an option in library.properties which the library author can set

from https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification

dot_a_linkage - (available from Arduino IDE 1.6.0 / arduino-builder 1.0.0-beta13) (optional) when set to true, the library will be compiled using a .a (archive) file. First, all source files are compiled into .o files as normal. Then instead of including all .o files in the linker command directly, all .o files are saved into a .a file, which is then included in the linker command. 1.5 format library folder structure is required.

jantje commented 4 years ago

it would be nicer if every library had own .ar With the current approach I wouldn't know how to get there

JAndrassy commented 4 years ago

after I found out about dot_a_linkage setting in library.properties I would see as a priority to link with this libraries over .ar, no matter if it is all done over the arduino.ar

jantje commented 4 years ago

That would be very similar to what is there already. Currently the flag bUseArchiver means "Is the arduino code compiled as a archive or not" (Some platforms had to be build without the archiving step) The biggest problem to face is: get the value of the flag. Not a huge problem so this should be relatively easy.