mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(cxx): avoid self-referential generator expression in libgcc_cxx
The cxx component re-injects its own archive late on the link line so its
stack-unwind wrappers take precedence over libgcc's (when C++ exceptions
are disabled). It does this through an INTERFACE helper, libgcc_cxx, that
carries `$<TARGET_FILE:${cxx}>`. That helper was linked back into the cxx
target with PUBLIC, which places it in the cxx archive's own
LINK_LIBRARIES, so the cxx target ends up transitively referencing its
own output file.
When CMake computes the cxx target's sources it walks the target's own
link implementation, encounters `$<TARGET_FILE:${cxx}>`, and to resolve the
file it needs the target's link language, which in turn needs its
sources. This loop makes generation fail with:
The SOURCES of "..." use a generator expression that depends on the
SOURCES themselves.
CMake only hits this when it reaches the cxx target standalone before the
target has been pulled into a link by a consumer, and whether that
happens depends on the project layout and target evaluation order. That
is why it surfaces only in some projects, while the examples build fine.
Link libgcc_cxx as INTERFACE instead of PUBLIC. A static archive is not
linked, so its private LINK_LIBRARIES are inert; consumers still receive
libgcc_cxx through INTERFACE_LINK_LIBRARIES, so the intended link order is
preserved. Removing the self-reference makes generation independent of
evaluation order.
Signed-off-by: Frantisek Hrbata <frantisek.hrbata@espressif.com>
This commit is contained in:
@@ -89,7 +89,14 @@ endif()
|
||||
idf_component_get_property(cxx cxx COMPONENT_LIB)
|
||||
add_library(libgcc_cxx INTERFACE)
|
||||
target_link_libraries(libgcc_cxx INTERFACE ${CONFIG_COMPILER_RT_LIB_NAME} $<TARGET_FILE:${cxx}>)
|
||||
target_link_libraries(${COMPONENT_LIB} PUBLIC libgcc_cxx)
|
||||
# Link as INTERFACE, not PUBLIC: libgcc_cxx references $<TARGET_FILE:${cxx}>, so adding it to the
|
||||
# cxx archive's own LINK_LIBRARIES would make the target depend on its own TARGET_FILE. CMake then
|
||||
# needs the link language (hence SOURCES) to resolve that TARGET_FILE, which is a self-reference and
|
||||
# fails generation with "The SOURCES of '...' use a generator expression that depends on the SOURCES
|
||||
# themselves" whenever the cxx target is not itself link-consumed (e.g. cmakev2, IDFGH-16748). A
|
||||
# static archive isn't linked, so its private link libraries are inert; consumers still get
|
||||
# libgcc_cxx through INTERFACE_LINK_LIBRARIES, preserving link order.
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE libgcc_cxx)
|
||||
|
||||
if(NOT CONFIG_COMPILER_CXX_EXCEPTIONS)
|
||||
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u __cxx_fatal_exception")
|
||||
|
||||
Reference in New Issue
Block a user