SDFat linker errors after updating to latest Arduino and Teensyduino tools

Status
Not open for further replies.

royontog

Member
I updated to Arduino 1.8.13 and Teensy 1.53 from version that were a couple (or more?) years back. I installed the new Arduino IDE, installed new Teensy, downloaded Grieman's SDFat ZIP file and installed it. I am compiling for Teensy 3.5. I got build errors with that, searched and found that I need to use the Library Manager to install SDFat. Then I Include Library SD, SdFat, and Time. (Not sure SD is needed.) I now get a linker error in a large project that built and ran fine on the much older tools.
The main problem is in SDFat (Greiman). I am using the SdioEx interface for performance. I get an undefined reference when linking:
undefined reference to
`FatFile::eek:pen(FatFile*, char const*, unsigned char)'
when called from FatFile::exist()
At first I thought this was a parameter mismatch or open() was called before it was declared. I reversed the order of exists() and open() in FatFile.h, to no effect. I then created a compile error in the
FatFile::eek:pen(FatFile*, char const*, unsigned char)
form and got the exact same parameters listed in the error message, so a method of that form exists.
I then reinstalled everything (minus SD library) and still get the same errors.
Here is the entire build output. Please ignore the type punning warnings - that will be a question for another thread. Also, the SysCall.h duplicates seem to be benign:

Code:
ReadWrite.cpp: In function 'bool readAudioFile(const char*)':
ReadWrite.cpp:246: warning: dereferencing type-punned pointer will break strict-aliasing rules 
     n = *((uint32_t *) &sc1[16]);
                                ^
ReadWrite.cpp:253: warning: dereferencing type-punned pointer will break strict-aliasing rules 
     n = *((uint16_t *) &sc1[20]);
                                ^
ReadWrite.cpp:260: warning: dereferencing type-punned pointer will break strict-aliasing rules 
     n = *((uint16_t *) &sc1[22]);
                                ^
ReadWrite.cpp:268: warning: dereferencing type-punned pointer will break strict-aliasing rules 
     uint32_t audio_rate = *((uint32_t *) &sc1[24]);
                                                  ^
ReadWrite.cpp:274: warning: dereferencing type-punned pointer will break strict-aliasing rules 
     uint16_t audio_bps =  *((uint16_t *) &sc1[34]);
                                                  ^
ReadWrite.cpp:281: warning: dereferencing type-punned pointer will break strict-aliasing rules 
     uint32_t sc2_data_size = *((uint32_t *) &sc1[40]);
                                                     ^
C:\Users\ROYREI~1\AppData\Local\Temp\arduino_build_912404\sketch\ReadWrite.cpp.o: In function `FatFile::exists(char const*)':
C:\Users\ROYREI~1\Documents\Arduino\libraries\SdFat\src/FatLib/FatFile.h:341: undefined reference to `FatFile::open(FatFile*, char const*, unsigned char)'
C:\Users\ROYREI~1\Documents\Arduino\libraries\SdFat\src/FatLib/FatFile.h:341: undefined reference to `FatFile::open(FatFile*, char const*, unsigned char)'
C:\Users\ROYREI~1\AppData\Local\Temp\arduino_build_912404\sketch\ReadWrite.cpp.o: In function `FatFileSystem::open(char const*, unsigned char)':
C:\Users\ROYREI~1\Documents\Arduino\libraries\SdFat\src/FatLib/FatFileSystem.h:95: undefined reference to `FatFile::open(FatFile*, char const*, unsigned char)'
C:\Users\ROYREI~1\Documents\Arduino\libraries\SdFat\src/FatLib/FatFileSystem.h:95: undefined reference to `FatFile::open(FatFile*, char const*, unsigned char)'
C:\Users\ROYREI~1\Documents\Arduino\libraries\SdFat\src/FatLib/FatFileSystem.h:95: undefined reference to `FatFile::open(FatFile*, char const*, unsigned char)'
collect2.exe: error: ld returned 1 exit status
Multiple libraries were found for "SysCall.h"
 Used: C:\Users\ROYREI~1\Documents\Arduino\libraries\SdFat
 Not used: C:\Users\ROYREI~1\Documents\Arduino\libraries\arduino_655865
Error compiling for board Teensy 3.5.
I'm not using FatFileSystem.h, AFAIK, so I think this might be an IDE setup problem.
Also, the build is using the arm-none-eabi toolchain. Is that the right one?
 

Attachments

  • SdFatConfig.h
    8 KB · Views: 63
  • sound.h
    682 bytes · Views: 41
  • log.h
    589 bytes · Views: 44
  • sleepynest.h
    3.5 KB · Views: 47
  • ReadWrite.h
    735 bytes · Views: 43
  • ReadWrite.cpp
    10.5 KB · Views: 75
Then I Include Library SD, SdFat, and Time. (Not sure SD is needed.)

