Closed pgreenland closed 5 years ago
Hi @pgreenland,
Thanks for the detailed bug report and the example project, it made reproducing this straightforward. Much appreciated.
In gcc 8 __ieee754_sqrtf()
is defined in libgcc not libm (I believe the reason for this is that it uses the floating point instructions, and this code lives in native libgcc not libc libm, although there might be some other toolchain-oriented reason).
You can resolve the issue by changing the dependencies line in externallib/CMakeLists.txt as follows:
target_link_libraries(examplelib m gcc)
This moves -lgcc
after -lm
in the linker arguments list.
If doing this in the external project is not viable, you can also do it in the parent component but only with CMake 3.13 or newer:
add_subdirectory(../examplelib examplelib)
target_link_libraries(${COMPONENT_TARGET} PRIVATE examplelib)
cmake_policy(SET CMP0079 NEW)
target_link_libraries(examplelib m gcc)
I looked to see if we can fix this on the IDF side but it doesn't look CMake will allow us to (we can make a CMake library target depend on specific libraries, but we can't create dependencies between two external libraries like libm & libgcc. For IDF components the order is preserved because we add target_link_libraries ... c m gcc
) in a fixed order always, but for external libraries this doesn't necessarily happen and CMake will add the libraries to the link line in the order it sees them.
Hey @projectgus,
Thanks for the lightning fast reply.
I'd found one reference to that function in the source for libgcc during a google session - was trying hard not to reveal too many of the magicians secrets though :-P.
Linking against both libm and libgcc, in that order for the correct symbol resolution works nicely for the example project.
Strangely when I do exactly the same thing for my larger project within the library cmake file itself as you describe it doesn't link.
Looking at the command line output on error it appears that both -lm and -lgcc are there, but in the wrong order still. The end of the command line being:
-L /home/user/esp/esp-idf/components/esp_wifi/lib_esp32 -lgcov -lc -lgcc -lm -u pthread_include_pthread_impl -u pthread_include_pthread_cond_impl -u pthread_include_pthread_local_storage_impl
I'm far from an expert at CMake unfortunately, although it's been going well up until now :-P. Other users report that the order of libraries in target_link_libraries
should be respected for this sort of reason. For me it doesn't seem to be. I am using the version in the Debian mirrors, which is a tad out of date at 3.7.2.
For now my solution is to bodge via the CMAKE_CXX_LINK_EXECUTABLE variable, which seems to work quite nicely.
set(CMAKE_CXX_LINK_EXECUTABLE "${CMAKE_CXX_LINK_EXECUTABLE} -lm -lgcc")
With that I'm back in business....while only feeling a little dirty :-P.
Thanks for the help, I'd have been at this for an age without that pointer.
Hi @pgreenland ,
Glad that this got you going again.
Strangely when I do exactly the same thing for my larger project within the library cmake file itself as you describe it doesn't link.
This might be a CMake bug? It would be interesting to know if also fails on newer CMake.
Clever kludge in any case, I'm glad it's got you up and running again. :)
Environment
Problem Description
Recently updated esp-idf, switching from GCC 5.2 to GCC 8.2 in the process.
I've a project which includes several "pure" cmake library projects, as described in the documentation https://docs.espressif.com/projects/esp-idf/en/latest/api-guides/build-system.html#using-third-party-cmake-projects-with-components. Previously these were building and linking correctly.
After updating to the latest esp-idf I'm struggling to successfully build my project, with linking failing on my pure cmake libraries which make use of math functions. In my case specifically sqrtf, which results in the following linker error:
/home/user/esp/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/bin/ld: /home/user/esp/xtensa-esp32-elf/bin/../lib/gcc/xtensa-esp32-elf/8.2.0/../../../../xtensa-esp32-elf/lib/libm.a(lib_a-wf_sqrt.o): in function
sqrtf': /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/src/newlib/newlib/libm/math/wf_sqrt.c:35: undefined reference to__ieee754_sqrtf'
Without use of math functions from my external projects the project links, flashes and runs correctly (with the exception of incorrect maths).
Expected Behavior
Linking completes without error when linking in external cmake projects consisting of C libraries which make use of math functions contained within math.h.
Actual Behavior
Linking fails with an undefined reference to a symbol I haven't been able to track down, seemingly related to the internal implementation of the sqrtf function.
Steps to repropduce
Code to reproduce this issue
See attached file:
minimal_linker_error_example.tar.gz
Debug Logs
Here's the complete output from a failed build, with the complete log attached complete_build_log.txt: