How to programm in c++ / How to execute void app_main(void) in c++

Dythe_
Posts: 7
Joined: Sun Feb 09, 2020 4:39 pm

How to programm in c++ / How to execute void app_main(void) in c++

Postby Dythe_ » Sun Feb 09, 2020 5:05 pm

Hi,
I am using the ESP-IDF V4.0 with the Eclipse plug in and I would like to use C++ to programm.
Unfortunately, in the past week, I did'nt found that solution. What I found was to use "extern C app_main()" but this only compile the main with a C compiler witch mean I can write c++ code but not use it.
Esp-IDF bug#7.png
Esp-IDF bug#7.png (143.53 KiB) Viewed 14395 times
Maybe theres is a guide and I just did'nt found it and then I would like it if someone could link it here or if there is'nt one can someone make one here please.

ESP_Angus
Posts: 2344
Joined: Sun May 08, 2016 4:11 am

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby ESP_Angus » Sun Feb 09, 2020 10:13 pm

Hi Dythe,

Where does the "spi_esp32.h" header come from? My guess is this contains a definition of "class Spi", but it seems like the corresponding .cpp file is not being compiled into your project, so it can't link to this class.

The solution may be as simple as adding the .cpp file to the component CMakeLists.txt SRCs list (probably in main/CMakeLists.txt).

There is more detailed information about writing component CMakeLists.txt files in the IDF docuemntation:
https://docs.espressif.com/projects/esp ... ists-files

Dythe_
Posts: 7
Joined: Sun Feb 09, 2020 4:39 pm

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby Dythe_ » Wed Feb 12, 2020 4:15 pm

Hi Angus,
Thanks for your solution, you were right that I needed to include the class '.cpp'. I also had to include the main.cpp in my class cpp to make it work.

But today I realised maybe it didn't work because the build failed at step 814 out of 817 with the message :

Code: Select all

FAILED: esp-idf/esp32/ld/esp32.project.ld
What I would like to have is a real complete guide on how to take an ESP-IDF template app that I get from my ESP-IDF V4.0 and transform it into a C++ project in witch I can build class and everything else.

At this point I am so unsure of what I did right and what I didn't do right that I would like to start again from the beginning.

Thank you

leenowell
Posts: 92
Joined: Tue Jan 15, 2019 1:50 pm

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby leenowell » Fri Feb 14, 2020 8:10 am

Hi

I have done this a few times off the top of my head the steps are...
1. Create the sample / new project using the project -> new etc route.
2. Change the generated main.c to main.cpp
3. Put the extern C around the header file includes too
4. Add the app_main extern inside the extern C braces i.e. the exact definition of the generated app_main but with extern in front.
5. In the makefile list file change main.c to main.cpp and add any other CPP files you need.

That should then compile fine and you can use C++ in you main.cpp file.

If this doesn't work, if you zip the generated project up and post here I will take a look later.

Thanks
Lee.

Dythe_
Posts: 7
Joined: Sun Feb 09, 2020 4:39 pm

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby Dythe_ » Fri Feb 14, 2020 2:14 pm

Hi Lee,

Thanks for the confirmation of the whole procedure. The only thing I'm not doing at the moment is to put the #include in the extern C.

While waiting for my last message to be approved I realise my problem with the compilation failling at step 817/820 was because you should NEVER compile a project for the first time with the local target. It gives lots of error and when you switch to the right target, it then give this failing message.

So now that I figured this out everything is working.
Thanks again.

leenowell
Posts: 92
Joined: Tue Jan 15, 2019 1:50 pm

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby leenowell » Fri Feb 14, 2020 7:38 pm

Glad you got it working. Once you start using functions from the header files I believe you will get linker errors if you don't put the #includes in extern C wrapper.

Dythe_
Posts: 7
Joined: Sun Feb 09, 2020 4:39 pm

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby Dythe_ » Sun Feb 16, 2020 2:56 am

Hi, Lee

Just like you said, I'm getting linker issue. The problem is still appearing even after following all you said to do.
I included a tar ball with my project because now I really don't know what to do
ak8975.tar.gz
(30.92 KiB) Downloaded 745 times
Thanks
Dythe

leenowell
Posts: 92
Joined: Tue Jan 15, 2019 1:50 pm

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby leenowell » Sun Feb 16, 2020 8:32 am

