How to programm in c++ / How to execute void app_main(void) in c++
How to programm in c++ / How to execute void app_main(void) in c++
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. 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.
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. 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.
Re: How to programm in c++ / How to execute void app_main(void) in c++
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
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
Re: How to programm in c++ / How to execute void app_main(void) in c++
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 :
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
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
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
Re: How to programm in c++ / How to execute void app_main(void) in c++
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.
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.
Re: How to programm in c++ / How to execute void app_main(void) in c++
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.
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.
Re: How to programm in c++ / How to execute void app_main(void) in c++
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.
Re: How to programm in c++ / How to execute void app_main(void) in c++
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 Thanks
Dythe
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 Thanks
Dythe
Re: How to programm in c++ / How to execute void app_main(void) in c++
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
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
Re: How to programm in c++ / How to execute void app_main(void) in c++
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 -Here is the main.cpp For the rest I didn't change anything
As for the linker error :
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 :
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
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 -Here is the main.cpp 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**)'
Dythe
Re: How to programm in c++ / How to execute void app_main(void) in c++
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