Skip to content

cmake/bfd: fix unset syntax error and undefined-variable typos - #487

Merged
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix-bfd-cmake-unset-typos
Apr 27, 2026
Merged

cmake/bfd: fix unset syntax error and undefined-variable typos#487
mrjimenez merged 1 commit into
amule-project:masterfrom
got3nks:fix-bfd-cmake-unset-typos

Conversation

@got3nks

@got3nks got3nks commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Fixes #486.

Summary

Three independent bugs in cmake/bfd.cmake, all surfacing only when bfd.h is found on the system and find_library(LIBBFD_TMP bfd) succeeds — i.e., wherever binutils-dev (or equivalent) is actually installed. None of the project's CI environments install it, so the buggy block has been dead code there; @danim7 hit it on a stock Ubuntu 24.04 with binutils-dev present.

The three bugs

1. unset (\${CMAKE_REQUIRED_LIBRARIES}) — wrong syntax

Expands the value of the variable into the unset call. When the loop iterates over multi-element lists like /usr/lib/.../libbfd.so;iberty, that's two arguments to unsetunset called with incorrect number of arguments. When the value is empty (the loop's first element, see #2), it's zero arguments → same error. The variable to clean up is CMAKE_REQUIRED_LIBRARIES itself, so the correct call is unset (CMAKE_REQUIRED_LIBRARIES).

2. Empty \"\" first foreach element

Tests linking with no extra link libraries. On systems where bfd auto-resolves, the test succeedsBFD_LIBRARY then gets set to the empty string, the loop breaks, and the subsequent if (NOT BFD_LIBRARY) fires (empty string is falsy in cmake), producing the spurious bfd.h found but can't link against it, disabling support message and disabling BFD support that actually works. The \"\${LIBBFD_TMP}\" entry already covers the "bfd alone is enough" case explicitly via the path returned by find_library, so the empty-string probe is redundant.

3. Three undefined-variable typos in the same line

  • \${LIBBFD};iberty;dl — missing _TMP suffix; LIBBFD (without _TMP) is undefined here.
  • \${LIBINTL_TMP} — never defined; intended LIBINTL.
  • \${LIBINBTL} — typo for LIBINTL.

Each expands to empty silently, so the surrounding combination collapses to either an earlier element (duplicate) or a partial entry missing libbfd entirely. Fixing the names gives a complete and distinct set of probe combinations.

While here, reformat the foreach element list onto one element per line — much easier to audit which combinations are actually being probed.

Diff

