forked from amule-project/amule
-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
692 lines (634 loc) · 27.7 KB
/
Copy pathCMakeLists.txt
File metadata and controls
692 lines (634 loc) · 27.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
cmake_minimum_required (VERSION 3.10...3.31)
project (amule)
set (MIN_BOOST_VERSION 1.70)
set (MIN_CRYPTOPP_VERSION 8.1)
set (MIN_GDLIB_VERSION 2.0.0)
set (MIN_WX_VERSION 3.2.0)
set (PACKAGE "amule")
set (PACKAGE_BUGREPORT "[email protected]")
set (PACKAGE_NAME "aMule")
set (PACKAGE_STRING "aMule GIT")
set (PACKAGE_TARNAME "amule")
set (PACKAGE_URL \"\")
set (PACKAGE_VERSION "GIT")
set (VERSION "GIT")
set (DEFAULT_BUILD_TYPE "Release")
set (RECONF_COMMAND ${CMAKE_COMMAND})
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Set the possible values of build type for cmake-gui
if (CMAKE_CONFIGURATION_TYPES)
set (CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE
STRING "Semicolon separated list of supported configuration types, only supports debug and release, anything else will be ignored" FORCE
)
set_property (CACHE CMAKE_CONFIGURATION_TYPES PROPERTY STRINGS
"Debug" "Release"
)
endif()
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message (STATUS "Setting build type to '${DEFAULT_BUILD_TYPE}' as none was specified.")
set (CMAKE_BUILD_TYPE "${DEFAULT_BUILD_TYPE}" CACHE
STRING "Choose the type of build." FORCE
)
endif()
# ccache auto-detection (AUTO = use if found, ON = require, OFF = skip).
# Distros that run their own ccache wrapper (FreeBSD ports, Gentoo, etc.)
# should pass -DENABLE_CCACHE=OFF so we don't double-wrap the compiler.
set (ENABLE_CCACHE "AUTO" CACHE STRING "Use ccache compiler launcher (AUTO/ON/OFF)")
set_property (CACHE ENABLE_CCACHE PROPERTY STRINGS "AUTO" "ON" "OFF")
if (NOT ENABLE_CCACHE STREQUAL "OFF")
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
message(STATUS "ccache found: ${CCACHE_PROGRAM}")
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}")
elseif (ENABLE_CCACHE STREQUAL "ON")
message(FATAL_ERROR "ccache requested via -DENABLE_CCACHE=ON but not found")
else()
message(STATUS "ccache not found.")
endif()
endif()
include (cmake/CmDaB.cmake)
include (cmake/manpage_install.cmake)
include (cmake/options.cmake)
include (cmake/search-dirs.cmake)
if (BUILD_AMULECMD OR BUILD_WEBSERVER)
include (cmake/FindReadline.cmake)
endif()
if (BUILD_CAS)
include (cmake/gdlib.cmake)
include (cmake/getopt_long.cmake)
endif()
if (BUILD_WEBSERVER OR NEED_ZLIB)
include (cmake/zlib.cmake)
endif()
if (BUILD_WEBSERVER)
include (cmake/png.cmake)
endif()
include (cmake/boost.cmake)
if (ENABLE_IP2COUNTRY)
include (cmake/ip2country.cmake)
endif()
if (ENABLE_NLS)
include (cmake/nls.cmake)
endif()
if (ENABLE_UPNP)
include (cmake/upnp.cmake)
endif()
if (NEED_GLIB_CHECK)
include (cmake/glib21.cmake)
endif()
if (NEED_LIB_CRYPTO)
include (cmake/cryptopp.cmake)
endif()
if (wx_NEEDED)
include (cmake/wx.cmake)
endif()
#
# GITDATE is consumed by config.h.cm (#define GITDATE "...") and
# version.rc.in (Windows version resource), and ends up in the binary's
# `--version` output and the amuled startup banner.
#
# Two modes:
# * Distro packagers building from a tarball (no .git) pass
# -DGITDATE="rev. foo" on the cmake command line. That value lands
# in the cache and is respected here unconditionally.
# * Source builds derive the value from `git describe` on EVERY
# configure so subsequent commits show up in the banner without a
# full reconfigure. The previous code wrapped this in
# `if (NOT GITDATE)` and stored the result with `CACHE STRING FORCE`,
# which froze the value at the first configure forever — every
# incremental rebuild thereafter embedded the stale revision string.
#
# CMAKE_CONFIGURE_DEPENDS makes the build system re-run cmake when the
# git state changes, so `cmake --build` alone is enough to pick up new
# commits in the banner.
#
# We need three files, not just HEAD:
# * HEAD — touched on `git checkout <branch>` (symref retarget),
# `git checkout --detach`, and explicit `git update-ref HEAD ...`.
# * the branch-ref file (refs/heads/<branch>) that HEAD points at —
# touched on `git commit`, `git reset --hard`, `git pull --ff-only`,
# and any other op that moves the branch tip. Tracking only HEAD
# misses these because HEAD is a symref text file, not the SHA itself.
# * packed-refs — touched by `git gc` / `git pack-refs`, which can
# consolidate the branch ref file out of existence. After a pack,
# the SHA lives only in packed-refs.
#
# Where those three live is a question for git, not an assumption about
# the directory layout — see the resolution step further down.
#
if (NOT DEFINED CACHE{GITDATE})
find_package (Git)
if (GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
execute_process (
COMMAND ${GIT_EXECUTABLE} describe
OUTPUT_VARIABLE GIT_INFO_WC_REVISION
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE GIT_INFO_RESULT
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
if (GIT_INFO_RESULT EQUAL 0 AND GIT_INFO_WC_REVISION)
set (GITDATE "rev. ${GIT_INFO_WC_REVISION}")
message (STATUS "git revision ${GITDATE} found")
endif()
# When HEAD sits exactly on a tag, override the GIT placeholder
# set above with the tag name so artifact filenames, the About
# dialog, the tray menu label, and the Windows version resource
# all reflect the release. Tagless builds keep "GIT" — the
# existing dev marker. The AMULE_TAGGED_RELEASE flag is also
# forwarded to config.h so ClientVersion.h can suppress the
# __GIT__ marker on releases.
execute_process (
COMMAND ${GIT_EXECUTABLE} describe --tags --exact-match HEAD
OUTPUT_VARIABLE GIT_TAG
OUTPUT_STRIP_TRAILING_WHITESPACE
RESULT_VARIABLE GIT_TAG_RESULT
ERROR_QUIET
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
if (GIT_TAG_RESULT EQUAL 0 AND GIT_TAG)
set (VERSION "${GIT_TAG}")
set (PACKAGE_VERSION "${GIT_TAG}")
set (PACKAGE_STRING "aMule ${GIT_TAG}")
set (AMULE_TAGGED_RELEASE 1)
# Suppress the "(Snapshot: ...)" trailer that
# MuleVersion.h's `#ifdef GITDATE` gate appends to
# GetMuleVersion(). On a tagged build the GITDATE the
# earlier git-describe block produced ("rev. <tag>")
# would render as "Initialising aMule <tag> ...
# (Snapshot: rev. <tag>)" — both redundant and
# inaccurate, since a tagged release isn't a snapshot.
# Pairs with the `#define` → `#cmakedefine` change in
# config.h.cm so an unset GITDATE yields `#undef
# GITDATE` instead of `#define GITDATE ""`, which
# otherwise leaves the empty parens in place.
unset (GITDATE)
message (STATUS "building tagged release: ${PACKAGE_STRING}")
endif()
else()
# No `.git` directory. If we're sitting in an extracted git
# archive — e.g. GitHub's "Download ZIP" button on a tag or
# commit, or a tarball someone produced via `git archive` —
# `.git_archival.txt` will exist with its `$Format:...$`
# placeholders substituted to the actual SHA / tag / describe
# output. Parse it as a fallback so the resulting binary
# self-identifies the same way a `.git`-present clone of the
# same commit would. See `.gitattributes` for the
# `export-subst` binding that triggers the substitution.
set (_archival_file "${CMAKE_SOURCE_DIR}/.git_archival.txt")
if (EXISTS "${_archival_file}")
file (READ "${_archival_file}" _archival_content)
# Skip un-substituted templates: a working-tree copy
# of the file (someone tar'd up `src/` without running
# `git archive`) still contains literal `$Format:`
# markers. These are the signal that `git archive`
# never touched the file — fall through to defaults.
if (NOT _archival_content MATCHES "\\\$Format:")
string (REGEX MATCH "describe-name:[ \t]*([^\r\n]+)" _ "${_archival_content}")
set (_describe "${CMAKE_MATCH_1}")
string (STRIP "${_describe}" _describe)
if (_describe)
# `git describe --tags` output:
# - exact-tag: just the tag name ("3.0.0", "v3.0.0")
# - off-tag: "<tag>-<N>-g<sha>" ("2.3.3-296-ge3f87f77f")
# Detect the off-tag form by the `-N-g<hex>`
# trailer; otherwise treat as a tagged release.
if (_describe MATCHES "-[0-9]+-g[0-9a-f]+$")
set (GITDATE "rev. ${_describe}")
message (STATUS "git archival metadata: ${GITDATE} found")
else()
set (VERSION "${_describe}")
set (PACKAGE_VERSION "${_describe}")
set (PACKAGE_STRING "aMule ${_describe}")
set (AMULE_TAGGED_RELEASE 1)
message (STATUS "git archival metadata: tagged release ${PACKAGE_STRING}")
endif()
endif()
endif()
endif()
endif()
# Depend on .git_archival.txt so that if it's swapped in
# (e.g. someone re-extracts an archive, or hand-edits the file),
# cmake re-runs and re-parses on the next build.
if (EXISTS "${CMAKE_SOURCE_DIR}/.git_archival.txt")
set_property (DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${CMAKE_SOURCE_DIR}/.git_archival.txt")
endif()
#
# `${CMAKE_SOURCE_DIR}/.git` is a directory only in a plain clone. In
# a linked worktree (`git worktree add`) — and in a submodule — it is
# a *file* holding a `gitdir:` pointer, so every path built by
# appending to it resolves to nothing. The EXISTS guards below then
# quietly skip every dependency and the auto-refresh this whole block
# exists for stops happening: the revision string stays frozen at
# whatever the first configure saw, with no diagnostic. Ask git for
# the real locations instead of assuming the layout:
#
# * --git-dir the per-worktree directory. Owns HEAD.
# * --git-common-dir the shared directory. Owns refs/heads/* and
# packed-refs, which linked worktrees do not
# get private copies of.
#
# The two are the same path in a plain clone and diverge in a
# worktree, which is exactly why both are needed — tracking only one
# would miss either the branch retarget or the branch tip moving.
# Resolution is scoped to the `.git`-at-source-root case on purpose:
# rev-parse walks up to any enclosing repository, so running it
# unconditionally would make a tarball unpacked inside some unrelated
# checkout describe that checkout instead of falling through to the
# .git_archival.txt path above.
#
if (GIT_FOUND AND EXISTS "${CMAKE_SOURCE_DIR}/.git")
execute_process (
COMMAND ${GIT_EXECUTABLE} rev-parse --git-dir
OUTPUT_VARIABLE _amule_git_dir
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
RESULT_VARIABLE _amule_git_dir_result
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
if (NOT _amule_git_dir_result EQUAL 0)
set (_amule_git_dir "")
endif()
execute_process (
COMMAND ${GIT_EXECUTABLE} rev-parse --git-common-dir
OUTPUT_VARIABLE _amule_git_common_dir
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET
RESULT_VARIABLE _amule_git_common_dir_result
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR})
if (NOT _amule_git_common_dir_result EQUAL 0)
set (_amule_git_common_dir "")
endif()
# Both are printed relative to the working directory in a plain
# clone (literally ".git") and absolute in a worktree, so
# normalise before building paths from them.
if (_amule_git_dir)
get_filename_component (_amule_git_dir "${_amule_git_dir}"
ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}")
endif()
# --git-common-dir arrived in git 2.5; on anything older the
# option is parsed as a revision and fails. Fall back to the
# per-worktree directory, which is the correct answer for every
# layout that old a git can produce.
if (_amule_git_common_dir AND NOT _amule_git_common_dir STREQUAL "--git-common-dir")
get_filename_component (_amule_git_common_dir "${_amule_git_common_dir}"
ABSOLUTE BASE_DIR "${CMAKE_SOURCE_DIR}")
else()
set (_amule_git_common_dir "${_amule_git_dir}")
endif()
endif()
if (_amule_git_dir AND EXISTS "${_amule_git_dir}/HEAD")
set_property (DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${_amule_git_dir}/HEAD")
# Resolve HEAD's symref target so we can also depend on the
# branch ref file directly. This catches commits/resets that
# move the branch tip without retargeting HEAD. A detached HEAD
# holds the SHA inline instead, and so is already covered by the
# dependency on HEAD itself.
file (READ "${_amule_git_dir}/HEAD" _amule_head_contents LIMIT 200)
string (STRIP "${_amule_head_contents}" _amule_head_contents)
if (_amule_head_contents MATCHES "^ref: (.+)$")
set (_amule_head_ref "${CMAKE_MATCH_1}")
if (EXISTS "${_amule_git_common_dir}/${_amule_head_ref}")
set_property (DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${_amule_git_common_dir}/${_amule_head_ref}")
endif()
endif()
endif()
# Also depend on packed-refs in case the branch ref is packed
# (loose ref file may not exist after `git gc`).
if (_amule_git_common_dir AND EXISTS "${_amule_git_common_dir}/packed-refs")
set_property (DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
"${_amule_git_common_dir}/packed-refs")
endif()
endif()
# Man-page `.TH` date. `string(TIMESTAMP)` honours SOURCE_DATE_EPOCH
# automatically, so reproducible builds (Debian etc.) get a stable value.
# We assemble "Month Year" from a numeric month index so the output is
# locale-neutral (strftime's %B is locale-dependent).
#
# The value embeds its own surrounding double-quotes so the substituted
# `.TH` argument stays a single quoted field. po4a's man module elides
# the outer quotes around single-token translatable values when it
# regenerates a translated `.1.in`, so a master like
# .TH AMULE 1 "@MAN_DATE@" ...
# becomes
# .TH AMULE 1 @MAN_DATE@ ...
# in the translated copy. With the quotes carried by the value, the
# masters use the unquoted form `@MAN_DATE@` directly and the final
# substitution always lands as `"Month Year"` regardless of which file
# configure_file processed.
set (_AMULE_MONTHS January February March April May June July August
September October November December)
string (TIMESTAMP _AMULE_MAN_MONTH_NUM "%m" UTC)
math (EXPR _AMULE_MAN_MONTH_IDX "${_AMULE_MAN_MONTH_NUM} - 1")
list (GET _AMULE_MONTHS ${_AMULE_MAN_MONTH_IDX} _AMULE_MAN_MONTH)
string (TIMESTAMP _AMULE_MAN_YEAR "%Y" UTC)
set (MAN_DATE "\"${_AMULE_MAN_MONTH} ${_AMULE_MAN_YEAR}\"")
if (ENABLE_BFD)
include (cmake/bfd.cmake)
else()
set (HAVE_BFD FALSE)
message (STATUS "ENABLE_BFD=NO; skipping libbfd detection. Backtraces fall back to addr2line + backtrace_symbols().")
endif()
# DownloadBandwidthThrottler holds the shared byte budget as
# std::atomic<int64_t>. On 64-bit targets the compiler emits native
# 8-byte CAS / load / store and no library is needed. On 32-bit targets
# (PPC32, ARMv5/v6, MIPS32, some old x86 toolchains) the atomic ops
# expand to __atomic_{load,store,compare_exchange,fetch_add}_8 calls
# that live in libatomic; the link fails with
# "Undefined symbols: ___atomic_compare_exchange_8" without -latomic.
#
# We don't probe with check_cxx_source_compiles -- a tiny probe lets
# the compiler inline the lock-free expansion end-to-end and reports
# "native works" even on targets where the real codebase's cross-TU
# atomic references actually do need the library (see #643). Just
# require libatomic unconditionally on 32-bit builds.
set (LIBATOMIC "")
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
# Probe with a compiler-driven LINK test, not find_library. With GCC,
# libatomic ships inside the compiler's own runtime dir (e.g.
# .../lib/gcc14/) which is not on find_library's filesystem search
# path, so find_library false-fails even though `-latomic` links fine
# -- the GCC driver resolves its internal libatomic (MacPorts, #453).
# check_library_exists links a probe with `-latomic` through the
# compiler driver, so it succeeds wherever the flag actually links:
# GCC's internal copy, or a system libatomic (Clang / distro -dev
# packages, versioned or not). This replaces the earlier find_library
# lookup that only searched standard library paths.
include (CheckLibraryExists)
check_library_exists (atomic __atomic_load_8 "" HAVE_LIBATOMIC)
if (HAVE_LIBATOMIC)
set (LIBATOMIC atomic)
message (STATUS "32-bit target: linking libatomic for std::atomic<int64_t>")
else()
message (FATAL_ERROR
"32-bit target detected (sizeof(void*) == 4). aMule's "
"download bandwidth throttler holds the byte budget as "
"std::atomic<int64_t>; 32-bit CPUs lack a native 8-byte "
"atomic and the operations expand to library calls "
"(__atomic_*_8) that live in libatomic. libatomic was "
"not found on this system. Install it and re-run cmake:\n"
" Debian/Ubuntu/Mint: libatomic1-dev\n"
" Fedora/RHEL/Rocky/Arch: libatomic\n"
" macOS/MacPorts: bundled with gcc; install gcc14+")
endif()
endif()
# glib-2.0 headers — needed for the Wayland wl_app_id / X11 WM_CLASS
# binding via g_set_prgname() (called from amule.cpp on the monolithic
# / daemon side, and from amule-remote-gui.cpp on the amulegui side
# once the remote-GUI fix lands as a separate PR). amulecmd and
# amuleweb don't need glib. Gated on wxGTK being the wx toolkit AND
# the host not being macOS — the `#include <glib.h>` / call sit behind
# `#if defined(__WXGTK__) && !defined(__APPLE__)` in those files;
# macOS doesn't run Wayland and macOS apps identify via Info.plist, so
# the call is a no-op there even when wxGTK happens to be the toolkit
# (MacPorts wxgtk, see #641) and there's no reason to drag glib2 in.
list (FIND wxWidgets_DEFINITIONS "__WXGTK__" _amule_wxgtk_idx)
if (_amule_wxgtk_idx GREATER -1 AND NOT APPLE)
find_package (PkgConfig QUIET)
if (PkgConfig_FOUND)
# gio-2.0 (ships with glib) provides GDBus, used by the monolithic /
# amulegui GUI to ask xdg-desktop-portal for background permission
# under Flatpak (see RequestFlatpakBackgroundPermission in amuleDlg.cpp).
pkg_check_modules (GLIB QUIET glib-2.0 gio-2.0)
endif()
if ((BUILD_MONOLITHIC OR BUILD_DAEMON OR BUILD_REMOTEGUI) AND NOT GLIB_FOUND)
message (FATAL_ERROR
"glib-2.0 development headers not found, but they are "
"required to build amule (monolithic), amuled, or "
"amulegui against wxGTK — these targets call "
"g_set_prgname() to bind the Wayland wl_app_id / X11 "
"WM_CLASS to the .desktop filename, which needs "
"<glib.h>. Install one of:\n"
" - libglib2.0-dev (Debian / Ubuntu / Mint)\n"
" - glib2-devel (Fedora / RHEL / Rocky)\n"
" - dev-libs/glib (Gentoo)\n"
" - glib (Arch / Manjaro)\n"
" - glib2 (MacPorts)\n"
" - glib (Homebrew)\n"
"…then re-run cmake AFTER deleting the build directory "
"(`rm -rf build`); pkg_check_modules only runs at "
"configure time, so installing the package on top of a "
"cached configure won't help. pkg-config itself is also "
"required — install `pkg-config` if cmake didn't find it.")
endif()
endif()
unset (_amule_wxgtk_idx)
# Optional StatusNotifierItem (SNI) backend for the system-tray icon.
# wxGTK's wxTaskBarIcon talks the legacy GtkStatusIcon API, which
# GNOME Shell removed in 3.26 and modern wlroots compositors never
# implemented. Apps that need a visible tray icon on Ubuntu (with the
# AppIndicators extension), KDE Plasma, and Sway speak the SNI D-Bus
# protocol directly via libayatana-appindicator3. When the dev
# headers are present we build a SNI backend into MuleTrayIcon; on
# platforms where the library is missing (Windows, macOS, builds
# without the dep) we fall back to wxTaskBarIcon.
#
# Both GUI binaries compile MuleTrayIcon (it is in GUI_SOURCES), so the
# probe covers either of them being built — gating it on the monolithic
# build alone left a remote-GUI-only build with the invisible legacy
# backend and no way to know.
if ((BUILD_MONOLITHIC OR BUILD_REMOTEGUI) AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package (PkgConfig QUIET)
if (PkgConfig_FOUND)
# `0.1` is the API version (never bumped, every release uses it),
# not a library version pin. Try the Ayatana fork first since
# that's the maintained one; fall back to Canonical's legacy
# `appindicator3-0.1` for distros that haven't migrated yet.
# The two are API-compatible at the headers/symbols level.
pkg_check_modules (AYATANA_APPINDICATOR QUIET ayatana-appindicator3-0.1)
if (NOT AYATANA_APPINDICATOR_FOUND)
pkg_check_modules (AYATANA_APPINDICATOR QUIET appindicator3-0.1)
endif()
if (AYATANA_APPINDICATOR_FOUND)
message (STATUS "AppIndicator3 found: ${AYATANA_APPINDICATOR_MODULE_NAME} ${AYATANA_APPINDICATOR_VERSION} — tray icon uses SNI backend")
set (WITH_LIBAYATANA_APPINDICATOR ON)
else()
message (STATUS "AppIndicator3 not found (looked for ayatana-appindicator3-0.1 and appindicator3-0.1) — tray icon falls back to legacy GtkStatusIcon, invisible on modern GNOME/wlroots")
endif()
endif()
endif()
configure_file (
config.h.cm
config.h
)
if (WIN32)
configure_file (
version.rc.in
version.rc
)
# Silences 80+ CI spam lines from MSYS2 `winsock2.h:15` which prints
# `#warning Please include winsock2.h before windows.h` whenever
# <windows.h> pulls in the legacy WinSock API first. Defining
# WIN32_LEAN_AND_MEAN tells windows.h to skip that legacy include,
# leaving <winsock2.h> to be pulled in cleanly by wx headers.
# Upstream wx 3.3 does this inside wrapwin.h; wx 3.2 does not.
add_compile_definitions(WIN32_LEAN_AND_MEAN)
endif()
if (BUILD_MONOLITHIC)
# Files use the canonical AppStream / Flatpak / Wayland app id
# `org.amule.aMule`. Wayland compositors bind windows to launcher
# icons by matching wl_app_id (set via g_set_prgname() in amule's
# OnInit) against the .desktop filename without extension; the id
# also doubles as the AppStream component id and the Flatpak app id
# so AppImage, Flatpak, and distro packages all resolve to the same
# entity in software catalogs.
install (FILES org.amule.aMule.desktop
DESTINATION "${CMAKE_INSTALL_DATADIR}/applications"
)
install (FILES org.amule.aMule.png
DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/128x128/apps"
)
install (FILES org.amule.aMule-256.png
RENAME org.amule.aMule.png
DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/apps"
)
# The source the raster sizes above are rendered from. Themes and
# launchers that can scale prefer this one, and it is what the app
# stores ask for; the raster sizes stay for the ones that cannot.
install (FILES org.amule.aMule.svg
DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps"
)
endif()
if (BUILD_REMOTEGUI)
install (FILES org.amule.aMule.gui.desktop
DESTINATION "${CMAKE_INSTALL_DATADIR}/applications"
)
endif()
if (BUILD_MONOLITHIC OR BUILD_REMOTEGUI)
# Teaches the desktop what a .emulecollection is, so the MimeType= line
# in the .desktop files above can match it. Without this the file is
# sniffed as text/plain (text form) or application/octet-stream (binary
# form) and aMule never shows up in "Open With".
#
# No update-mime-database hook here: refreshing the system cache is the
# packager's job for a system install. The AppImage path has no packager
# and so does it itself, in AppImageIntegration::RefreshSystemCaches.
#
# The filename is app-id-prefixed because Flathub's linter requires
# exported files to be; flatpak exports share/mime/packages
# automatically, so the manifests need no change.
install (FILES org.amule.aMule.xml
DESTINATION "${CMAKE_INSTALL_DATADIR}/mime/packages"
)
# Icon for the file type itself. The name is mandated by the icon
# naming spec - the MIME type with '/' replaced by '-' - and without
# it file managers fall back to the generic "unknown file" glyph even
# though the type is recognised. Reuses the application icon; aMule
# has no separate document artwork.
install (FILES org.amule.aMule.png
RENAME application-x-emule-collection.png
DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/128x128/mimetypes"
)
install (FILES org.amule.aMule-256.png
RENAME application-x-emule-collection.png
DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/256x256/mimetypes"
)
install (FILES org.amule.aMule.svg
RENAME application-x-emule-collection.svg
DESTINATION "${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/mimetypes"
)
endif()
# The AppStream metainfo's <releases> list is generated from docs/CHANGELOG.md
# at build time so the store-visible version can't drift from the shipped one
# (single source of truth). This runs inside any CMake build -- including
# flatpak-builder / Flathub building from a tag -- so the tagged source tree is
# self-sufficient. AppStream metainfo is a freedesktop concept; gate it to Linux
# (macOS/Windows never consumed the installed copy) so those builds need no
# python3.
if (CMAKE_SYSTEM_NAME STREQUAL "Linux")
find_package (Python3 COMPONENTS Interpreter REQUIRED)
set (_amule_metainfo "${CMAKE_CURRENT_BINARY_DIR}/org.amule.aMule.metainfo.xml")
add_custom_command (
OUTPUT "${_amule_metainfo}"
COMMAND "${Python3_EXECUTABLE}"
"${CMAKE_CURRENT_SOURCE_DIR}/packaging/gen-metainfo-releases.py"
--changelog "${CMAKE_CURRENT_SOURCE_DIR}/docs/CHANGELOG.md"
--template "${CMAKE_CURRENT_SOURCE_DIR}/org.amule.aMule.metainfo.xml.in"
--output "${_amule_metainfo}"
DEPENDS
"${CMAKE_CURRENT_SOURCE_DIR}/packaging/gen-metainfo-releases.py"
"${CMAKE_CURRENT_SOURCE_DIR}/org.amule.aMule.metainfo.xml.in"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/CHANGELOG.md"
COMMENT "Generating AppStream metainfo releases from docs/CHANGELOG.md"
VERBATIM
)
add_custom_target (amule_metainfo ALL DEPENDS "${_amule_metainfo}")
install (FILES "${_amule_metainfo}"
DESTINATION "${CMAKE_INSTALL_DATADIR}/metainfo"
)
endif()
install (FILES LICENSE.md
DESTINATION "${CMAKE_INSTALL_DOCDIR}"
)
if (ENABLE_NLS)
include (FindGettext)
add_subdirectory (po)
endif()
add_subdirectory (docs)
add_subdirectory (src)
if (BUILD_TESTING)
enable_testing()
add_subdirectory (unittests)
endif()
message (STATUS "
Configured aMule ${PACKAGE_VERSION} for '${CMAKE_SYSTEM}' on '${CMAKE_SYSTEM_PROCESSOR}'.
aMule enabled options:
**** aMule Core ****
Prefix where aMule should be installed? ${CMAKE_PREFIX_PATH}
Should aMule be compiled with i18n support? ${ENABLE_NLS}
Which mode should aMule be compiled in? ${CMAKE_BUILD_TYPE}
Should aMule be compiled with UPnP support? ${ENABLE_UPNP}
Should aMule be compiled with IP2country support? ${ENABLE_IP2COUNTRY}
Should aMule monolithic application be built? ${BUILD_MONOLITHIC}
Should aMule daemon version be built? ${BUILD_DAEMON}
Should aMule remote gui be built? ${BUILD_REMOTEGUI}
**** aMule TextClient ****
Should aMule Command Line Client be built? ${BUILD_AMULECMD}
**** aMule WebServer ****
Should aMule WebServer be built? ${BUILD_WEBSERVER}
**** aMule REST API ****
Should aMule REST API be built? ${BUILD_AMULEAPI}
**** aMule ED2K Links Handler ****
Should aMule ED2K Links Handler be built? ${BUILD_ED2K}
**** aMuleLinkCreator ****
Should aMuleLinkCreator GUI version (alc) be built? ${BUILD_ALC}
Should aMuleLinkCreator for console (alcc) be built? ${BUILD_ALCC}
**** aMule Statistics ****
Should C aMule Statistics (CAS) be built? ${BUILD_CAS}
Should aMule GUI Statistics (wxCas) be built? ${BUILD_WXCAS}"
)
message ("
**** General Libraries and Tools ****
Should aMule file viewer for console be built? ${BUILD_FILEVIEW}
Libraries aMule will use to build:"
)
if (NEED_WX)
message (STATUS " wxWidgets ${WX_VERSION}")
endif()
message (" boost ${Boost_VERSION}")
if (NEED_LIB_CRYPTO)
message (" crypto++ ${CRYPTOPP_VERSION} in ${CRYPTOPP_INCLUDE_PREFIX}")
endif()
if (ENABLE_UPNP)
message (" libupnp ${LIBUPNP_VERSION}")
endif()
message (" libintl ${ENABLE_NLS}")
if (ENABLE_IP2COUNTRY)
message (" libmaxminddb ${MAXMINDDB_LIB}")
endif()
if (BUILD_WEBSERVER)
message (" libpng ${PNG_VERSION_STRING}")
endif()
if (BUILD_CAS)
message (" libgd ${gdlib_VERSION}")
endif()
if (NEED_ZLIB)
message (" zlib ${ZLIB_VERSION_STRING}")
endif()
if ((BUILD_MONOLITHIC OR BUILD_REMOTEGUI) AND CMAKE_SYSTEM_NAME STREQUAL "Linux")
if (WITH_LIBAYATANA_APPINDICATOR)
message (" tray-icon backend StatusNotifierItem (libayatana-appindicator ${AYATANA_APPINDICATOR_VERSION})")
else()
message (" tray-icon backend legacy GtkStatusIcon (invisible on modern GNOME/wlroots — install libayatana-appindicator3-dev for SNI)")
endif()
endif()