esphome / issues

Issue Tracker for ESPHome
https://esphome.io/
290 stars 36 forks source link

api services remote_transmitter compile error esp32c3 #2 #3564

Open paccerdk opened 2 years ago

paccerdk commented 2 years ago

The problem

Getting undefined reference when using lambda

Seems that stale bot is closing a lot of issues in this repo that should not be closed - I've come across this a lot in this repo., this time, came here from google, with same problem.

original issue: https://github.com/esphome/issues/issues/3201

one thing i'm noticing is that i use esp32-c3 too, in this case, with esp-idf however.

Which version of ESPHome has the issue?

ESPHome version 2022.8.3 compiled on Sep 7 2022, 22:10:13

What type of installation are you using?

Home Assistant Add-on

Which version of Home Assistant has the issue?

2022.8.7

What platform are you using?

ESP-IDF

Board

ESP-C3-12F custom hardware

Component causing the issue

api service lambda

Example YAML snippet

esphome:
  name: espinfra1
  platformio_options:
    board_build.flash_mode: dio

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:
  services:
    - service: send_ir_raw
      variables:
        keycode: int[]
      then:
      - remote_transmitter.transmit_raw:
          transmitter_id: IR_TX
          code: !lambda 'return keycode;'
          carrier_frequency: 38kHz

ota:
  password: "xxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

remote_transmitter:
  - id: IR_TX
    pin: GPIO3
    carrier_duty_percent: 50%
  - id: dummy #workaround for issue: https://github.com/esphome/issues/issues/2934 
    pin: GPIO0
    carrier_duty_percent: 50%

remote_receiver:
  pin:
    number: GPIO4
    inverted: true
  dump: all

Anything in the logs that might be useful for us?

INFO Reading configuration /config/esphome/espinfra1.yaml...
INFO Generating C++ source...
INFO Compiling app...
Processing espinfra1 (board: esp32-c3-devkitm-1; framework: espidf; platform: platformio/espressif32 @ 3.5.0)
--------------------------------------------------------------------------------
HARDWARE: ESP32C3 160MHz, 320KB RAM, 4MB Flash
 - framework-espidf @ 3.40302.0 (4.3.2) 
 - tool-cmake @ 3.16.4 
 - tool-ninja @ 1.7.1 
 - toolchain-riscv32-esp @ 8.4.0+2021r2-patch2 
 - toolchain-xtensa-esp32s2 @ 8.4.0+2021r2-patch2
Reading CMake configuration...
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
No dependencies
Compiling /data/espinfra1/.pioenvs/espinfra1/src/main.o
Linking /data/espinfra1/.pioenvs/espinfra1/firmware.elf
/data/cache/platformio/packages/toolchain-riscv32-esp/bin/../lib/gcc/riscv32-esp-elf/8.4.0/../../../../riscv32-esp-elf/bin/ld: /data/espinfra1/.pioenvs/espinfra1/src/main.o: in function `esphome::api::ListEntitiesServicesArgument::ListEntitiesServicesArgument()':
/config/esphome/.esphome/build/espinfra1/src/esphome/components/api/api_pb2.h:786: undefined reference to `esphome::api::enums::ServiceArgType esphome::api::to_service_arg_type<std::vector<long, std::allocator<long> > >()'
collect2: error: ld returned 1 exit status
*** [/data/espinfra1/.pioenvs/espinfra1/firmware.elf] Error 1
========================= [FAILED] Took 21.36 seconds =========================
waicool20 commented 2 years ago

Similar issue but I got a bit more in the log

HARDWARE: ESP32C3 160MHz, 320KB RAM, 4MB Flash
 - framework-espidf @ 3.40302.0 (4.3.2) 
 - tool-cmake @ 3.16.4 
 - tool-ninja @ 1.7.1 
 - toolchain-riscv32-esp @ 8.4.0+2021r2-patch2 
 - toolchain-xtensa-esp32s2 @ 8.4.0+2021r2-patch2