You don't mention what linker errors you have but it is probably because you have put the #include "spi.h" inside the extern "C" wrapper in both source files.

The way to think about it is that if the file extension is .cpp the c++ compiler will be invoked and will alter all the names during the compilation process. Therefore, when it tries to link everything it is looking for the altered names not the ones you specified. For a .c extension, it uses the c compiler and therefore uses the names you specified.

So... If you start calling C functions which have been compiled using a C compiler (e.g. all the IDF ones) from a .cpp file, the "library" you ultimately link with has the unchanged names in it but your c++ compiler has altered then when it compiled the .cpp file and is looking at link time for the altered name not the original name. Putting extern "C" wrapper around the include tells the cpp compiler for those items do not alter the names and use the original ones.

Putting your #include "spi.h" in the extern C wrapper therefore tells the c++ compiler not to change the names for the calls to these functons/ methods on the include but spi.cpp is compiled but the c++ compiler which is altering the names. Hence the linked issues.

Net result if you are including functions which have been compiled in C put the extern C wrapper around the #include. Otherwise you are in normal C++ mode and continue as you normally would.

Hope this helps

Dythe_
Posts: 7
Joined: Sun Feb 09, 2020 4:39 pm

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby Dythe_ » Sun Feb 16, 2020 7:37 pm

Hi,
It does help because now I understand more about how it works.
Unfortunately, I am still getting the same error even after cleanning and recompiling.


Here are the change I did :
-I got rid of the extern C wrapper in the spi.cpp
-Here is the spi.h now
esp-idf bug #9.png
esp-idf bug #9.png (17.99 KiB) Viewed 14047 times
-Here is the main.cpp
esp-idf bug#10.png
esp-idf bug#10.png (19.27 KiB) Viewed 14047 times
For the rest I didn't change anything

As for the linker error :

Code: Select all

