stevemarple / IniFile

Arduino library to parse ini files.
GNU Lesser General Public License v2.1
87 stars 45 forks source link

Not working when using SdFat instead of SD library #38

Open rmicmir opened 1 year ago

rmicmir commented 1 year ago

Hi!

Thanks for your work on this library!

I've been trying to use IniFile compining against SdFat instead the defaukt SD library. I've used the examples included in IniFile witout success.

`#include

include

include

include

// The select pin used for the SD card [...]`

include

include

include

include

// The select pin used for the SD card [...]`

Error:

tmp/arduino/sketches/BB2A6256ECD89697A9217989C990A171/sketch/IniBrowseExample.ino.cpp.o: In functionIniFile::open()': /home/user/Arduino/libraries/IniFile/src/IniFile.h:161: undefined reference to SD' /tmp/arduino/sketches/BB2A6256ECD89697A9217989C990A171/sketch/IniBrowseExample.ino.cpp.o: In functionsetup': /tmp/.arduinoIDE-unsaved202339-2452-1rlkvoh.nh7h/IniBrowseExample/IniBrowseExample.ino:72: undefined reference to IniFile::IniFile(char const*, int, bool)' /tmp/.arduinoIDE-unsaved202339-2452-1rlkvoh.nh7h/IniBrowseExample/IniBrowseExample.ino:126: undefined reference toSD' /tmp/.arduinoIDE-unsaved202339-2452-1rlkvoh.nh7h/IniBrowseExample/IniBrowseExample.ino:126: undefined reference to `SD' collect2: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1`

`#define PREFER_SDFAT_LIBRARY 1

include

SdFat SD;

include

include

include

// The select pin used for the SD card [...]`

Error:

/tmp/arduino/sketches/BB2A6256ECD89697A9217989C990A171/sketch/IniBrowseExample.ino.cpp.o: In functionsetup': /tmp/.arduinoIDE-unsaved202339-2452-1rlkvoh.nh7h/IniBrowseExample/IniBrowseExample.ino:73: undefined reference to `IniFile::IniFile(char const*, int, bool)' collect2: error: ld returned 1 exit status

exit status 1

Compilation error: exit status 1`

Is there any way to solve this? If I can help any way please let me know.

Thanks!

stevemarple commented 1 year ago

I've not used the SdFat library - the changes to support it have been contributed from users. I cannot confirm that the examples will work with it (I hope they do but I have never tried them that way). You'll need to make sure that the SdFat SD object is defined somewhere, since IniFile.h expects it to exist (from IniFile.cpp line 8: extern SdFat SD;). This is the cause of the undefined reference to SD error you report.

If you define #define PREFER_SDFAT_LIBRARY 1 when including IniFile.h in your example or main .ino file you had better make sure that macro is in effect when compiling IniFile.cpp. For now that is probably best achieved by editing IniFile.h so the macro is defined everywhere it is needed. If you don't have this right then the IniFile constructor parameter types will be wrong, as evidenced by the undefined reference toIniFile::IniFile(char const*, int, bool)` error message you report.

A real IDE will allow you to define a macro globally that is applied for all compilation units. For some stupid ideological reasons the Arduino developers think this is not necessary. I've lost count of the number of times these type of problems have arisen because of this. I even submitted a PR (https://github.com/arduino/arduino-builder/pull/29) to fix it but it has not been accepted.

rmicmir commented 1 year ago

Hi

Thanks for your answer. I'm not an experienced developer and I don't fully understand your proposal. I cannot understand how editting the IniFile.h and including the PREFER_SDFAT_LIBRARY macro there this would be solved.

As far as I can understand the code, the SD and SdFat classes should be managed the same by IniFile. The PREFER_SDFAT_LIBRARY only affects which one is loaded, but the IniFile constructor is not affected by the macro, right?

Just to make you aware, my interest in using SdFat instead of SD is because I've read that SdFat makes a better energy management of the SD hardware, and I'm trying to minimize power consumption on a project.

Thanks again

stevemarple commented 1 year ago

I cannot understand how editting the IniFile.h and including the PREFER_SDFAT_LIBRARY macro there this would be solved.

You define PREFER_SDFAT_LIBRARY before including IniFile.h, which affects the mode_t typedef, which in turn affects the IniFile constructor parameter types but only when compiling the .ino file. IniFile.cpp is a separate compilation unit, and it isn't affected by your PREFER_SDFAT_LIBRARY #define. The linkage error arises because the two compilation units (your arduino .ino file, and IniFile.cpp) are out of sync. Put them in sync by having PREFER_SDFAT_LIBRARY defined for both; this is simplest by adding the macro to line 5 of IniFile.h.

rmicmir commented 1 year ago

Hi!

You are a genius :)

I've finally got it working after following your instructions but I had some problems I would like to share with you: your solution works only if "IniFile.h" and "IniFile.cpp" are on the same directory as my .ino files. I've also tried to create a subfolder "Lib" in my project, just to keep things in order, and I've placed the .h and .cpp files there properly referenced from my .ino file and that keeps yelling the same error.

Is that "subfolder inclusion" not working for any other reason? Can you explain me why? I think I would learn something else from you :)

Thanks!