foreach (CMAKE_REQUIRED_LIBRARIES
-    "" "\${LIBBFD_TMP}" "\${LIBBFD_TMP};iberty" "\${LIBBFD_TMP};dl" "\${LIBBFD};iberty;dl" "\${LIBBFD_TMP};\${LIBINTL}" "\${LIBBFD_TMP};iberty;\${LIBINTL_TMP}" "\${LIBBFD_TMP};iberty;dl;\${LIBINBTL}"
+    "\${LIBBFD_TMP}"
+    "\${LIBBFD_TMP};iberty"
+    "\${LIBBFD_TMP};dl"
+    "\${LIBBFD_TMP};iberty;dl"
+    "\${LIBBFD_TMP};\${LIBINTL}"
+    "\${LIBBFD_TMP};iberty;\${LIBINTL}"
+    "\${LIBBFD_TMP};iberty;dl;\${LIBINTL}"
)
    ...
    if (BFD_COMPILE_TEST)
        set (BFD_LIBRARY \${CMAKE_REQUIRED_LIBRARIES} CACHE STRING \"...\")
-       unset (\${CMAKE_REQUIRED_LIBRARIES})
+       unset (CMAKE_REQUIRED_LIBRARIES)
        break()
    endif()

Test plan

Credits: diagnosis and the empty-string fix are @danim7's from #486; this PR adds the unset syntax fix and the three typos plus the formatting cleanup.

Three independent bugs in cmake/bfd.cmake, all surfacing when bfd.h
is found and find_library(LIBBFD_TMP bfd) succeeds (i.e., on systems
where libbfd is actually available):

1. Line 29: 'unset (${CMAKE_REQUIRED_LIBRARIES})' expands the *value*
   of the variable into the unset call. When the loop iterates over
   list values like '/usr/lib/.../libbfd.so;iberty', the value
   expands to multiple arguments and unset bails with 'incorrect
   number of arguments'. When the value is empty (the loop's first
   element, see amule-project#2), it expands to zero arguments -- same error.
   The variable to clean up is CMAKE_REQUIRED_LIBRARIES itself, so
   the correct call is 'unset (CMAKE_REQUIRED_LIBRARIES)'.

2. Line 14: the empty "" first foreach element tests whether bfd
   links with no extra link libraries. On systems where it does
   succeed (e.g., libbfd auto-resolves), BFD_LIBRARY then gets set
   to the empty string, the loop breaks, and the subsequent
   'if (NOT BFD_LIBRARY)' check fires (empty string is falsy in
   cmake) -- producing the spurious 'bfd.h found but can't link
   against it, disabling support' message and disabling BFD
   support that actually works. The "${LIBBFD_TMP}" entry already
   covers the "bfd alone is enough" case explicitly via the
   library path returned by find_library, so the empty-string
   probe is redundant.

3. Line 14 again: three undefined-variable typos. ${LIBBFD} (no
   _TMP suffix), ${LIBINTL_TMP}, and ${LIBINBTL} are all undefined
   in this scope, so each expands to empty silently and the
   surrounding combination collapses to a partial entry that's
   either equivalent to an earlier element or missing libbfd
   entirely. Fixing them to the intended names (LIBBFD_TMP,
   LIBINTL, LIBINTL respectively) gives a complete and distinct
   set of probe combinations.

While here, reformat the foreach element list onto one element
per line -- it's much easier to audit the combinations this way.

Diagnosis (and the empty-string fix) reported by @danim7 in amule-project#486.
@mrjimenez
mrjimenez merged commit ae5b70b into amule-project:master Apr 27, 2026
9 checks passed
@danim7

danim7 commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Thanks, I confirm it works now!

@danim7

danim7 commented Apr 27, 2026

Copy link
Copy Markdown
Contributor

Maybe you could also install binutils-dev in the CI environment to catch this kind of issue in the future?

got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
The bug fixed in the previous commit lived in cmake/bfd.cmake and
fired only when bfd.h was findable on the build host. Without
binutils-dev installed, check_include_file(bfd.h) returns false and
the entire foreach block is dead code -- which is why CI never
caught it and the bug survived for years.

Adding binutils-dev to the Ubuntu CI dep list ensures the BFD probe
loop actually runs in CI, so any future regression in bfd.cmake
fails the build. The mingw-w64 and macOS jobs are intentionally
left alone: the cmake logic is platform-agnostic, so coverage on
one platform is sufficient and we avoid bloating the other two
jobs' install steps.

Suggested by @danim7 in amule-project#487 review.
@got3nks

got3nks commented Apr 27, 2026

Copy link
Copy Markdown
Contributor Author

@danim7 — good call. Followed up in #488 (had to be a separate PR since this one merged before I could push). #488 adds binutils-dev to the Ubuntu CI dep list so the BFD probe loop actually runs from now on. Left mingw-w64 and macOS jobs alone since the cmake logic is platform-agnostic — Ubuntu coverage is enough to catch regressions without bloating the other two jobs' install steps.

@mrjimenez

Copy link
Copy Markdown
Contributor

I now have issues compiling aMule in Opensuse Tumbleweed. At first it was amulecmd, then I tried adding

link_libraries(zstd sframe iberty z)

To the top of the root of CMakeLists.txt, but it still fails in CTagTest:

[ 89%] Building C object unittests/tests/CMakeFiles/CTagTest.dir/__/__/src/libs/common/strerror_r.c.o                                                                         
[ 89%] Linking CXX executable CTagTest                                                                                                                                        
/usr/bin/ld.bfd: /usr/lib64/libbfd.a(elf64-x86-64.o): in function `elf_x86_64_output_arch_local_syms':                                                                        
/home/abuild/rpmbuild/BUILD/binutils-2.45-build/binutils-2.45/build-dir/bfd/../../bfd/elf64-x86-64.c:5783:(.text+0x7fe): undefined reference to `htab_traverse'               
/usr/bin/ld.bfd: /usr/lib64/libbfd.a(elfxx-x86.o): in function `elf_x86_link_hash_table_free':                                                                                
/home/abuild/rpmbuild/BUILD/binutils-2.45-build/binutils-2.45/build-dir/bfd/../../bfd/elfxx-x86.c:686:(.text+0x201): undefined reference to `htab_delete'                     
/usr/bin/ld.bfd: /home/abuild/rpmbuild/BUILD/binutils-2.45-build/binutils-2.45/build-dir/bfd/../../bfd/elfxx-x86.c:688:(.text+0x212): undefined reference to `objalloc_free'  
/usr/bin/ld.bfd: /usr/lib64/libbfd.a(elfxx-x86.o): in function `_bfd_elf_x86_get_local_sym_hash':                                                                             
/home/abuild/rpmbuild/BUILD/binutils-2.45-build/binutils-2.45/build-dir/bfd/../../bfd/elfxx-x86.c:585:(.text+0x1278): undefined reference to `htab_find_slot_with_hash'       
/usr/bin/ld.bfd: /home/abuild/rpmbuild/BUILD/binutils-2.45-build/binutils-2.45/build-dir/bfd/../../bfd/elfxx-x86.c:598:(.text+0x1356): undefined reference to `_objalloc_alloc
'
/usr/bin/ld.bfd: /usr/lib64/libbfd.a(elfxx-x86.o): in function `_bfd_x86_elf_link_hash_table_create':
/home/abuild/rpmbuild/BUILD/binutils-2.45-build/binutils-2.45/build-dir/bfd/../../bfd/elfxx-x86.c:776:(.text+0x148d): undefined reference to `htab_try_create'
/usr/bin/ld.bfd: /home/abuild/rpmbuild/BUILD/binutils-2.45-build/binutils-2.45/build-dir/bfd/../../bfd/elfxx-x86.c:780:(.text+0x1499): undefined reference to `objalloc_create
'

I can't see what is going on right now, but since you are all at it now, maybe take a look at what might be causing it.

mrjimenez pushed a commit that referenced this pull request Apr 27, 2026
cmake/bfd.cmake's foreach probe loop only runs when bfd.h is
findable on the build host, i.e. when binutils-dev is installed.
None of the CI jobs install it today, which is why the bugs
fixed in #487 (PR ae5b70b) survived for years -- the entire
buggy block was dead code under CI.

Adding binutils-dev to the Ubuntu CI dep list ensures the BFD
probe loop actually runs, so any future regression in bfd.cmake
fails the build. The mingw-w64 and macOS jobs are intentionally
left alone: cmake/bfd.cmake is platform-agnostic, so coverage on
one platform is enough and we avoid bloating the other two
jobs' install steps.

Suggested by @danim7 as a follow-up to #487.
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
…deps

Reported by @mrjimenez in amule-project#487 (post-merge): on OpenSuse Tumbleweed
the probe loop fixed in amule-project#487 still produces an aMule that won't
link, with undefined references to libzstd (ZSTD_compress in
libbfd's compress.o) and to libiberty (htab_*, objalloc_* in
elfxx-x86.o, elf64-x86-64.o).

Two compounding problems:

1. The probe's bfd_errmsg-only test program is too small. It only
   forces the linker to pull in libbfd's tiny error-message object,
   which has no transitive deps -- so the probe matches at
   '${LIBBFD_TMP}' alone on every system. aMule's real usage in
   MuleDebug.cpp pulls in bfd_openr / bfd_check_format_matches,
   which drag in the ELF reader, which on modern binutils
   transitively references libzstd (via compress.o) and libsframe.

2. The probe's combination list doesn't include zstd or sframe,
   so even with a faithful test program there's no candidate that
   would actually link on Tumbleweed.

Fix: keep pkg-config-first as a fast path (some distros ship
bfd.pc; Tumbleweed/Ubuntu currently don't); strengthen the
fallback probe to call the same bfd functions MuleDebug.cpp uses
in production; extend the combination list to include
zstd;sframe;iberty;dl, which is what binutils 2.42+ on glibc
needs in practice.

Reproduced on stock OpenSuse Tumbleweed in docker:
    /usr/bin/ld.bfd: /usr/lib64/libbfd.a(compress.o): undefined
        reference to symbol 'ZSTD_compress'
    /usr/bin/ld.bfd: /usr/lib64/libzstd.so.1: error adding symbols:
        DSO missing from command line
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
…deps

Reported by @mrjimenez in amule-project#487 (post-merge): on OpenSuse Tumbleweed
the probe loop fixed in amule-project#487 still produces an aMule that won't
link, with undefined references to libzstd (ZSTD_compress in
libbfd's compress.o) and to libiberty (htab_*, objalloc_* in
elfxx-x86.o, elf64-x86-64.o).

Two compounding problems:

1. The probe's bfd_errmsg-only test program is too small. It only
   forces the linker to pull in libbfd's tiny error-message object,
   which has no transitive deps -- so the probe matches at
   '${LIBBFD_TMP}' alone on every system. aMule's real usage in
   MuleDebug.cpp pulls in bfd_openr / bfd_check_format_matches,
   which drag in the ELF reader, which on modern binutils
   transitively references libzstd (via compress.o) and libsframe.

2. The probe's combination list doesn't include zstd or sframe,
   so even with a faithful test program there's no candidate that
   would actually link on Tumbleweed.

Fix: keep pkg-config-first as a fast path (some distros ship
bfd.pc; Tumbleweed/Ubuntu currently don't); strengthen the
fallback probe to call the same bfd functions MuleDebug.cpp uses
in production; extend the combination list to include
zstd;sframe;iberty;dl, which is what binutils 2.42+ on glibc
needs in practice.

Reproduced on stock OpenSuse Tumbleweed in docker:
    /usr/bin/ld.bfd: /usr/lib64/libbfd.a(compress.o): undefined
        reference to symbol 'ZSTD_compress'
    /usr/bin/ld.bfd: /usr/lib64/libzstd.so.1: error adding symbols:
        DSO missing from command line
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
cmake/bfd.cmake sets BFD_LIBRARY (with underscore + _LIBRARY suffix)
but src/CMakeLists.txt has been reading the bare LIBBFD at four
target_link_libraries sites (amulecmd, amuled, amule monolithic,
amulegui). LIBBFD is undefined here, so it expands to empty -- those
four target_link_libraries calls have been silently linking nothing
for years. The variable-name mismatch predates the cmake-only
migration in amule-project#466.

Why amule still linked at all on most distros: until recently libbfd
either shipped as a shared library that auto-resolved its own deps
via DT_NEEDED, or its transitive deps (libiberty, libintl) were
short enough that the linker auto-pulled them via implicit search.

Why this surfaces now (amule-project#487 follow-up): OpenSuse Tumbleweed ships
libbfd only as a static archive, with no bfd.pc, and modern ld
--as-needed defaults. The archive's transitive deps
(zstd/sframe/iberty) aren't on the link line at all because
target_link_libraries has been adding nothing. With the variable
name corrected, cmake/bfd.cmake's probe-loop output finally reaches
the link line, and the loop's job of discovering the correct
combination becomes load-bearing.
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
…nfig

Reported by @mrjimenez on amule-project#487 (post-merge): on OpenSuse Tumbleweed,
amulecmd fails to link against libbfd.a with undefined references to
ZSTD_compress (libzstd) and htab_*/objalloc_* (libiberty). Static
libbfd needs zstd/sframe/iberty as transitive deps on modern
binutils, but the probe-loop approach in cmake/bfd.cmake was unable
to discover the right combination -- its toy bfd_errmsg probe links
fine with -lbfd alone on every system, even when the real aMule
link drags in objects from libbfd that need decompression /
hashtable / objalloc helpers.

Replaced with a two-tier strategy:

1. Try pkg-config first (some distros ship bfd.pc with the full
   transitive LIBS string already enumerated; when present that's
   the cleanest path). Prefer the --static form when available
   since libbfd is typically a static archive and we need
   Libs.private deps too.

2. Otherwise, collect every transitive dep libbfd is known to need
   on modern binutils -- iberty, zstd, sframe, intl, dl -- via
   find_library, and pass all that exist to the link line
   unconditionally. --as-needed (Linux default) drops shared libs
   that don't satisfy any reference; unused static archives
   contribute nothing. So over-linking is harmless on systems that
   don't need it, and load-bearing on those that do.

The previous combinatorial probe is gone entirely. It was always
guessing what libbfd's transitive deps are, when on a system where
binutils-devel is installed we can just *enumerate* them.

Reproduced on stock OpenSuse Tumbleweed in docker:
    /usr/bin/ld.bfd: /usr/lib64/libbfd.a(compress.o): undefined
        reference to symbol 'ZSTD_compress'
    /usr/bin/ld.bfd: /usr/lib64/libzstd.so.1: error adding symbols:
        DSO missing from command line

(Companion fix in src/CMakeLists.txt switches the consumer-side
references from ${LIBBFD} -- which has been undefined and silently
expanding to empty for years -- to ${BFD_LIBRARY}.)
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
cmake/bfd.cmake sets BFD_LIBRARY (with underscore + _LIBRARY suffix)
but src/CMakeLists.txt has been reading the bare ${LIBBFD} at four
target_link_libraries sites (amulecmd, amuled, amule monolithic,
amulegui). ${LIBBFD} is undefined here, so it expands to empty --
those four target_link_libraries calls have been silently linking
nothing. The variable-name mismatch predates the cmake-only
migration in amule-project#466.

The build worked anyway on most distros because libbfd's transitive
deps were either short enough that the linker auto-pulled them via
implicit search, or libbfd was a shared library whose own DT_NEEDED
entries dragged its deps in. On OpenSuse Tumbleweed (amule-project#487 follow-up
report) libbfd ships only as a static archive without bfd.pc, so
the explicit transitive deps cmake/bfd.cmake collects must actually
reach the link line for the build to succeed.
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
…nfig

Reported by @mrjimenez on amule-project#487 (post-merge): on OpenSuse Tumbleweed,
amulecmd fails to link against libbfd.a with undefined references
to ZSTD_compress (libzstd) and htab_*/objalloc_* (libiberty).
Static libbfd needs zstd/sframe/iberty as transitive deps on modern
binutils, but the probe-loop approach in cmake/bfd.cmake was unable
to discover the right combination -- its toy bfd_errmsg probe
linked fine with -lbfd alone on every system, even when the real
aMule link drags in objects from libbfd that need decompression /
hashtable / objalloc helpers. Even after reworking the probe to
call the same bfd functions MuleDebug.cpp uses in production
(bfd_find_nearest_line / bfd_map_over_sections / etc.), the small
test program still linked successfully with libbfd alone -- those
functions don't always pull in the same archive members ld picks
up when amulecmd's full link line is in flight.

Replaced with a two-tier strategy:

1. Try pkg-config first (some distros ship bfd.pc with the full
   transitive LIBS string already enumerated; when present that's
   the cleanest path). Prefer the --static form (PC_BFD_STATIC_*)
   when available since libbfd is typically a static archive and
   we need Libs.private deps too.

2. Otherwise, collect every transitive dep libbfd is known to need
   on modern binutils -- iberty, zstd, sframe, intl, dl -- via
   find_library, and pass all that exist to the link line
   unconditionally. --as-needed (Linux default) drops shared libs
   that don't satisfy any reference; unused static archives
   contribute nothing. So over-linking is harmless on systems
   that don't need it, and load-bearing on those that do.

The combinatorial probe is gone entirely. It was always guessing
what libbfd's transitive deps are; on a system where binutils-devel
is installed we can just *enumerate* them.

Reproduced on stock OpenSuse Tumbleweed in docker:
    /usr/bin/ld.bfd: /usr/lib64/libbfd.a(compress.o): undefined
        reference to symbol 'ZSTD_compress'
    /usr/bin/ld.bfd: /usr/lib64/libzstd.so.1: error adding symbols:
        DSO missing from command line
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
…nfig

Reported by @mrjimenez on amule-project#487 (post-merge): on OpenSuse Tumbleweed,
amulecmd fails to link against libbfd.a with undefined references
to ZSTD_compress (libzstd) and htab_*/objalloc_* (libiberty).
Static libbfd needs zstd/sframe/iberty as transitive deps on modern
binutils, but the probe-loop approach in cmake/bfd.cmake was unable
to discover the right combination -- its toy bfd_errmsg probe
linked fine with -lbfd alone on every system, even when the real
aMule link drags in objects from libbfd that need decompression /
hashtable / objalloc helpers. Even after reworking the probe to
call the same bfd functions MuleDebug.cpp uses in production
(bfd_find_nearest_line / bfd_map_over_sections / etc.), the small
test program still linked successfully with libbfd alone -- those
functions don't always pull in the same archive members ld picks
up when amulecmd's full link line is in flight.

Replaced with a two-tier strategy:

1. Try pkg-config first (some distros ship bfd.pc with the full
   transitive LIBS string already enumerated; when present that's
   the cleanest path). Prefer the --static form (PC_BFD_STATIC_*)
   when available since libbfd is typically a static archive and
   we need Libs.private deps too.

2. Otherwise, collect every transitive dep libbfd is known to need
   on modern binutils -- iberty, zstd, sframe, intl, dl -- via
   find_library, and pass all that exist to the link line
   unconditionally. --as-needed (Linux default) drops shared libs
   that don't satisfy any reference; unused static archives
   contribute nothing. So over-linking is harmless on systems
   that don't need it, and load-bearing on those that do.

The combinatorial probe is gone entirely. It was always guessing
what libbfd's transitive deps are; on a system where binutils-devel
is installed we can just *enumerate* them.

Reproduced on stock OpenSuse Tumbleweed in docker:
    /usr/bin/ld.bfd: /usr/lib64/libbfd.a(compress.o): undefined
        reference to symbol 'ZSTD_compress'
    /usr/bin/ld.bfd: /usr/lib64/libzstd.so.1: error adding symbols:
        DSO missing from command line
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
cmake/bfd.cmake sets BFD_LIBRARY (with underscore + _LIBRARY suffix)
but src/CMakeLists.txt has been reading the bare ${LIBBFD} at four
target_link_libraries sites (amulecmd, amuled, amule monolithic,
amulegui). ${LIBBFD} is undefined here, so it expands to empty --
those four target_link_libraries calls have been silently linking
nothing. The variable-name mismatch predates the cmake-only
migration in amule-project#466.

The build worked anyway on most distros because libbfd's transitive
deps were either short enough that the linker auto-pulled them via
implicit search, or libbfd was a shared library whose own DT_NEEDED
entries dragged its deps in. On OpenSuse Tumbleweed (amule-project#487 follow-up
report) libbfd ships only as a static archive without bfd.pc, so
the explicit transitive deps cmake/bfd.cmake collects must actually
reach the link line for the build to succeed.
got3nks added a commit to got3nks/amule that referenced this pull request Apr 27, 2026
…nfig

Reported by @mrjimenez on amule-project#487 (post-merge): on OpenSuse Tumbleweed,
amulecmd fails to link against libbfd.a with undefined references
to ZSTD_compress (libzstd) and htab_*/objalloc_* (libiberty).
Static libbfd needs zstd/sframe/iberty as transitive deps on modern
binutils, but the probe-loop approach in cmake/bfd.cmake was unable
to discover the right combination -- its toy bfd_errmsg probe
linked fine with -lbfd alone on every system, even when the real
aMule link drags in objects from libbfd that need decompression /
hashtable / objalloc helpers. Even after reworking the probe to
call the same bfd functions MuleDebug.cpp uses in production
(bfd_find_nearest_line / bfd_map_over_sections / etc.), the small
test program still linked successfully with libbfd alone -- those
functions don't always pull in the same archive members ld picks
up when amulecmd's full link line is in flight.

Replaced with a two-tier strategy:

1. Try pkg-config first (some distros ship bfd.pc with the full
   transitive LIBS string already enumerated; when present that's
   the cleanest path). Prefer the --static form (PC_BFD_STATIC_*)
   when available since libbfd is typically a static archive and
   we need Libs.private deps too.

2. Otherwise, collect every transitive dep libbfd is known to need
   on modern binutils -- iberty, zstd, sframe, intl, dl -- via
   find_library, and pass all that exist to the link line
   unconditionally. --as-needed (Linux default) drops shared libs
   that don't satisfy any reference; unused static archives
   contribute nothing. So over-linking is harmless on systems
   that don't need it, and load-bearing on those that do.

The combinatorial probe is gone entirely. It was always guessing
what libbfd's transitive deps are; on a system where binutils-devel
is installed we can just *enumerate* them.

Reproduced on stock OpenSuse Tumbleweed in docker:
    /usr/bin/ld.bfd: /usr/lib64/libbfd.a(compress.o): undefined
        reference to symbol 'ZSTD_compress'
    /usr/bin/ld.bfd: /usr/lib64/libzstd.so.1: error adding symbols:
        DSO missing from command line
mrjimenez pushed a commit that referenced this pull request Apr 27, 2026
cmake/bfd.cmake sets BFD_LIBRARY (with underscore + _LIBRARY suffix)
but src/CMakeLists.txt has been reading the bare ${LIBBFD} at four
target_link_libraries sites (amulecmd, amuled, amule monolithic,
amulegui). ${LIBBFD} is undefined here, so it expands to empty --
those four target_link_libraries calls have been silently linking
nothing. The variable-name mismatch predates the cmake-only
migration in #466.

The build worked anyway on most distros because libbfd's transitive
deps were either short enough that the linker auto-pulled them via
implicit search, or libbfd was a shared library whose own DT_NEEDED
entries dragged its deps in. On OpenSuse Tumbleweed (#487 follow-up
report) libbfd ships only as a static archive without bfd.pc, so
the explicit transitive deps cmake/bfd.cmake collects must actually
reach the link line for the build to succeed.
mrjimenez pushed a commit that referenced this pull request Apr 27, 2026
…nfig

Reported by @mrjimenez on #487 (post-merge): on OpenSuse Tumbleweed,
amulecmd fails to link against libbfd.a with undefined references
to ZSTD_compress (libzstd) and htab_*/objalloc_* (libiberty).
Static libbfd needs zstd/sframe/iberty as transitive deps on modern
binutils, but the probe-loop approach in cmake/bfd.cmake was unable
to discover the right combination -- its toy bfd_errmsg probe
linked fine with -lbfd alone on every system, even when the real
aMule link drags in objects from libbfd that need decompression /
hashtable / objalloc helpers. Even after reworking the probe to
call the same bfd functions MuleDebug.cpp uses in production
(bfd_find_nearest_line / bfd_map_over_sections / etc.), the small
test program still linked successfully with libbfd alone -- those
functions don't always pull in the same archive members ld picks
up when amulecmd's full link line is in flight.

Replaced with a two-tier strategy:

1. Try pkg-config first (some distros ship bfd.pc with the full
   transitive LIBS string already enumerated; when present that's
   the cleanest path). Prefer the --static form (PC_BFD_STATIC_*)
   when available since libbfd is typically a static archive and
   we need Libs.private deps too.

2. Otherwise, collect every transitive dep libbfd is known to need
   on modern binutils -- iberty, zstd, sframe, intl, dl -- via
   find_library, and pass all that exist to the link line
   unconditionally. --as-needed (Linux default) drops shared libs
   that don't satisfy any reference; unused static archives
   contribute nothing. So over-linking is harmless on systems
   that don't need it, and load-bearing on those that do.

The combinatorial probe is gone entirely. It was always guessing
what libbfd's transitive deps are; on a system where binutils-devel
is installed we can just *enumerate* them.

Reproduced on stock OpenSuse Tumbleweed in docker:
    /usr/bin/ld.bfd: /usr/lib64/libbfd.a(compress.o): undefined
        reference to symbol 'ZSTD_compress'
    /usr/bin/ld.bfd: /usr/lib64/libzstd.so.1: error adding symbols:
        DSO missing from command line
got3nks pushed a commit to got3nks/amule that referenced this pull request Jul 23, 2026
…mule-project#487)

* feat(gui): scalable SVG icons for toolbar and preferences on hi-DPI

The toolbar and Preferences page-list icons were fixed-size raster art
(32x32 / 16x16) embedded in the executable. Because the GUI is
per-monitor-DPI aware, those bitmaps were drawn at their physical pixel
size and looked tiny and blurry on 4K and other hi-DPI screens. This
migrates them to resolution-independent SVG so wx rasterizes each icon
crisply at whatever logical size / DPI the widget requests.

Pipeline:
- embed_icons.py now embeds each icon's optional same-name .svg twin
  next to its PNG. AMuleIconEntry gains svg_data/svg_len. The PNG stays
  mandatory (raster fallback and natural size); an .svg with no .png
  twin is a build error.
- CamuleArtProvider::CreateBitmapBundle() serves an SVG-backed
  wxBitmapBundle via wxBitmapBundle::FromSVG() when wx has SVG support
  (wxHAS_SVG), and otherwise falls back to the PNG plus a smooth 2x
  upscale. A malformed/unsupported SVG also degrades to the PNG path.
- The main toolbar (Add_Skin_Icon) and the Preferences page list request
  bundles from the art provider; an active user skin still takes
  precedence and keeps its own PNG art.
- CMake globs *.svg alongside *.png for the generated table; the
  checked-in icon_data.c fallback (used only when Python3 is absent at
  configure time) is regenerated to match.

Artwork:
- 28 toolbar/preferences icons redrawn as flat, NanoSVG-compatible SVGs
  (shapes/paths/gradients only), plus an SVG for the IP2Country pin. The
  Linux Tux (Directories) reuses the Crystal Project penguin and the
  Events mule follows the eMule mascot.

Notes for reviewers:
- Requires wx >= 3.2 (already the project minimum). NanoSVG is on by
  default in wx's CMake and autotools builds; without it the icons fall
  back to the embedded PNGs, so nothing breaks.
- The generic wxListCtrl on wxGTK/wxOSX only selects the hi-res
  rendition from wx 3.3; wxMSW uses it from 3.2.
- Licensing: the Tux is Crystal Project (LGPL, Everaldo); the mule
  follows the eMule project logo -- please confirm attribution suits the
  project before merge.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): use nullptr in CamuleArtProvider::CreateBitmapBundle

clang-tidy Tier-2 (modernize-use-nullptr) flagged the two NULL
comparisons on the newly added lines. Switch them to nullptr.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): address review feedback on the SVG icon path

- Add_Skin_Icon: fold the toolbar art id with the existing
  CCtypeAsciiScope RAII helper (pins LC_CTYPE to "C") plus
  wxString::Lower(), instead of a hand-rolled ASCII loop. Matches the
  locale-safe country-code lowercasing in MaxMindDBDatabase.cpp that
  feeds the same CamuleArtProvider.
- CamuleArtProvider::CreateBitmapBundle: in the PNG fallback, derive
  both the 1x and 2x renditions from the original decoded image so each
  is a single high-quality resample, instead of building the 2x from
  the already-rescaled 1x (scale-of-a-scale).

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* docs(gui): credit Crystal Project Tux (LGPL 2.1) for the Directories icon

The Preferences "Directories" icon embeds the Tux penguin from the
Crystal Project icon set (Everaldo Coelho, LGPL v2.1). LGPL 2.1 §6(c)
requires the credit to appear among the copyright notices shown to the
user, so add it to the About dialog (untranslated, alongside the
existing notices) and document the component in docs/THIRDPARTY.md next
to the picojson / muleunit entries.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): original folder art for Directories icon, drop icon attribution

The Preferences "Directories" icon was redrawn from the Crystal Project
Tux (LGPL v2.1), which obliged a permanent in-app copyright notice plus a
THIRDPARTY.md entry and license reference for a single icon. Per reviewer
feedback (amule-project#487) that is disproportionate, so replace it with original,
hand-drawn art that carries no third-party derivation:

- src/icons/prefs_directories.svg: original amber folder glyph, NanoSVG-safe
- src/AboutDialog.cpp: drop the Crystal Project credit line
- docs/THIRDPARTY.md: drop the "Crystal Project icons" section
- src/icons/icon_data.c: regenerate (Directories SVG twin updated)

The Events icon keeps the eMule mascot: it is GPL-consistent with aMule
(which is itself based on eMule) and carries no separate attribution.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): redraw Events icon as original bell glyph

Following the same reviewer feedback (amule-project#487), replace the Events icon —
previously traced from the eMule mascot — with an original notification
bell drawn from scratch, so the icon tree carries no derived art at all
and needs no attribution.

- src/icons/prefs_events.svg: original bell glyph, NanoSVG-safe
- src/icons/icon_data.c: regenerate (Events SVG twin updated, ~91KB -> ~0.7KB)

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): align Events raster fallback with the bell SVG

The Events SVG became a bell in 6989700, but its PNG twin
(prefs_events.png) still held the old eMule mascot — so the raster
fallback path and any non-SVG build still rendered the mascot. Replace
the PNG with the bell so the Events icon is the bell across every render
path.

- src/icons/prefs_events.png: bell raster (was the eMule mascot)
- src/icons/icon_data.c: regenerate

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): align Directories raster fallback with the folder SVG

Same fix as the Events bell: the Directories SVG is the folder, but its
PNG twin still held the old penguin, so the raster fallback path and
non-SVG builds still rendered the penguin. Replace the PNG with the
folder so Directories is consistent across every render path.

- src/icons/prefs_directories.png: folder raster (was the old penguin)
- src/icons/icon_data.c: regenerate

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* feat(gui): scalable SVG icons for the main-window status glyphs

Migrate the remaining hand-pixelled main-window images to the SVG art
pipeline: the status bar (log "i", users, up/down speed arrows and the
eD2k/Kad connection globe), the transfer window's clear-completed check
(+ its disabled state) and the show/hide-sources chevron toggles.

- src/icons/: 18 new icons. Each PNG twin is the original bitmap,
  extracted from muuli_wdr.cpp's embedded RGB/XPM data, so the raster
  fallback stays pixel-identical to today's art; each SVG is a
  hand-drawn remaster. The globe keeps the original composition
  scheme -- a base globe plus one overlay arrow per network state --
  with identical arrow geometry across base and overlays so the
  overlays cover the base exactly at any raster scale.
- muuli_wdr.cpp: the status bar and transfer window widgets take
  their art from wxArtProvider bundles ("amule:" ids); the now-unused
  dlStatusImages()/connImages() image tables are removed.
- amuleDlg.cpp: ShowConnectionState composes the globe from bundles
  rasterized at the window's DPI scale (GetBitmapFor), replacing the
  wxImageList overlay draw onto the widget's current bitmap;
  ShowTransferRate picks the speed-state art id directly.
- TransferWnd/SharedFilesWnd: the sources-list toggles use the
  bundle-aware SetBitmapPressed/SetBitmapCurrent setters (the legacy
  SetBitmapSelected/SetBitmapHover aliases are wxBitmap-only).

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* style: clang-format the new status-glyph code in amuleDlg.cpp

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): rework main-window status glyphs (curved conn arrows, single-avatar users, chevron arrows)

Address review feedback on the newly-added status icons:

- status_conn_*: the connection arrows are now curved arrows converging on
  the globe centre, matching the original artwork -- the Kad arrow (top-right)
  points south-west and the eD2k arrow (bottom-left, its 180-degree rotation)
  points north-east. The eD2k/Kad -> corner mapping matches the original
  (eD2k bottom-left, Kad top-right) so each network's colour lands in the
  right corner.
- status_users: a single avatar (head + torso), not two figures.
- arrows_down / arrows_up: three distinct stacked chevron-arrows instead of a
  solid tree; arrows_up is arrows_down mirrored vertically (same geometry).

SVG-only change; the PNG twins remain the extracted originals. icon_data.c
regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): second-pass rework of status glyphs (users pose, chevron sizes, one-piece globe arrows)

Further review feedback on the main-window icons:

- status_users: single figure in a 3/4 pose -- head turned to look
  down-right, a distinct bent left arm, rounded turned back -- replacing
  the flat front-facing avatar.
- arrows_down / arrows_up: three stacked triangles sized small -> medium
  -> big (biggest at the tip); the previous size order was reversed.
  arrows_up remains the vertical mirror of arrows_down.
- status_conn_*: the two network arrows are now single-piece curved
  arrows (head and body one silhouette), shorter and thicker; the globe
  gains an Africa + Europe landmass instead of abstract green blobs.

SVG-only; PNG twins stay the extracted originals. icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): third-pass status glyphs (arrow z-order, rim-anchored globe arrows, redrawn users)

- arrows_down / arrows_up: the three triangles now stack with the SMALL one
  on top (front) and the big one at the back, matching the original (whose
  internal edges show the smaller triangle in front). Sizes stay
  small->medium->big; up remains the vertical mirror of down.
- status_conn_*: each network arrow now starts at the globe rim -- Kad at the
  north-east edge, eD2k at the south-west -- and points inward, still a single
  short, thick one-piece curved arrow.
- status_users: redrawn from scratch to match the original pose -- a single
  chunky figure, small head turned to look down-right, a rounded right
  shoulder/back and a distinct left arm.

SVG-only; PNG twins unchanged. icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): polish users figure + thicker globe arrows

- status_users: redrawn as a clean, glossy person (round head + smooth
  rounded shoulders, subtle turn/arm seam) instead of the lumpy silhouette.
- status_conn_*: thicker one-piece arrows (chunkier head and body).
- status_conn_base: pull the globe's top highlight fully inside the rim.

SVG-only; PNG twins unchanged. icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): supplied curved arrow for the connection globe + front-facing users

- status_conn_*: adopt the user-supplied curved-arrow artwork, baked into
  16x16 coordinates (no transform attribute, NanoSVG-safe). Kept the NE (Kad)
  / SW (eD2k) positions and the inward-pointing direction; recoloured per
  state (red/yellow/orange/green with a darker outline) in place of black.
- status_users: redrawn front-facing with both arms -- head, torso and two
  arms, kept the glossy green look.

SVG-only; PNG twins unchanged. icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): trim users bust to arm height; stop clear-completed check being clipped

- status_users: cut the torso flush with the bottom of the arms (a head-and-
  shoulders bust) instead of a long body.
- transfer_clear_completed(+_disabled): inset the tick so it keeps a margin
  inside its viewBox.
- muuli_wdr.cpp: the clear-completed button had collapsed toward the bitmap's
  best size (clipping the tick); give it a fixed 34x34 min size so the icon
  is no longer cut off.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): compose the connection globe into a private bitmap

ShowConnectionState drew the Kad/eD2k overlay arrows straight into the
bitmap returned by GetBitmapBundle("amule:status_conn_base").GetBitmapFor().
wxArtProvider caches that bundle and wxBitmapBundleImplSVG caches its
rasterized bitmap, handing it back copy-on-write; a wxMemoryDC draws into
the shared pixel buffer without unsharing it. So the overlays were being
stamped into the cached base globe and accumulated on every later state
change (and poisoned the base for any other consumer of the bundle).

Deep-copy the base into a private bitmap (preserving the DPI scale factor)
before compositing the overlays onto it.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): un-clip the connection plug-cord; guard the embed generator

The red plug cable in prefs_connection.svg and its twin toolbar_connect.svg
dipped past the 0 0 32 32 viewBox (the 3.4-wide stroke reached y~=33.7), so
its rounded tip was clipped flat against the icon's bottom edge. Raise the
lower curve of both cord strokes to keep the whole stroke within bounds, and
regenerate icon_data.c for the two updated SVGs.

Also harden embed_icons.py: error out if two icons resolve to the same art
id or C identifier. sanitise() folds '-'/'.' to '_', so distinct names could
silently collide into a duplicate C symbol; not triggered by the current
icon set, but a future rename now fails loudly at generation time.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(gui): size the connection globe to match the other status icons

wxBitmapBundle::GetBitmapFor() returns an *unscaled* bitmap (scale factor
1.0) whose pixel size already matches the window DPI. Setting the composed
globe on the status-bar wxStaticBitmap as-is rendered it DPI-scale times
larger than the sibling icons (info, users, speed), which are bundle-backed
and size themselves in logical units -- clearly oversized on hi-DPI displays.

Stamp the window's DPI scale factor on the composite so its logical size
matches the siblings (a no-op at 100% DPI). Verified in-app at hi-DPI: the
globe now measures the same height as the users/speed icons.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): spread the connection-globe overlay arrows apart

Review feedback on amule-project#487: the Kad (NE) and eD2k (SW) overlay arrows sat
so close together that the composited globe read a little messy -- the
red arrow head collided with the green arrow tail near the centre.

Push each arrow outward along the NE-SW diagonal and shrink it a touch
(anchor 11.0,4.9 -> 11.5,4.35; scale 0.015 -> 0.0132, mirrored for
eD2k), tripling the gap between them (~1.2 -> ~3.3 units of 16) while
keeping the full stroke inside the 16x16 viewBox. Base + all seven
overlay SVGs move in lockstep so every state composites correctly;
icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): brighten the connection globe for dark status bars

Review feedback on amule-project#487: the composited connection glyph read dimmer
than the old raster art, especially on a dark status bar -- the navy
sea gradient sank into the bar and the flat arrow fills with heavy dark
outlines dimmed the arrows at 16px.

Brighten the sea gradient (#8fd0ff -> #3e8ce0 -> #1156a0) and the
continents, strengthen the polar gloss, and fill the arrows with a lit
gradient (pale highlight -> base -> deep shade, light from the
top-left like the old art) behind a thinner outline. Measured at 16px
against the old raster composite, mean luminance goes 89 -> 123 (old:
103) and bright-pixel share 19% -> 34% (old: 32%).

Each file's gradient ids are now unique across the set: NanoSVG parses
files standalone so it never cared, but inlining several conn SVGs into
one document (previews, galleries) had the browser resolving every
url(#arr) against the first file's gradient.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): brighten the up/down speed arrows to match the old raster

Follow-up to the connection-globe recolor (review feedback on amule-project#487, and
the old raster art was brighter): the speed glyph's black outlines,
dark-grey shafts and half-dark gradient dimmed it -- 16px mean
luminance 60 vs the old raster's 74.

Reuse the lit palette from the globe arrows (pale highlight -> base ->
deep shade, light from the top-left) for the green/red heads, colour
the outlines with each head's deep tone instead of black, and lighten
the shafts to the old art's mid-grey. Measures 110 after (old: 74).
Geometry is untouched; gradient ids are unique per file like the conn
set. icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): enlarge the users figure to the old raster's footprint

Review feedback on amule-project#487: next to the old raster the users glyph read
dimmer and smaller. It was mostly size: the old figure fills a 14x16
box with 66% pixel coverage, the SVG bust only 10x13 at 37% -- brighter
per pixel yet emitting a third less light overall.

Scale the figure up to the same 14x16 footprint (shoulders broadened a
touch toward the old proportions), which brings the emitted light to
within 5% of the raster. Design is unchanged: front-facing bust, both
arms, cut at arm height. icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): size the speed arrows to the old raster's footprint

Review feedback on amule-project#487: alongside the brightness pass, the up/down
glyph also read a bit smaller than the raster art. The old arrowheads
are 9px wide with 3px stems; the SVG had 8.6-unit heads and ~2.1-unit
shafts, so the glyph carried less visual weight at status-bar size.

Widen the heads to 9.2 units and the shafts to 2.5 (+0.4 outline ~ the
old stems' 3px), keeping every stroke inside the 16x16 viewBox. At 16px
the glyph now covers 89px vs the raster's 74 with the same 14x16-ish
footprint. icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): redraw the connection-globe arrows by hand, bigger and bolder

Review feedback on amule-project#487 asked for larger, clearer overlay arrows on the
composite network glyph. After several parameterised iterations of the
previous curved arrow, the arrows were redrawn by hand in an SVG editor
over the globe base: two bold swoosh arrows cycling around the globe,
tails toward the NE/SW corners, heads interlocking near the centre.

The editor output placed them via CSS transform-box/transform-origin,
which browsers honour but NanoSVG ignores, so every transform is baked
into absolute path coordinates. The SW arrow is the exact 180-degree
point reflection of the NE arrow, both arrows share the icon set's
top-left-lit gradient, and the pair sits 0.7 units outward from the
initial draft so the canvas margins stay balanced. The globe's
continents/gloss tweaks from the same edit are kept. All seven state
overlays are regenerated from the same geometry; icon_data.c updated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* feat(icons): real continents on the connection globe

Replace the three hand-drawn continent blobs with actual coastlines
extracted from a proper Earth-globe SVG (Americas, Europe/Africa/Asia,
northern islands), baked through the source's full transform chain into
plain NanoSVG-safe paths and remapped onto our globe so coastlines that
touch the source's circle meet the rim's border line. All landmasses
share one uniform green, and the polar gloss is dropped -- the flatter,
detailed globe reads better at status-bar size. icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): contrast pass on the connection glyph (review feedback)

got3nks: the red arrows read well, but green and yellow blend into the
globe. Give every overlay arrow a bolder outline (stroke 0.4 -> 0.6)
and darken the green/yellow/orange outline tones so the boundary does
the work the hue cannot; red keeps its outline colour. Lighten the
globe's rim (#0d3b6e -> #1a5da8) so the darkest edges in the icon are
the arrows, not the border -- the arrows now lead the composition.
icon_data.c regenerated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): enlarge the connection-globe arrows (review feedback)

got3nks on macOS: the overlay arrows are still hard to read at
status-bar size; bigger is the reliable fix. The arrows were enlarged
by hand in the SVG editor, then normalized: the SW arrow is the exact
180-degree point reflection of the NE one, and the pair is balanced to
an isometric 14.8x14.8 footprint with equal 0.30 canvas margins on all
four sides -- the arrows now use practically the whole 16x16 box. All
seven state overlays regenerated from the same geometry; editor cruft
(style attributes) stripped; icon_data.c updated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): bigger arrow heads on the connection glyph (review feedback)

got3nks compared the SVG glyph against the original raster side by side:
the old art's arrows are bolder and larger, and asked for the SVG to
match. Rework the arrows with substantially bigger chevron heads and
shorter bodies (hand-drawn in the SVG editor), normalized as before:
the SW arrow is the exact 180-degree reflection of the NE one, and the
pair is balanced to an isometric 14.84x14.84 footprint with equal 0.28
canvas margins. All seven state overlays regenerated from the same
geometry; icon_data.c updated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

* fix(icons): bigger, brighter connection arrows + toned-down globe

Further legibility pass from the review thread (bigger arrow bodies,
higher contrast). Scale the whole arrow up ~10% about its centroid so
both head and body grow -- the pair now fills a 15.2x15.2 footprint
with the heads reaching the canvas edge and the tails pulled inward.
Brighten the arrow fills (lift the gradient's base/deep stops; keep the
dark outlines for the edge), and tone the globe down a notch (sea,
continents and rim each moved partway toward a muted blue-green) so the
arrows carry the icon. Symmetry/isometry preserved: SW arrow is the
exact 180-degree reflection of NE, equal canvas margins. All seven
overlays regenerated; icon_data.c updated.

Co-Authored-By: Claude Opus 4.8 <[email protected]>

---------

Co-authored-by: Carlos Barrero <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
mrjimenez pushed a commit to mrjimenez/amule that referenced this pull request Aug 1, 2026
…or tab-close (amule-project#675) (amule-project#735)

* feat(gui): migrate Friends/Messages headers, reload buttons, folder tree, and tab-close icons to CamuleArtProvider

Continues the icon-system cleanup scoped in amule-project#675, independent of
amule-project#732/amule-project#733 (different files, no overlap).

- amuleDlgImages(14)/(15): the small header icons in the Friends and
  Messages tabs. Friends gets a new "amule:friends" SVG; Messages
  reuses the existing "amule:toolbar_messages" art, requested at an
  explicit 16x16 so it doesn't inherit the toolbar's 32x32 natural
  size.
- amuleDlgImages(18)/(30): the "reload list" buttons (shared files,
  ED2K server list, Kad node list) -- three call sites, one new
  "amule:reload" SVG (see below for its own history).
- amuleSpecial(1)/(2): the shared-directory tree's folder icons get
  new "amule:folder"/"amule:folder_shared" SVGs -- same shape, tinted
  orange vs. red, matching how the original raw bitmaps only differed
  by colour.
- amuleSpecial(3)/(4): the chat/search notebook tabs' close-on-hover
  icon, replaced with wx's own stock wxART_CLOSE for both states
  instead of a second bespoke asset (both were the same "X in a box"
  bitmap, differing only by a hover-highlight border colour).

reload.svg's own history, per PR review: the first hand-drawn attempt
(thin blue single arc) didn't match the original at all -- got3nks
caught it, I reconstructed the original amuleDlgImages(18) raster to
check (a thicker green double-arrow circle) and redrew closer to that,
which still wasn't good enough. Final version is AI-vectorized via
Recraft (through the Higgsfield MCP), which got3nks preferred over
further hand-drawn iterations.

src/icons/icon_data.c (the checked-in fallback used when Python3 is
absent at configure time, per amule-project#487) regenerated via embed_icons.py to
match.

Rebased onto current master (picking up amule-project#732/amule-project#733/amule-project#739, which all
touch the same amuleSpecial/amuleDlgImages functions) -- conflicts
resolved by redoing the index deletions against the current tree
rather than replaying the stale patch, since amule-project#725/amule-project#733 already moved
the surrounding line numbers.

Verified via a full amule build (macOS) and a visual check of every
call site: Friends/Messages tab headers, the ED2K server-list and Kad
node-list reload buttons, the shared-files reload button, and the
Preferences > Directory shared-folder tree.

* fix(gui): thicker reload stroke, dedicated message-bubble icon (amule-project#735 review)

got3nks, testing amule-project#735:
- reload: arrow bodies read too thin at 16px. Regenerated via Recraft
  with an explicit thicker/bolder-stroke prompt.
- Messages panel header: reusing "amule:toolbar_messages" (the main
  toolbar's detailed gradient mascot bust) at 16x16 doesn't read as
  "messages" once shrunk that far from its 32x32 native size. Added a
  dedicated "amule:message" chat-bubble glyph instead, sized for
  legibility at 16x16 specifically, and pointed the Messages panel
  header at it instead of the toolbar art.

Folder/folder_shared and the tab-close X were already approved as-is.

Verified via a full amule build (macOS) and a visual check of both
fixes: the shared-files reload button and the Messages panel header.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bfd.cmake error - unset called with incorrect number of arguments

3 participants