FAILED: app-template.elf 
: && /home/isecurity/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-elf/bin/xtensa-esp32-elf-g++  -mlongcalls -Wno-frame-address  -nostdlib CMakeFiles/app-template.elf.dir/project_elf_src.c.obj  -o app-template.elf  esp-idf/esp_ringbuf/libesp_ringbuf.a esp-idf/driver/libdriver.a esp-idf/wpa_supplicant/libwpa_supplicant.a esp-idf/efuse/libefuse.a esp-idf/bootloader_support/libbootloader_support.a esp-idf/app_update/libapp_update.a esp-idf/spi_flash/libspi_flash.a esp-idf/nvs_flash/libnvs_flash.a esp-idf/esp_wifi/libesp_wifi.a esp-idf/esp_eth/libesp_eth.a esp-idf/lwip/liblwip.a esp-idf/tcpip_adapter/libtcpip_adapter.a esp-idf/esp_event/libesp_event.a esp-idf/pthread/libpthread.a esp-idf/espcoredump/libespcoredump.a esp-idf/esp32/libesp32.a esp-idf/xtensa/libxtensa.a esp-idf/esp_common/libesp_common.a esp-idf/esp_rom/libesp_rom.a esp-idf/soc/libsoc.a esp-idf/log/liblog.a esp-idf/heap/libheap.a esp-idf/freertos/libfreertos.a esp-idf/vfs/libvfs.a esp-idf/newlib/libnewlib.a esp-idf/cxx/libcxx.a esp-idf/app_trace/libapp_trace.a esp-idf/asio/libasio.a esp-idf/coap/libcoap.a esp-idf/console/libconsole.a esp-idf/nghttp/libnghttp.a esp-idf/esp-tls/libesp-tls.a esp-idf/esp_adc_cal/libesp_adc_cal.a esp-idf/esp_gdbstub/libesp_gdbstub.a esp-idf/tcp_transport/libtcp_transport.a esp-idf/esp_http_client/libesp_http_client.a esp-idf/esp_http_server/libesp_http_server.a esp-idf/esp_https_ota/libesp_https_ota.a esp-idf/protobuf-c/libprotobuf-c.a esp-idf/protocomm/libprotocomm.a esp-idf/mdns/libmdns.a esp-idf/esp_local_ctrl/libesp_local_ctrl.a esp-idf/esp_websocket_client/libesp_websocket_client.a esp-idf/expat/libexpat.a esp-idf/wear_levelling/libwear_levelling.a esp-idf/sdmmc/libsdmmc.a esp-idf/fatfs/libfatfs.a esp-idf/freemodbus/libfreemodbus.a esp-idf/jsmn/libjsmn.a esp-idf/json/libjson.a esp-idf/libsodium/liblibsodium.a esp-idf/mqtt/libmqtt.a esp-idf/openssl/libopenssl.a esp-idf/spiffs/libspiffs.a esp-idf/ulp/libulp.a esp-idf/unity/libunity.a esp-idf/wifi_provisioning/libwifi_provisioning.a esp-idf/main/libmain.a -Wl,--cref -Wl,--Map=/home/isecurity/esp/eclipse-workspace/ak8975/build/app-template.map -fno-rtti -fno-lto esp-idf/asio/libasio.a esp-idf/coap/libcoap.a esp-idf/esp_adc_cal/libesp_adc_cal.a esp-idf/esp_gdbstub/libesp_gdbstub.a esp-idf/esp_https_ota/libesp_https_ota.a esp-idf/esp_http_client/libesp_http_client.a esp-idf/esp_local_ctrl/libesp_local_ctrl.a esp-idf/esp_websocket_client/libesp_websocket_client.a esp-idf/expat/libexpat.a esp-idf/fatfs/libfatfs.a esp-idf/wear_levelling/libwear_levelling.a esp-idf/sdmmc/libsdmmc.a esp-idf/freemodbus/libfreemodbus.a esp-idf/jsmn/libjsmn.a esp-idf/libsodium/liblibsodium.a esp-idf/mqtt/libmqtt.a esp-idf/tcp_transport/libtcp_transport.a esp-idf/esp-tls/libesp-tls.a esp-idf/openssl/libopenssl.a esp-idf/spiffs/libspiffs.a esp-idf/ulp/libulp.a esp-idf/unity/libunity.a esp-idf/wifi_provisioning/libwifi_provisioning.a esp-idf/protocomm/libprotocomm.a esp-idf/esp_http_server/libesp_http_server.a esp-idf/nghttp/libnghttp.a esp-idf/protobuf-c/libprotobuf-c.a esp-idf/mdns/libmdns.a esp-idf/console/libconsole.a esp-idf/json/libjson.a esp-idf/esp_ringbuf/libesp_ringbuf.a esp-idf/driver/libdriver.a esp-idf/wpa_supplicant/libwpa_supplicant.a esp-idf/efuse/libefuse.a esp-idf/bootloader_support/libbootloader_support.a esp-idf/app_update/libapp_update.a esp-idf/spi_flash/libspi_flash.a esp-idf/nvs_flash/libnvs_flash.a esp-idf/esp_wifi/libesp_wifi.a esp-idf/esp_eth/libesp_eth.a esp-idf/lwip/liblwip.a esp-idf/tcpip_adapter/libtcpip_adapter.a esp-idf/esp_event/libesp_event.a esp-idf/pthread/libpthread.a esp-idf/espcoredump/libespcoredump.a esp-idf/esp32/libesp32.a esp-idf/xtensa/libxtensa.a esp-idf/esp_common/libesp_common.a esp-idf/esp_rom/libesp_rom.a esp-idf/soc/libsoc.a esp-idf/log/liblog.a esp-idf/heap/libheap.a esp-idf/freertos/libfreertos.a esp-idf/vfs/libvfs.a esp-idf/newlib/libnewlib.a esp-idf/cxx/libcxx.a esp-idf/app_trace/libapp_trace.a esp-idf/mbedtls/mbedtls/library/libmbedtls.a esp-idf/mbedtls/mbedtls/library/libmbedcrypto.a esp-idf/mbedtls/mbedtls/library/libmbedx509.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libcoexist.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libcore.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libespnow.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libmesh.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libnet80211.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libphy.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libpp.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/librtc.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libsmartconfig.a esp-idf/esp_ringbuf/libesp_ringbuf.a esp-idf/driver/libdriver.a esp-idf/wpa_supplicant/libwpa_supplicant.a esp-idf/efuse/libefuse.a esp-idf/bootloader_support/libbootloader_support.a esp-idf/app_update/libapp_update.a esp-idf/spi_flash/libspi_flash.a esp-idf/nvs_flash/libnvs_flash.a esp-idf/esp_wifi/libesp_wifi.a esp-idf/esp_eth/libesp_eth.a esp-idf/lwip/liblwip.a esp-idf/tcpip_adapter/libtcpip_adapter.a esp-idf/esp_event/libesp_event.a esp-idf/pthread/libpthread.a esp-idf/espcoredump/libespcoredump.a esp-idf/esp32/libesp32.a esp-idf/xtensa/libxtensa.a esp-idf/esp_common/libesp_common.a esp-idf/esp_rom/libesp_rom.a esp-idf/soc/libsoc.a esp-idf/log/liblog.a esp-idf/heap/libheap.a esp-idf/freertos/libfreertos.a esp-idf/vfs/libvfs.a esp-idf/newlib/libnewlib.a esp-idf/cxx/libcxx.a esp-idf/app_trace/libapp_trace.a esp-idf/mbedtls/mbedtls/library/libmbedtls.a esp-idf/mbedtls/mbedtls/library/libmbedcrypto.a esp-idf/mbedtls/mbedtls/library/libmbedx509.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libcoexist.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libcore.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libespnow.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libmesh.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libnet80211.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libphy.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libpp.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/librtc.a /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32/libsmartconfig.a -u esp_app_desc -L /home/isecurity/esp/esp-idf/components/esp_wifi/lib_esp32 -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl -L /home/isecurity/esp/eclipse-workspace/ak8975/build/esp-idf/esp32 -T esp32_out.ld -u app_main -L /home/isecurity/esp/eclipse-workspace/ak8975/build/esp-idf/esp32/ld -T esp32.project.ld -L /home/isecurity/esp/esp-idf/components/esp32/ld -T esp32.peripherals.ld -u call_user_start_cpu0 -u ld_include_panic_highint_hdl /home/isecurity/esp/esp-idf/components/xtensa/esp32/libhal.a -Wl,--gc-sections -L /home/isecurity/esp/esp-idf/components/esp_rom/esp32/ld -T esp32.rom.ld -T esp32.rom.libgcc.ld -T esp32.rom.syscalls.ld -T esp32.rom.newlib-data.ld -T esp32.rom.newlib-funcs.ld -Wl,--undefined=uxTopUsedPriority -u vfs_include_syscalls_impl esp-idf/newlib/libnewlib.a -u newlib_include_locks_impl -u newlib_include_heap_impl -u newlib_include_syscalls_impl -u newlib_include_pthread_impl -u __cxa_guard_dummy -lstdc++ esp-idf/pthread/libpthread.a -u __cxx_fatal_exception -lgcov -lc -lm -lgcc && :
/home/isecurity/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/bin/ld: esp-idf/main/libmain.a(main.cpp.obj):(.literal.app_main+0x20): undefined reference to `Spi::spiBusAddDevice(spi_host_device_t, spi_device_interface_config_t const*, spi_device_t**)'
/home/isecurity/.espressif/tools/xtensa-esp32-elf/esp-2019r2-8.2.0/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/bin/ld: esp-idf/main/libmain.a(main.cpp.obj): in function `app_main':
/home/isecurity/esp/eclipse-workspace/ak8975/build/../main/main.cpp:49: undefined reference to `Spi::spiBusAddDevice(spi_host_device_t, spi_device_interface_config_t const*, spi_device_t**)'
Just in case, I'm adding the Problem windows because I'm also getting warning issue with the "driver/spi_master.h" librairie which is included in my spi.h file :
esp-idf bug#11.png
esp-idf bug#11.png (72.41 KiB) Viewed 14047 times
Thank you so much for your help, it's been 3 weeks now since I started setuping this environment and I'm still not able to use it fully.
Dythe

leenowell
Posts: 92
Joined: Tue Jan 15, 2019 1:50 pm

Re: How to programm in c++ / How to execute void app_main(void) in c++

Postby leenowell » Sun Feb 16, 2020 8:55 pm

In the spi.h file, the #includes above the extern C are standard C header files and therefore need to be inside the wrapper. If that doesn't work can you post the full compile log?

Who is online

Users browsing this forum: grantb and 117 guests