String.h conflicts with <string.h> on case insensitive filesystems
The Arduino API renamed "WString.h" to "String.h" Given that "string.h" is a part of libc, and that most modern operating systems implement sort of "fuzzy" case-matching in their filesystems, this seems ripe for generating confusion.
And in fact, it seems to break builds when sketches have been imported into Atmel Studio 7, if they use the ArduinoAPI - when ipaddress.cpp is built as part of the core, it includes both <string.h> and "String.h", and gets api/string.h for both of them, leaving the libc functions undefined:
Target "CoreBuild" in file "C:\Program Files (x86)\Atmel\Studio\7.0\Vs\Compiler.targets" from project "c:\users\rnovaes\Documents\Atmel Studio\7.0\ArduinoSketch7\ArduinoSketch7\ArduinoCore\ArduinoCore.cppproj" (target "Build" depends on it):
Using "RunCompilerTask" task from assembly "C:\Program Files (x86)\Atmel\Studio\7.0\Extensions\Application\AvrGCC.dll".
Task "RunCompilerTask"
Shell Utils Path C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils
C:\Program Files (x86)\Atmel\Studio\7.0\shellUtils\make.exe all --jobs 4 --output-sync
Building file: ../src/core/api/IPAddress.cpp
Invoking: AVR8/GNU C Compiler : 5.4.0
"C:\Program Files (x86)\Atmel\Studio\7.0\toolchain\avr8\avr8-gnu-toolchain\bin\avr-g++.exe" -funsigned-char -funsigned-bitfields -DDEBUG -DF_CPU=16000000L -DARDUINO=10809 -DARDUINO_AVR_NANO_EVERY -DARDUINO_ARCH_AVR -DUSB_VID=0x2341 -DUSB_PID=0x0058 -DUSB_MANUFACTURER="\"Arduino LLC\"" -I"C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\include" -I"..\include\core" -I"..\include\core\api" -I"..\include\core\api\deprecated" -I"..\include\core\api\deprecated-avr-comp\avr" -I"..\include\variants\nona4809" -Os -fno-threadsafe-statics -ffunction-sections -fdata-sections -fpack-struct -fshort-enums -g2 -w -mmcu=atmega4809 -B "C:\Program Files (x86)\Atmel\Studio\7.0\Packs\atmel\ATmega_DFP\1.2.209\gcc\dev\atmega4809" -c -std=gnu++11 -MD -MP -MF "src/core/api/IPAddress.d" -MT"src/core/api/IPAddress.d" -MT"src/core/api/IPAddress.o" -o "src/core/api/IPAddress.o" "../src/core/api/IPAddress.cpp"
In file included from ../src/core/api/IPAddress.cpp:21:0:
..\include\core\api/Print.h: In member function 'size_t Print::write(const char*)':
c:\users\rnovaes\Documents\Atmel Studio\7.0\ArduinoSketch7\ArduinoSketch7\ArduinoCore\include\core\api\Print.h(50,52): error: 'strlen' was not declared in this scope
return write((const uint8_t *)str, strlen(str));
^
../src/core/api/IPAddress.cpp: In constructor 'IPAddress::IPAddress(const uint8_t*)':
c:\users\rnovaes\Documents\Atmel Studio\7.0\ArduinoSketch7\ArduinoSketch7\ArduinoCore\src\core\api\IPAddress.cpp(43,59): error: 'memcpy' was not declared in this scope
memcpy(_address.bytes, address, sizeof(_address.bytes));
^
../src/core/api/IPAddress.cpp: In member function 'IPAddress& IPAddress::operator=(const uint8_t*)':
c:\users\rnovaes\Documents\Atmel Studio\7.0\ArduinoSketch7\ArduinoSketch7\ArduinoCore\src\core\api\IPAddress.cpp(90,59): error: 'memcpy' was not declared in this scope
memcpy(_address.bytes, address, sizeof(_address.bytes));
^
../src/core/api/IPAddress.cpp: In member function 'bool IPAddress::operator==(const uint8_t*) const':
c:\users\rnovaes\Documents\Atmel Studio\7.0\ArduinoSketch7\ArduinoSketch7\ArduinoCore\src\core\api\IPAddress.cpp(102,63): error: 'memcmp' was not declared in this scope
return memcmp(addr, _address.bytes, sizeof(_address.bytes)) == 0;
^
make: *** [src/core/api/IPAddress.o] Error 1
c:\users\rnovaes\Documents\Atmel Studio\7.0\ArduinoSketch7\ArduinoSketch7\ArduinoCore\Debug\Makefile(243,1): error: recipe for target 'src/core/api/IPAddress.o' failed
There is some discussion here: https://www.avrfreaks.net/forum/7-compilation-error-arduino-nano-every-sketch
The exact problem may be that AS7 adds -I"..\include\core\api" that isn't needed (or used in an Arduino IDE build), but it does illustrate the sort of confusion that can/will occur.
I just ran into the same issue.
Was using -I"{runtime.platform.path}/cores/arduino/api" in my platform.txt for all build steps, for convenience.
Switched to using -I"{runtime.platform.path}/cores/arduino" (where my custom Arduino.h is located) and explicitly including the ArduinoAPI.h + family headers with paths relative to that location.
Not the end of the world but it was a surprise
I was writing an Arduino Emulator and was wondering why it did not compile on OS/X !
It took me quite some time to figure this out.... my vote is to use WString.h instead of String.h! In the meantime I have to decide how to deal with this....
Recently I tried to import an Arduino sketch to Microchip Studio 7 and ran into the same issue. I renamed String.h and changed all references of it to make it compile, but this is really annoying.
Please find another name for this file! I bet a lot of people are confused by the naming, even in the original Arduino IDE.
I was originally named WString.h, and still is in the AVR core which most people are using today.
https://github.com/arduino/ArduinoCore-avr/blob/master/cores/arduino/WString.h
I was creating the project for the ATMEGA4809 which is on the Arduino Nano Every. If I do the same with then normal Arduino Nano, there is no String.h. So I guess, only the newer platforms may be affacted yet.
only the newer platforms may be affacted yet.
Yes, the renaming happened as part of the new "Arduino API" project, which is supposed to be the "direction which all cores are headed." Theoretically, this allows code that isn't core-dependent (like Strings) to be shared between multiple platforms, which would be a good thing.
So far, the old cores have not been ported to the new API, and still have WString.* in their cores...
Hi Bill,
the only core still not ported is avr indeed (but it is ongoing, just needs a ton of attention not to break anything).
Anyway, I'm ok with renaming to WString or any other name. @cmaglie do you have any preference?
Some good news: WIN 10+ now supports case sensitive directories.
See https://docs.microsoft.com/en-us/windows/wsl/case-sensitivity for more info.
NOTE: an elevated command window is needed and the directory must be empty but you can: rename the dir, create new dir, enable case-sensitivity, the copy everything from renamed to new.
memcpy is undefined in Visual Studio for Nano Every. #include <string.h> includes String.h, not the string.h. String.h includes string.h but agin it leads to String.h. So what one should do if their system is CASE_INSENSITIVE?
I've been hitting this issue as well when creating a new Arduino Core and integrating with some SDKs, so the rename to WString would be welcomed.
This issue also makes it impossible to mock the CoreAPI for non-Arduino platforms...