Problem
hal-exceptions is built as a plain static archive (add_library(...) with no type keyword in libhal_make_library, CMakeLists.txt, which produces libhal-exceptions.a). Static archives only pull in the .o members needed to resolve an existing undefined symbol reference — anything else gets dropped by the linker.
That's a problem here because runtime/armv7/libunwind_wrappers.cpp defines symbols like __wrap___gnu_unwind_pr_common, __wrap___aeabi_unwind_cpp_pr0/1/2, __wrap__sig_func, __wrap___gxx_personality_v0, __wrap___gcc_personality_v0, __wrap_register_tm_clones/__wrap_deregister_tm_clones — but conanfile.py's exelinkflags only passes -Wl,--wrap= for a different, smaller set of symbols (__cxa_throw, __cxa_rethrow, __cxa_end_catch, __cxa_begin_catch, __cxa_end_cleanup, _Unwind_Resume). None of the libunwind-wrapper symbols have a matching --wrap flag, so nothing in a normal link creates an undefined reference to them, and the linker would otherwise skip that object file entirely.
The current workaround is brute force: package_info() splices -Wl,--whole-archive <path to libhal-exceptions.a> -Wl,--no-whole-archive into every consumer's link flags, forcing every member object into the link regardless of whether it's referenced.
Proposal
Build hal-exceptions as a CMake OBJECT library (or otherwise package/link its raw .o files) instead of a static archive. Object files passed directly to the linker (not inside an archive) are always included unconditionally — this is the same effect --whole-archive is being used to force today, just achieved without an archive member-selection step to fight in the first place. This would let package_info() drop the -Wl,--whole-archive / -Wl,--no-whole-archive pair entirely.
Caveat
Conan's CMakeDeps generator doesn't have a clean built-in path for exporting a package as a set of loose object files the way it does for a .a/.so (no first-class "imported OBJECT library from a package" pattern). That said, this package already bypasses normal target-based linking — package_info() hand-writes a literal path into exelinkflags rather than relying on a generated CMake target — so this isn't actually a blocker here. Worth flagging so whoever picks this up doesn't expect a trivial add_library(... OBJECT) swap to be transparently packaged by Conan; the package()/package_info() steps will need to copy/reference the .o files directly, same as is already done for the .a today.
Expected benefit
- Removes the need for
-Wl,--whole-archive/-Wl,--no-whole-archive and the associated hardcoded .a path in package_info().
- Removes the implicit dependency on every "always force-included" symbol needing to either be
--wrapped or otherwise referenced — object files are included unconditionally, so this failure mode (an object silently dropped because nothing references its symbols) can't recur.
Problem
hal-exceptionsis built as a plain static archive (add_library(...)with no type keyword inlibhal_make_library, CMakeLists.txt, which produceslibhal-exceptions.a). Static archives only pull in the.omembers needed to resolve an existing undefined symbol reference — anything else gets dropped by the linker.That's a problem here because
runtime/armv7/libunwind_wrappers.cppdefines symbols like__wrap___gnu_unwind_pr_common,__wrap___aeabi_unwind_cpp_pr0/1/2,__wrap__sig_func,__wrap___gxx_personality_v0,__wrap___gcc_personality_v0,__wrap_register_tm_clones/__wrap_deregister_tm_clones— butconanfile.py'sexelinkflagsonly passes-Wl,--wrap=for a different, smaller set of symbols (__cxa_throw,__cxa_rethrow,__cxa_end_catch,__cxa_begin_catch,__cxa_end_cleanup,_Unwind_Resume). None of the libunwind-wrapper symbols have a matching--wrapflag, so nothing in a normal link creates an undefined reference to them, and the linker would otherwise skip that object file entirely.The current workaround is brute force:
package_info()splices-Wl,--whole-archive <path to libhal-exceptions.a> -Wl,--no-whole-archiveinto every consumer's link flags, forcing every member object into the link regardless of whether it's referenced.Proposal
Build
hal-exceptionsas a CMakeOBJECTlibrary (or otherwise package/link its raw.ofiles) instead of a static archive. Object files passed directly to the linker (not inside an archive) are always included unconditionally — this is the same effect--whole-archiveis being used to force today, just achieved without an archive member-selection step to fight in the first place. This would letpackage_info()drop the-Wl,--whole-archive/-Wl,--no-whole-archivepair entirely.Caveat
Conan's
CMakeDepsgenerator doesn't have a clean built-in path for exporting a package as a set of loose object files the way it does for a.a/.so(no first-class "imported OBJECT library from a package" pattern). That said, this package already bypasses normal target-based linking —package_info()hand-writes a literal path intoexelinkflagsrather than relying on a generated CMake target — so this isn't actually a blocker here. Worth flagging so whoever picks this up doesn't expect a trivialadd_library(... OBJECT)swap to be transparently packaged by Conan; thepackage()/package_info()steps will need to copy/reference the.ofiles directly, same as is already done for the.atoday.Expected benefit
-Wl,--whole-archive/-Wl,--no-whole-archiveand the associated hardcoded.apath inpackage_info().--wrapped or otherwise referenced — object files are included unconditionally, so this failure mode (an object silently dropped because nothing references its symbols) can't recur.