Reading CMake configuration...
LDF: Library Dependency Finder -> https://bit.ly/configure-pio-ldf
Dependency Graph
|-- noise-c @ 0.1.4
|   |-- libsodium @ 1.10018.1
Compiling /data/test/.pioenvs/test/src/main.o
Linking /data/test/.pioenvs/test/firmware.elf
/data/cache/platformio/packages/toolchain-riscv32-esp/bin/../lib/gcc/riscv32-esp-elf/8.4.0/../../../../riscv32-esp-elf/bin/ld: /data/test/.pioenvs/test/src/main.o: in function `esphome::api::ExecuteServiceArgument* std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<esphome::api::ExecuteServiceArgument const*, std::vector<esphome::api::ExecuteServiceArgument, std::allocator<esphome::api::ExecuteServiceArgument> > >, esphome::api::ExecuteServiceArgument*>(__gnu_cxx::__normal_iterator<esphome::api::ExecuteServiceArgument const*, std::vector<esphome::api::ExecuteServiceArgument, std::allocator<esphome::api::ExecuteServiceArgument> > >, __gnu_cxx::__normal_iterator<esphome::api::ExecuteServiceArgument const*, std::vector<esphome::api::ExecuteServiceArgument, std::allocator<esphome::api::ExecuteServiceArgument> > >, esphome::api::ExecuteServiceArgument*)':
/data/cache/platformio/packages/toolchain-riscv32-esp/riscv32-esp-elf/include/c++/8.4.0/bits/stl_uninitialized.h:82: undefined reference to `long esphome::api::get_execute_arg_value<long>(esphome::api::ExecuteServiceArgument const&)'
/data/cache/platformio/packages/toolchain-riscv32-esp/bin/../lib/gcc/riscv32-esp-elf/8.4.0/../../../../riscv32-esp-elf/bin/ld: /data/test/.pioenvs/test/src/main.o: in function `esphome::api::ListEntitiesServicesArgument::ListEntitiesServicesArgument()':
/data/cache/platformio/packages/toolchain-riscv32-esp/riscv32-esp-elf/include/c++/8.4.0/bits/stl_vector.h:1085: undefined reference to `esphome::api::enums::ServiceArgType esphome::api::to_service_arg_type<long>()'
github-actions[bot] commented 1 year ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

paccerdk commented 1 year ago

bug still present

CarlosGS commented 1 year ago

