ArduinoCore-API icon indicating copy to clipboard operation
ArduinoCore-API copied to clipboard

String.h conflicts with <string.h> on case insensitive filesystems

Open WestfW opened this issue 6 years ago • 17 comments

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.

WestfW avatar Aug 02 '19 23:08 WestfW

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

oclyke avatar Jul 02 '20 17:07 oclyke

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....

pschatzmann avatar Dec 14 '20 20:12 pschatzmann

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.

kiesel-electronics avatar Jan 01 '21 12:01 kiesel-electronics

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

PaulStoffregen avatar Jan 02 '21 19:01 PaulStoffregen

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.

kiesel-electronics avatar Jan 02 '21 20:01 kiesel-electronics

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...

WestfW avatar Jan 04 '21 03:01 WestfW

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?

facchinm avatar Jan 04 '21 12:01 facchinm

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.

toddk123 avatar Nov 16 '21 01:11 toddk123

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?

KillzoneKid avatar Dec 05 '21 20:12 KillzoneKid

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.

carlosperate avatar Oct 05 '22 18:10 carlosperate

This issue also makes it impossible to mock the CoreAPI for non-Arduino platforms...

higaski avatar Feb 19 '24 09:02 higaski