wanderson

I am attempting to modify my Entropy library to allow the user to decide if they want to include floating point functions for the library. I placed conditional defines around the relavent code; however, it wouldn't link. I determined that the source level #define was not being passed to the libraries cpp compile, though it was passed to the libraries header file.

My current solution is to require the user to comment/uncomment the header file for the library, but this is cumbersome, and problematic. It would be nice if the compilation for library code included the defines made by the Arduino sketch.

Libraries are not slaves to the user of the library.The library code is compiled separately and the behavior you are seeing isthe expected behavior. This is how libraries work.i.e. a library is a separate compilable module that must be capable of being compiledseparately, in advance, and without any knowledge of any code that uses the library.In most build environments, libraries are compiled up front, saved away, and then used (linked against)as needed. Since multiple users of the library might want to set library compile defines separately/differentlythere would be no way to build the library object without seeing the user code that used it.The Arduino build methodology is not all that smart and does not save things like the compiled librariesfor re-use across different sketches. However, in the Arduno environment, even though the librariesare not being saved for other sketches to use, the libraries are still actual libraries andsince a library is a separate entity from the code that uses it, there is no way to do what you are wanting.

There are some ways to kind of do what you are wanting to do.

You could play some games with the pre-processor to rename the names of thefunctions that the user code ends up calling.

That way you could have two sets of functions in the actual library,one that uses floating point and the other that does not. To select which the user simply puts a #define above the inclusion of the library header.(The default might be floating point, then if the magic define is set it drops to integer only)

Then in the library header file, the header remaps all the function names based on some ifdef condition

At link time the appropriate function would be pulled in and you end up withthe version of the support you want/need.

Another similar alternative would be to still have the two sets of functionsbut then have an inline wrapper function that simple calls the integer or floatingpoint version. The inline wrapper function would be in a header file that the userssketch code includes. That way, conditionals could change it appropriately.The library would still have to have both sets functions but only the onesactually referenced would be linked in.

I do some similar things in my openGLCD library to map some older functionsto the newer functions. In my case, I even manipulate the parameters beingpassed to the functions.The user sketch code doesn't change, all the magic is done by the mapping macros.Another alternative that would work but some might call "ugly" would be to put allthe code in the header file.The code is no longer a library at that point but you could then do whatever youwanted and any conditionals you put in the user code prior to including the headerfile would work as you are wanting.

wanderson

Libraries are not slaves to the user of the library.The library code is compiled separately and the behavior you are seeing isthe expected behavior. This is how libraries work.

Yes, and if the Arduino environment was actually using libraries I would understand that I would have to use a different method to get around the problem, for instance letting a define specify which vesion of the library to link into the code; however, as you point out below, the Arduino libaries are not really libraries, but module of code that get included in the compile process.

The Arduino build methodology is not all that smart and does not save things like the compiled librariesfor re-use across different sketches. However, in the Arduno environment, even though the librariesare not being saved for other sketches to use, the libraries are still actual libraries andsince a library is a separate entity from the code that uses it, there is no way to do what you are wanting.

wanderson

the simplest solution I can think of is to provide two libraries but that is a burden for the developer.

Another way is to use a templates. A very short intro see - http://www.cplusplus.com/doc/tutorial/templates/ - at the end of the pageor- http://www.tutorialspoint.com/cplusplus/cpp_templates.htm -

Thanks for the references! My c++ experience predates the inclusion of templates in the language, and I have never had a need for that feature before. I will look at the references provided and see about incorporating that solution into the library.

This way, the library is compiled with full functionality, and the sketch will only see the float functions if they explicity add #define ENTROPY_FLOAT. The compiler should be able to remove the unused pieces.

If you want to prevent compiling of the float features altogether, that can still be achieved.

Forum Mod anyone?https://arduino.land/Moduino/

wanderson

Yeh, this library works even on some of the small tiny avr's (2313), but only if none of the code for floating point is included since that brings in additional 'library' code that really bulks up an application. However, for some applications, and on the appropriate chips, floating point random numbers can be very useful, so I want to include the capability in the library, but only if the user needs it.

After reading the references on template specialization, that seems like a likely solution, though I will also try pyro_65's solution as well. Ultimately, I want the library to be useable outside of the Arduino environment as well, since I occasionally use straight c/c++ as well.

Libraries are not slaves to the user of the library.The library code is compiled separately and the behavior you are seeing isthe expected behavior. This is how libraries work.

