Linking issue after compilation ESP32

matt001k
Posts: 11
Joined: Thu Sep 03, 2020 2:42 am

Linking issue after compilation ESP32

Postby matt001k » Thu Jun 10, 2021 3:17 am

Hi all,
I'm having an issue while linking my executable I'm the esp-idf. I'm getting a lot of "undefined reference to" functions in the output failing the build. This made me believe that there is an issue with missing source files included in the build but this is not the case, I have the associated object files needed for linking in my build directory. The following is a brief overview of my build setup:

Code: Select all

- drivers
    - needed src/libs
    - CMakeLists.txt
- interface
    - needed src/libs
    - CMakeLists.txt
- main
    - needed src/libs
    - CMakeLists.txt
- lib
    - needed src/libs
    - CMakeLists.txt
- platform
    - needed src/libs
    - CMakeLists.txt 
- CMakeLists.txt 
I'm registering these components in using idf_component_register and many of these libraries depend on one another.
For example the LM75 driver depends on the I2C interface and the temperature interface depends on the LM75 driver. Now some components from drivers are required in interface and visa versa.
I'm thinking that because under registered components:
PRIV_REQUIRES: interface(for drivers)
PRIV_REQUIRES: drivers(for interface)
There is a dual dependency happening and the linker is not able to determine the order of operation needed to link these files.
I've come across this error before in CMake environments but have always found work around, with the ESP-IDF there is a lot of abstraction within the CMake files and does not allow a lot of manipulation.
I'm just curious if anyone else has had this issue and what they did to fix this

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

Re: Linking issue after compilation ESP32

Postby ESP_Angus » Thu Jun 10, 2021 3:42 am

Hi matt001k,

If you're sure all the components are being included in the build (can check the list that is output in the CMake run output), and the problem is due to cyclic dependencies in the components, then there are three possible fixes:
  • Set this CMake property in a component that's part of the cycle. This line can be placed anywhere under the idf_component_register line:

    Code: Select all

    set_property(TARGET ${COMPONENT_LIB} APPEND PROPERTY LINK_INTERFACE_MULTIPLICITY 3)
    . This is something of a heavy solution as it causes all components in the linker cycle to be repeated 3 times instead of 2, to make sure all parts of the cycle are resolved. There may be circumstances where you need to increase the number furhter.
  • If you only have a few symbols (functions or variables) that have a "reverse" dependency and it is a pure link-time dependency (ie the header dependency at compile time is one way only), then *instead* you can mark these as "undefined" on the linker command line and remove the reverse "REQUIRES" so it's one way. Adding an undefined symbol ensures that it always get included into the link, even if the linker hasn't processed the thing that relies on it yet. You can do this by adding a line like:

    Code: Select all

    target_link_libraries(${COMPONENT_LIB} INTERFACE "-u symbol_in_this_component_that_is_always_required")
    . This is less heavy-handed than LINK_INTERFACE_MULTIPLICITY and linking will be faster. However, as mentioned, it only works if the dependency cycle doesn't also exist at compile time and you can remove one of the "REQUIRES" directions.
  • Combine the components which have a dependency cycle. This may seem silly, but it's still possible to have modular code without absolutely everything being a component. If two things are very tightly coupled then it may make sense for them to be in the same component.
This is a common question when folks are scaling up to more involved project structures, so we'll add some advice to the Build System page in the docs.

matt001k
Posts: 11
Joined: Thu Sep 03, 2020 2:42 am

Re: Linking issue after compilation ESP32

Postby matt001k » Thu Jun 10, 2021 10:34 am

Thank you so much for the information ESP_Angus. I will try it out today, I attempted the MULTIPLICITY directive, but was not sure how to name the set component, but it makes sense now. Will there be a way in the future to bring some of that abstraction away from CMake and allow for better transparency in large projects? My company uses Espressif products heavily and this would be greatly beneficial to have.

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

Re: Linking issue after compilation ESP32

Postby ESP_Angus » Fri Jun 11, 2021 12:04 am

matt001k wrote:
Thu Jun 10, 2021 10:34 am
Will there be a way in the future to bring some of that abstraction away from CMake and allow for better transparency in large projects? My company uses Espressif products heavily and this would be greatly beneficial to have.
Hi Matt,

What kind of support do you have in mind? If there's particular tasks you'd wish had easier or clearer solutions ("How do I ..."), please let us know and we'll try to improve them.

Something we want to make it easier to do is detect cyclic dependencies between components (A depends on B depends on C depends on A). This is something we also do inside ESP-IDF as we can clean up its internal architecture. However, once a cyclic dependency is identified the fix will probably be one of things mentioned above (or re-architecting the software to remove the cycle). CMake doesn't have any additional magic for handling cyclic dependencies between libraries and neither does the GNU linker.

(There are the linker options --start-group/--end-group option which we used in the old GNU Make build system but this leads to slow links, encourages "big ball of mud" architectures where everything depends on everything else, and isn't well supported in CMake anyhow - so for these reasons it probably won't be coming back).

Angus

matt001k
Posts: 11
Joined: Thu Sep 03, 2020 2:42 am

Re: Linking issue after compilation ESP32

Postby matt001k » Sat Jun 12, 2021 12:44 am

Hi Angus!
Thanks again for the response, the fix for cyclic dependencies worked our well.
I was just curious if there will ever be a more "bare" option in which building will not be as reliant on the IDF? I guess it is possible to build with gcc's Extensa compiler, and maybe that question is not that important :) .
I did have another question about low level register manipulation for led pwm library. I can open another thread on that if that works best or ask on here?

Who is online

Users browsing this forum: Bing [Bot], Google [Bot] and 73 guests