I confirm this is still an issue with ESP32C3, in this case using Arduino idf (haven't tried with esp-idf).

/data/cache/platformio/packages/toolchain-riscv32-esp/bin/../lib/gcc/riscv32-esp-elf/8.4.0/../../../../riscv32-esp-elf/bin/ld: /data/co2portable/.pioenvs/co2portable/src/main.cpp.o: in function `esphome::api::ExecuteServiceArgument* std::__uninitialized_copy<false>::__uninit_copy<__gnu_cxx::__normal_iterator<esphome::api::ExecuteServiceArgument const*, std::vector<esphome::api::ExecuteServiceArgument, std::allocator<esphome::api::ExecuteServiceArgument> > >, esphome::api::ExecuteServiceArgument*>(__gnu_cxx::__normal_iterator<esphome::api::ExecuteServiceArgument const*, std::vector<esphome::api::ExecuteServiceArgument, std::allocator<esphome::api::ExecuteServiceArgument> > >, __gnu_cxx::__normal_iterator<esphome::api::ExecuteServiceArgument const*, std::vector<esphome::api::ExecuteServiceArgument, std::allocator<esphome::api::ExecuteServiceArgument> > >, esphome::api::ExecuteServiceArgument*)':
/data/cache/platformio/packages/toolchain-riscv32-esp/riscv32-esp-elf/include/c++/8.4.0/bits/stl_uninitialized.h:82: undefined reference to `long esphome::api::get_execute_arg_value<long>(esphome::api::ExecuteServiceArgument const&)'
/data/cache/platformio/packages/toolchain-riscv32-esp/bin/../lib/gcc/riscv32-esp-elf/8.4.0/../../../../riscv32-esp-elf/bin/ld: /data/co2portable/.pioenvs/co2portable/src/main.cpp.o: in function `esphome::api::ListEntitiesServicesArgument::ListEntitiesServicesArgument()':
/config/esphome/.esphome/build/co2portable/src/esphome/components/adc/adc_sensor.h:17: undefined reference to `esphome::api::enums::ServiceArgType esphome::api::to_service_arg_type<long>()'
collect2: error: ld returned 1 exit status

It only happens when enabling services:, removing that part allows to compile correctly.

CarlosGS commented 1 year ago

@agners Please help us out, this issue is related to what you saw here https://github.com/esphome/esphome/pull/2035#discussion_r672128988. The linker gets confused by the different types and gives an error when enabling api user services.

The error goes away by changing int32_t to long (https://github.com/esphome/esphome/compare/dev...CarlosGS:esphome:patch-48), but the API stops working. In general, I don't understand this part well enough to make a proper PR. Maybe it is possible to re-define the int32_t earlier, or maybe it is something else. Hoping you can have a go at it. Thanks! :)

agners commented 1 year ago

Can't you just define it using int, e.g.

template<> std::vector<int> get_execute_arg_value<std::vector<int>>(const ExecuteServiceArgument &arg) {

Honestly, I am also not sure as to why RISC-V defines uint32_t differently.

agners commented 1 year ago

Hm, that would essentially revert my change :thinking: Yeah, not sure :cold_sweat:

CarlosGS commented 1 year ago

Thanks! No worries, I was just hoping it'd be something more evident :smile: Unfortunately Espressif has adopted this oddity for Xtensa too: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/release-5.x/5.0/gcc.html#int32-t-and-uint32-t-for-xtensa-compiler & https://github.com/espressif/esp-idf/issues/9511#issuecomment-1354539638.

Another issue caused by this: https://github.com/esphome/issues/issues/3970

For the api services, I've tried just swapping all int to int32_t https://github.com/CarlosGS/esphome/commit/a07ad7f7074e68a03aa89c8ef463bac0585955a9, in line with your change, and it compiles without errors/warnings. But the API stops working even for the normal HASS connection. The compilation is clean & USB logging doesn't show anything relevant with VERY_VERBOSE (sensors & OTA work OK, just no API). And on the HASS side, logs just show Connection error occurred: [Errno 104] Connection reset by peer.

Thanks for having a look. Can't do much more at the moment either, but it's good to keep an eye on that annoying change.

agners commented 1 year ago

Unfortunately Espressif has adopted this oddity for Xtensa too: https://docs.espressif.com/projects/esp-idf/en/latest/esp32/migration-guides/release-5.x/5.0/gcc.html#int32-t-and-uint32-t-for-xtensa-compiler & espressif/esp-idf#9511 (comment).

Well, I guess it is a good thing in the end, as it matches now and it seems to be what upstream GCC is doing. But yeah, the change is annoying at first :sweat_smile:

But the API stops working even for the normal HASS connection.

I mean it didn't compile before, so "stops working" sounds weird to me?

CarlosGS commented 1 year ago

Good point! Well the linker error mentioned in this thread only appears when adding services: to the api section.

I meant when changing user_services.cpp to turn all int to int32_t, there are no linker errors anymore, but the api connection now doesn't work (with or without services: enabled in YAML).

twosky2000 commented 1 year ago

here's my fix:


esphome:
  name: fingerprint
  platformio_options:
    board_build.flash_mode: dio
    board_build.extra_flags:
      #- "-DARDUINO_USB_MODE=0"
      - "-DARDUINO_USB_CDC_ON_BOOT=0"
      - "-include \"fix.h\""

file at .esphome/build/fingerprint/fix.h


#ifdef __riscv

#undef __INT32_TYPE__
#define __INT32_TYPE__      int

#undef __UINT32_TYPE__
#define __UINT32_TYPE__     unsigned int

#endif // __riscv

I got the idea from https://github.com/espressif/esp-idf/issues/6906 https://github.com/arendst/Tasmota/pull/11808/commits

seams esp-idf assumes int is int long for RISC-V/esp32-3c. Maybe PlatformIO can use this fix too.

I try to make a pr when I figure out how to make this automatic.

mkaiser commented 1 year ago

`

here's my fix:


esphome:
  name: fingerprint
  platformio_options:
    board_build.flash_mode: dio
    board_build.extra_flags:
      #- "-DARDUINO_USB_MODE=0"
      - "-DARDUINO_USB_CDC_ON_BOOT=0"
      - "-include \"fix.h\""

file at .esphome/build/fingerprint/fix.h


#ifdef __riscv

#undef __INT32_TYPE__
#define __INT32_TYPE__      int

#undef __UINT32_TYPE__
#define __UINT32_TYPE__     unsigned int

#endif // __riscv

I got the idea from espressif/esp-idf#6906 https://github.com/arendst/Tasmota/pull/11808/commits

seams esp-idf assumes int is int long for RISC-V/esp32-3c. Maybe PlatformIO can use this fix too.

I try to make a pr when I figure out how to make this automatic.

thank you very much for this hotfix, got my stuff working now, after several headaches ;)

@ESP Core developers: Is there any chance you can "really fix" this datatype interpretation issue?

clomads commented 1 year ago

I can also confirm the hotfix works

CarlosGS commented 11 months ago

Here's the updated patch, after the .esphome build folder was moved in https://github.com/esphome/esphome/pull/5374

babgvant commented 9 months ago

Here's the updated patch, after the .esphome build folder was moved in esphome/esphome#5374

* Create the file `fix.h` mentioned above, but now place it in the main esphome folder (next to the yaml files).

* In the yaml code you need to add `src/` and additional `includes:` statement:
esphome:
  name: theName
  platformio_options:
    board_build.extra_flags:
      - "-include \"src/fix.h\""
  includes:
    - fix.h

This way the fix.h file is automatically copied into the src/ folder within the platformio build directory.

Thank you! This worked for me as well with a ESP-C3-Zero board.

CarlosGS commented 6 months ago

Not sure when or how, but this seems to be already fixed :tada: Anyone else can confirm it is possible to compile without the patch?

mircsicz commented 5 months ago

Not sure when or how, but this seems to be already fixed 🎉 Anyone else can confirm it is possible to compile without the patch?

I'm on a Lolin C3 Pico and for me it didn't without the fix...