Yes, and if the Arduino environment was actually using libraries I would understand that I would have to use a different method to get around the problem, for instance letting a define specify which vesion of the library to link into the code; however, as you point out below, the Arduino libaries are not really libraries, but module of code that get included in the compile process.

All the other Arduino libraries like your Entropy library are still being treated like a library by the IDE.The IDE doesn't create a library .a archive file for it but otherwise the library is being handledvery similar to a "normal" library.The files in the library are each compiled separately from the users code (sketch files) and then then the library objects are linked in with the users code.(The library files are not included or merged into the same compilation unit as the users sketch)The only difference between "real" libraries and what the IDE is doingis that with the exception of the Arduino core library, the compiled objects in the other librariesare not archived into a .a archive file before they are linked in.

wanderson,In the bigger picture, without seeing your new code or understanding on how youare changing the API, it really isn't possible to make anyrecommendations since it can depend on how you are implementing things.

For example, if the function names for obtaining floating point random numbersvs integer random numbers is different or are overloaded functions, then there is nothing that you will need to do.The IDE sets the gcc compiler and linker options to remove functions that are not called.So while the Entropy library object will have the compiled code for the functions for both integerand floating point functions as well as all the s/w floating point routines in it,only the functions used will actually be linked in.i.e. if you don't call the floating point functions, they will not be linked inand all the floating point s/w support will also be yanked out.

git has great support for branches. Perhaps you could push your latest updatesinto a branch so we could take a look at it?

--- bill

wanderson

All the other Arduino libraries like your Entropy library are still being treated like a library by the IDE.The IDE doesn't create a library .a archive file for it but otherwise the library is being handledvery similar to a "normal" library.The files in the library are each compiled separately from the users code (sketch files) and then then the library objects are linked in with the users code.(The library files are not included or merged into the same compilation unit as the users sketch)The only difference between "real" libraries and what the IDE is doingis that with the exception of the Arduino core library, the compiled objects in the other librariesare not archived into a .a archive file before they are linked in.

--- bill

It doesn't appear to me that the Arduino IDE is treating them as libraries, but rather as additional source files included in a make like environment. In that environment I would feed defines to my make file to control the compilation of the executable. That is what I am looking for here; however, I think the template specialization may make a cleaner solution, or perhaps I can simply rely on the linker to not include any methods which aren't used as you described above; however, that behavior wasn't what I thought occurred. I thought if you used some of a classes code, then all of it were included.

Yeh, this library works even on some of the small tiny avr's (2313), but only if none of the code for floating point is included since that brings in additional 'library' code that really bulks up an application. However, for some applications, and on the appropriate chips, floating point random numbers can be very useful, so I want to include the capability in the library, but only if the user needs it...

I thought if you used some of a classes code, then all of it were included.

No overhead for unused data. To achieve what you want, no mods are needed.

The defines I provided hide them from the user. I use templates frequently, however they are overkill for this. The floating point data is compiled, but not linked in unless you use it. Which means there is no additional code impact if the user decides not to use it.

No overhead for unused data. To achieve what you want, no mods are needed.

Same is true for code.

The gcc tools have gotten a lot more sophisticated/smarter in the past few years.There are new options that put every single function and data element into its own sectionand if there is no referenced to that section, the linker tosses it out.It requires cooperation between the compiler and linker but the IDE turns on theoptions to enable it.make can do anything, since it just a dependency rule based system to run commands.Most of the makefiles that I create for doing builds/compiles use real libraries and create archive files and even peek into the archive files for dependencies.I only wish the IDE was using meak underneath the covers vs trying to create their own setof rules.Much of the Arduino build nonsense that the IDE is doing and has been doing over the years would have been avoided.

As far as the libraries being real "libaries". The IDE is treating them similar to real libraries.The distinction being that they are compiled separately vs being combined with users source when compiled.The only thing not being done by the IDE is to combine the library objects into .a archive file.The IDE does create a library archive file by combining all the core objects into a .a archive, so for sure the Arduino core library is a true archive library.

In the early days, the IDE was combining everything into one mega gigantic file and then compiling it.For many unsophisticated users, that probably would work better and even allow certain kindsof optimizations that cannot be done when things are separate modules and compiled separately.

Maybe what was throwing me is this:

Quote

the Arduino libaries are not really libraries, but module of code that get included in the compile process.

as it was ambiguous to me.I had assumed that you meant that the library source was getting included in the users sketch codeas part of the compile process where both were compiled together.While that used to happen long ago, the current IDE process treats the libraries as libraries and compilesthe library modules separately. The only thing the IDE doesn't do right now is build a library archive .a filefor the libraries. (well it does for the core library).