SdFat is a replacement of SD, so you should not include both, also it may be necessary to remove SD from library, as it also has a SdFat.h which may results in missing references.
 
Thanks, WMXZ!
I searched my drive and found three places with libraries. I removed all SD and SdFat libraries.
Documents\Arduino\libraries\arduino_655865 // This is an SdFat library!
Documents\Arduino\libraries\SdFat // This is the real Greiman SdFat library
Program Files (x86)\Arduino\libraries\SD
AppData\Local\Temp\arduino_build_186614\libraries\*.*

I then used the Arduino Library Manager to re-install SdFat. Unfortunately, the "undefined reference to `FatFile::eek:pen..." error still persists.
There were two changes to the build.
1. The duplicate SysCall.h warning is gone (due to arduino_655865).
2. I am now getting ten instances of the dreaded TimeLib.h warning:
Code:
In file included from c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\sys\stat.h:9:0,
                 from c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\sys\_default_fcntl.h:188,
                 from c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\sys\fcntl.h:4,
                 from c:\program files (x86)\arduino\hardware\tools\arm\arm-none-eabi\include\fcntl.h:1,
                 from C:\Users\ROYREICH~1\Documents\Arduino\libraries\SdFat\src/FatLib/FatApiConstants.h:30,
                 from C:\Users\ROYREICH~1\Documents\Arduino\libraries\SdFat\src/FatLib/FatFile.h:36,
                 from C:\Users\ROYREICH~1\Documents\Arduino\libraries\SdFat\src/FatLib/ArduinoFiles.h:33,
                 from C:\Users\ROYREICH~1\Documents\Arduino\libraries\SdFat\src/FatLib/FatLib.h:27,
                 from C:\Users\ROYREICH~1\Documents\Arduino\libraries\SdFat\src/SdFat.h:33,
                 from C:\Users\ROYREI~1\AppData\Local\Temp\arduino_build_204673\sketch\log.cpp:7:
C:\Program Files (x86)\Arduino\hardware\teensy\avr\libraries\Time/time.h:1:2: warning: #warning "Please include TimeLib.h, not Time.h.  Future versions will remove Time.h" [-Wcpp]
 #warning "Please include TimeLib.h, not Time.h.  Future versions will remove Time.h"
  ^
I can include the full build output if needed, LMK. I have started reading the forums for this issue, which doesn't seem to have a simple fix, so far. The offending Time.h include is from arduino\hardware\tools\arm\arm-none-eabi\include\sys\stat.h:9:0, in all ten instances, with the same sequence of includes from FatFile.h to stat.h, but triggered from different places in the SdFat library. Switching the include from Time.h to TimeLib.h would require editing the toolchain files, which I'm very nervous about. I'm not sure whether this is related to the undefined reference problem, and needs to be fixed first (and the best way to fix it), or continue with the undefined reference problem, and how to proceed with that. Or both. Any suggestions or ideas?
 
The TimeLib warning, is only a gentle reminder to not to use Time.h if you wanted to include the Arduino TimeLib library. (have a look into TimeLib/Time.h)
It seems that TimeLib was written by a Linux guy that ignores that windows filing is not case sensitive, so Time.h will include system library time.h.
Only change Arduino files to use TimeLib.h not toolchain files (all below arm-none-eabi)

I would not use the arduino library manager but download the github zipfile and place it under either yourSketchFolder/libraries or under hardware/teensy/avr/libraries. Remove the "-master" from the extracted library.
But the Arduino location may work or not (I don't use it).

Summary:
I have three locations where libraries are found
Documents/Arduino-1.8.12/libraries (for Arduino in general, change every time Arduino is downloaded )
Documents/Arduino-1.8.12/hardware/teensy/avr/libraries (Teensy specific libraries, change every time Teensyduino is downloaded)
Documents/Arduino/libraries (my private sketch libraries, that only change when I change them)
 
Thanks to your guidance, after cleaning up my library structure I was able to find the root cause of my problem. Way back in the dim times I created a local copy of SdFat's SdFatConfig.h to override the default settings, to turn off long file names and SDIO streaming support. When I updated to the new tools versions, I was therefore still using an old copy of SdFatConfig.h. I merged the new and old versions. Other than my required changes, the main difference is in how USE_FCNTL_H is configured based on CPU flags (line 93). After merging the new version I was able to compile without the undefined references! I changed it one more to set USE_FCNTL_H 0, and the error came back.

Now I was left with only four Time.h warnings. I looked at this a lot. The problem is that the gcc toolchain is including time.h, not Time.h. The time.h include is from stat.h, which is included by fcntl.h, which is included by SdFat. I see no straightforward way to modify my code or Arduino/Teesnyduino libraries to fix that. The solution for me was to delete Time.h in the TimeLib folder. Since I do not have the Arduino Time library installed, the correct (I hope) toolchain time.h was found. The code builds and tested fine.

I can't thank you enough for your help with this, WMXZ!
 
Status
Not open for further replies.
Back
Top