calebh / Juniper

https://www.juniper-lang.org/
MIT License
79 stars 9 forks source link

No such file or directory: #include <new> #10

Closed Timo-Weike closed 1 year ago

Timo-Weike commented 2 years ago

I currently try to build and upload the blink example with VsCode using the Arduino IDE. But I get the following error message when I try to compile the generated file

Alternatives for new: []
ResolveLibrary(new)
  -> candidates: []fatal error: new: No such file or directory

 #include <new>
          ^~~~~
compilation terminated.

The board is a Arduino Nano Every and I have not included any other libraries.

calebh commented 2 years ago

The new operation that we need the header for is called a placement new, which essentially runs a new operation in some preallocated (in this case, stack allocated) space. I will look into ways to remove the dependency on this standard library header by defining my own implementation.

calebh commented 2 years ago

@Timo-Weike can you try the following fix? In the compiled C++ file, remove the #include <new> and place the following snippet into the global scope:

void* operator new(size_t size, void* ptr)
{
    return ptr;
}

This should implement the placement new operator which is what that header file was included for in the first place. It's weird that you're getting this error, since the header is definitely part of the Arduino standard library.

Timo-Weike commented 2 years ago

I found that chainging #include <new> to #include <new.h> solved the issue that the file could not be found.

But the content of the file found is not the one you suggested I add

// path: C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino\new.h
#ifndef NEW_H
#define NEW_H

#include <stdlib.h>

void * operator new(size_t size);
void * operator new[](size_t size);
void operator delete(void * ptr);
void operator delete[](void * ptr);

#endif

Also so adding the code you suggested did solved some problems but compiling the code brought new ones.

In file included from C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino/api/Interrupts.h:8:0,
from C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino/api/ArduinoAPI.h:29,
from C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino/Arduino.h:23,
from c:\Users\timow\Documents\GitHub\arduino-projects\juniper_test\juniper_test.ino:663:
C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino/api/Common.h:115:6: error: conflicting declaration of 'void setup()' with 'C' linkage
void setup(void);
^~~~~
c:\Users\timow\Documents\GitHub\arduino-projects\juniper_test\juniper_test.ino:7019:6: note: previous declaration with 'C++' linkage
void setup() {
^~~~~
In file included from C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino/api/Interrupts.h:8:0,
from C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino/api/ArduinoAPI.h:29,
from C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino/Arduino.h:23,
from c:\Users\timow\Documents\GitHub\arduino-projects\juniper_test\juniper_test.ino:663:
C:\Users\timow\AppData\Local\Arduino15\packages\arduino\hardware\megaavr\1.8.7\cores\arduino/api/Common.h:116:6: error: conflicting declaration of 'void loop()' with 'C' linkage
void loop(void);
^~~~
c:\Users\timow\Documents\GitHub\arduino-projects\juniper_test\juniper_test.ino:7022:6: note: previous declaration with 'C++' linkage
void loop() {
^~~~

See for the code juniper_test.zip

calebh commented 2 years ago

@Timo-Weike I was able to reproduce what you were seeing. It seems that the board package you're using is using some sort of nonstandard Arduino API. Besides the missing placement new operator, it seems that the Arduino Nano Every compiles with setup() and loop() as having C linkage instead of C++ linkage. I checked the official Arduino repository and those functions have C++ linkage. I then checked the board package for the Nano Every and those functions have C linkage.

To fix your compilation error you can change the setup() and loop() definitions at the bottom of juniper_test.ino with this code:

#ifdef __cplusplus
extern "C" {
#endif
void setup() {
    Blink::setup();
}
#ifdef __cplusplus
}
#endif

#ifdef __cplusplus
extern "C" {
#endif
void loop() {
    Blink::loop();
}
#ifdef __cplusplus
}
#endif

Which will give those functions the proper linkage. All the other board packages that I've encountered so far use C++ linkage. Likewise for the placement new operator, if that operator is properly defined in new.c, including a duplicate copy of that function will result in the compilation error which would break compilation for other boards. The only thing I can do is provide extra configuration flags in the Juniper compiler which will change the generated code.

calebh commented 2 years ago

I have added two new compilation flags to fix the issues you brought up. This is the new help message:

Juniper 3.1.1
usage: Juniper.exe -s s1.jun s2.jun ... sn.jun -o main.cpp
  options:
    -s, --source: The .jun Juniper source files to compile
    -o, --output: The file in which the compiled C++ is written
    -h, --help: View this help message
    --custom-placement-new: Output a custom implementation of placement new, for use in Arduino board packages that give compilation errors related to #include <new>
    --c-linkage: setup and loop functions should have C linkage instead of C++. For Arduino board packages that give compilation error related to setup() and loop() linkage issues

I should have this fix in the binaries and released by next Sunday at the latest. In the meantime if you feel like using this version now you can compile the compiler from the source code.