CMake: adds option -DENABLE_IMAGE_LOGO=<BOOL>

This commit is contained in:
Carter Li
2026-09-17 13:50:07 +08:00
parent 9bac273165
commit e004c97ee0
7 changed files with 118 additions and 33 deletions
+1 -1
View File
@@ -21,7 +21,7 @@ jobs:
run: uname -a
- name: configure project
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_EET=OFF -DENABLE_THREADS=OFF
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DCMAKE_INSTALL_PREFIX=/usr . -DENABLE_VULKAN=OFF -DENABLE_WAYLAND=OFF -DENABLE_XCB_RANDR=OFF -DENABLE_XCB=OFF -DENABLE_XRANDR=OFF -DENABLE_X11=OFF -DENABLE_DRM=OFF -DENABLE_DRM_AMDGPU=OFF -DENABLE_GIO=OFF -DENABLE_DCONF=OFF -DENABLE_DBUS=OFF -DENABLE_SQLITE3=OFF -DENABLE_RPM=OFF -DENABLE_IMAGEMAGICK7=OFF -DENABLE_IMAGEMAGICK6=OFF -DENABLE_CHAFA=OFF -DENABLE_ZLIB=OFF -DENABLE_EGL=OFF -DENABLE_GLX=OFF -DENABLE_OPENCL=OFF -DENABLE_FREETYPE=OFF -DENABLE_PULSE=OFF -DENABLE_DDCUTIL=OFF -DENABLE_ELF=OFF -DENABLE_EET=OFF -DENABLE_THREADS=OFF -DENABLE_IMAGE_LOGO=OFF
- name: build project
run: cmake --build . --target package --verbose -j4
+9 -3
View File
@@ -1,9 +1,10 @@
# Unreleased
Changes:
* ImageMagick is no longer used for image logos on Windows and macOS, and has been replaced by the platform image frameworks (WIC on Windows, ImageIO on macOS). (Logo, Windows / macOS)
* Image logos on Windows and macOS no longer depend on ImageMagick being installed.
* Image sources that only ImageMagick could decode, such as SVG, PDF and PostScript, are no longer supported on Windows: neither WIC nor the embedded sixel encoder can decode them.
* ImageMagick is no longer used for image logos on Windows and macOS, and has been replaced by the platform image frameworks (WIC on Windows, ImageIO on macOS). (Logo)
* ImageMagick 6 support is deprecated. It's only kept for old Debian & Ubuntu releases which have no ImageMagick 7 available.
* Intended to be removed in a future release. Users are encouraged to upgrade to ImageMagick 7 when possible.
* The `--logo-recache` option has been replaced by `--logo-cache <bool|regen>`, and the `logo.recache` JSON property has been renamed to `logo.cache`. (Logo)
* `--logo-cache true` (the default) reuses a cached rendering when it is valid, and writes it back on a cache miss.
* `--logo-cache false` ignores the image logo cache completely: nothing is read from it and nothing is written to it.
@@ -29,6 +30,11 @@ Features:
* The default is `1`, which renders a still image, so nothing changes for anyone who does not opt in.
* The frames come from the platform image framework (WIC on Windows, ImageIO on macOS, ImageMagick 7 on Linux). A single frame GIF falls back to a still image. A build with none of those, or with ImageMagick 6, reports an error instead of quietly showing a still image.
* A terminal that supports the kitty graphics protocol but not its animation frames, as Konsole does not, shows the first frame.
* Added the CMake option `ENABLE_IMAGE_LOGO`, which defaults to `ON`. Configure with `-DENABLE_IMAGE_LOGO=OFF` to build fastfetch without any image logo support. (Logo)
* Image logos are the only consumer of ImageMagick, of chafa and of the embedded libsixel encoder, so none of the three is looked for at configure time, and no image decoding source is compiled in.
* The `sixel`, `kitty`, `kitty-direct`, `kitty-icat`, `iterm` and `chafa` logo types are rejected with an error, on the command line and in the JSON config alike, and the `auto` logo type never tries an image.
* `--logo-type raw` keeps working: it writes a pre-rendered byte stream through unchanged and needs no decoder, so a logo can still be displayed by converting the image externally.
* This is intended to be used to reduce binary size on embedded systems (such as OpenWrt) only.
* Added CPU name and frequency detection support on SPARC. (CPU, Linux)
* Added package detection support for CRUX. (Packages, Linux)
* Exposed in custom format as `{crux}`.
+31 -10
View File
@@ -88,10 +88,6 @@ cmake_dependent_option(ENABLE_EET "Enable eet" ON "LINUX OR FreeBSD OR OpenBSD O
cmake_dependent_option(ENABLE_DBUS "Enable dbus-1" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_SQLITE3 "Enable sqlite3" ON "LINUX OR FreeBSD OR APPLE OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_RPM "Enable rpm" ON "LINUX OR GNU" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_SIXEL "Enable sixel logo output via the embedded libsixel encoder (Windows and macOS; replaces ImageMagick's SIXEL coder)" ON "WIN32 OR APPLE" OFF)
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7 OR WIN32 OR APPLE" OFF)
cmake_dependent_option(ENABLE_EGL "Enable egl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR WIN32 OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_GLX "Enable glx" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_OPENCL "Enable opencl" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR WIN32 OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
@@ -101,6 +97,14 @@ cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF)
cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR ANDROID OR DragonFly OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
option(ENABLE_IMAGE_LOGO "Enable image logos (sixel / kitty / iTerm / chafa)" ON)
if(ENABLE_IMAGE_LOGO)
cmake_dependent_option(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR ANDROID OR SunOS OR Haiku OR GNU" OFF)
cmake_dependent_option(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON "LINUX OR FreeBSD OR OpenBSD OR NetBSD OR SunOS OR GNU" OFF)
cmake_dependent_option(ENABLE_SIXEL "Enable sixel logo output via the embedded libsixel encoder (Windows and macOS; replaces ImageMagick's SIXEL coder)" ON "WIN32 OR APPLE" OFF)
cmake_dependent_option(ENABLE_CHAFA "Enable chafa" ON "ENABLE_IMAGEMAGICK6 OR ENABLE_IMAGEMAGICK7 OR WIN32 OR APPLE" OFF)
endif()
option(ENABLE_ZLIB "Enable zlib" ON)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
@@ -501,10 +505,6 @@ set(LIBFASTFETCH_SRC
src/detection/weather/weather.c
src/detection/zpool/zpool.c
src/logo/builtin.c
src/logo/image/im6.c
src/logo/image/im7.c
src/logo/image/image.c
src/logo/image/sixel.c
src/logo/logo.c
src/modules/modules.c
src/options/display.c
@@ -512,6 +512,15 @@ set(LIBFASTFETCH_SRC
src/options/general.c
)
if(ENABLE_IMAGE_LOGO)
list(APPEND LIBFASTFETCH_SRC
src/logo/image/image.c
src/logo/image/im6.c
src/logo/image/im7.c
src/logo/image/sixel.c
)
endif()
foreach(FF_MODULE_DIR ${FF_MODULE_DIRS})
list(APPEND LIBFASTFETCH_SRC
src/modules/${FF_MODULE_DIR}/${FF_MODULE_DIR}.c
@@ -1023,8 +1032,12 @@ elseif(APPLE)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.c
src/detection/camera/camera_apple.m
src/logo/image/imageio.c
)
if(ENABLE_IMAGE_LOGO)
list(APPEND LIBFASTFETCH_SRC
src/logo/image/imageio.c
)
endif()
# CMAKE_SYSTEM_PROCESSOR has been normalized before
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "amd64")
list(APPEND LIBFASTFETCH_SRC
@@ -1117,8 +1130,12 @@ elseif(WIN32)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_windows.c
src/detection/camera/camera_windows.cpp
src/logo/image/wic.cpp
)
if(ENABLE_IMAGE_LOGO)
list(APPEND LIBFASTFETCH_SRC
src/logo/image/wic.cpp
)
endif()
elseif(SunOS)
list(APPEND LIBFASTFETCH_SRC
src/common/impl/dbus.c
@@ -1846,6 +1863,10 @@ if(ENABLE_THREADS)
endif()
endif()
if(ENABLE_IMAGE_LOGO)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_IMAGE_LOGO=1)
endif()
if(ENABLE_EMBEDDED_PCIIDS)
target_compile_definitions(libfastfetch PUBLIC FF_HAVE_EMBEDDED_PCIIDS=1)
endif()
+1 -3
View File
@@ -46,6 +46,7 @@ const char* ffGpuDetectMetal(FFlist* gpus) {
continue;
}
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#ifndef MAC_OS_X_VERSION_10_15
if ([device supportsFeatureSet:MTLFeatureSet_macOS_GPUFamily2_v1]) {
ffStrbufSetStatic(&gpu->platformApi, "Metal Feature Set 2");
@@ -53,14 +54,11 @@ const char* ffGpuDetectMetal(FFlist* gpus) {
ffStrbufSetStatic(&gpu->platformApi, "Metal Feature Set 1");
}
#else // MAC_OS_X_VERSION_10_15
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunguarded-availability-new"
if ([device supportsFamily:MTLGPUFamilyMetal4]) {
ffStrbufSetStatic(&gpu->platformApi, "Metal 4");
} else if ([device supportsFamily:MTLGPUFamilyMetal3]) {
ffStrbufSetStatic(&gpu->platformApi, "Metal 3");
}
#pragma clang diagnostic pop
else if ([device supportsFamily:MTLGPUFamilyCommon3]) {
ffStrbufSetStatic(&gpu->platformApi, "Metal Common 3");
} else if ([device supportsFamily:MTLGPUFamilyCommon2]) {
+20 -6
View File
@@ -518,6 +518,7 @@ static bool logoPrintFileIfExists(bool doColorReplacement, bool raw) {
return true;
}
#if FF_HAVE_IMAGE_LOGO
static bool logoPrintImageIfExists(FFLogoType logo, bool printError) {
if (!ffLogoPrintImageIfExists(logo, printError)) {
return false;
@@ -526,6 +527,7 @@ static bool logoPrintImageIfExists(FFLogoType logo, bool printError) {
logoApplyColors(logoGetBuiltinDetected(FF_LOGO_SIZE_NORMAL), false);
return true;
}
#endif
static bool logoTryKnownType(void) {
FFOptionsLogo* options = &instance.config.logo;
@@ -593,7 +595,16 @@ static bool logoTryKnownType(void) {
return logoPrintFileIfExists(false, true);
}
#if FF_HAVE_IMAGE_LOGO
return logoPrintImageIfExists(options->type, instance.config.display.showErrors);
#else
// No image logo type can be selected in this build (see ffOptionsParseLogoCommandLine), and
// FF_LOGO_TYPE_IMAGE_RAW was handled above, so nothing printable is left for this source.
if (instance.config.display.showErrors) {
fprintf(stderr, "Logo: Unsupported logo type for source: %s\n", options->source.chars);
}
return false;
#endif
}
void ffLogoPrint(void) {
@@ -638,8 +649,10 @@ void ffLogoPrint(void) {
}
}
#if FF_HAVE_IMAGE_LOGO
// Try to load the logo as an image.
if (!ffStrbufEndsWithIgnCaseS(&options->source, ".txt")) {
#if !FF_MODULE_DISABLE_TERMINAL
#if !FF_MODULE_DISABLE_TERMINAL
const FFTerminalResult* terminal = ffDetectTerminal();
bool supportsIterm2 = ffStrbufEqualS(&terminal->prettyName, "iTerm");
@@ -655,21 +668,22 @@ void ffLogoPrint(void) {
ffStrbufIgnCaseEqualS(&terminal->processName, "wezterm") ||
ffStrbufIgnCaseEqualS(&terminal->processName, "wayst") ||
ffStrbufIgnCaseEqualS(&terminal->processName, "ghostty") ||
#ifdef __APPLE__
#ifdef __APPLE__
ffStrbufIgnCaseEqualS(&terminal->processName, "WarpTerminal") ||
#else
#else
ffStrbufIgnCaseEqualS(&terminal->processName, "warp") ||
#endif
#endif
false;
#else
#else
bool supportsKitty = false;
#endif
#endif
// Try to load the logo as an image. If it succeeds, print it and return.
if (logoPrintImageIfExists(supportsKitty ? FF_LOGO_TYPE_IMAGE_KITTY : FF_LOGO_TYPE_IMAGE_CHAFA, false)) {
return;
}
}
#endif
// Try to load the logo as a file. If it succeeds, print it and return.
if (logoPrintFileIfExists(true, false)) {
+2
View File
@@ -39,5 +39,7 @@ const FFlogo* ffLogoGetBuiltinDetected(FFLogoSize size);
extern const FFlogo* ffLogoBuiltins[];
extern const FFlogo ffLogoUnknown;
#if FF_HAVE_IMAGE_LOGO
// image/image.c
bool ffLogoPrintImageIfExists(FFLogoType type, bool printError);
#endif
+54 -10
View File
@@ -3,6 +3,42 @@
#include "common/jsonconfig.h"
#include "common/strutil.h"
#if !FF_HAVE_IMAGE_LOGO
// The image logo types are still accepted by the parsers below in a build that can not render them,
// so that the user is told which type is unavailable instead of being told the type does not exist.
// The one that is deliberately left out is `raw`: it writes a pre-rendered byte stream through
// untouched and needs no decoder, so a build without image logos can still display one.
static bool logoTypeIsImage(FFLogoType type) {
switch (type) {
case FF_LOGO_TYPE_IMAGE_SIXEL:
case FF_LOGO_TYPE_IMAGE_KITTY:
case FF_LOGO_TYPE_IMAGE_KITTY_DIRECT:
case FF_LOGO_TYPE_IMAGE_KITTY_ICAT:
case FF_LOGO_TYPE_IMAGE_ITERM:
case FF_LOGO_TYPE_IMAGE_CHAFA:
return true;
default:
return false;
}
}
#endif
// --sixel, --kitty, --kitty-direct, --kitty-icat and --iterm. They keep a branch of their own in
// every build so that the error a build without image logos gives names the flag that was used,
// rather than it being rejected as an unknown option. --chafa is not among them: it is gated on
// FF_HAVE_CHAFA, which a build without image logos turns off as well, and it keeps the message it
// has always given in that case.
static void logoParseImageFlag(FFOptionsLogo* options, const char* key, const char* value, FFLogoType type) {
#if FF_HAVE_IMAGE_LOGO
ffOptionParseString(key, value, &options->source);
options->type = type;
#else
FF_UNUSED(options, key, value, type);
fputs("Error: Fastfetch was built without image logo support\n", stderr);
exit(477);
#endif
}
void ffOptionsInitLogo(FFOptionsLogo* options) {
ffStrbufInit(&options->source);
options->type = FF_LOGO_TYPE_AUTO;
@@ -71,6 +107,12 @@ bool ffOptionsParseLogoCommandLine(FFOptionsLogo* options, const char* key, cons
{ "none", FF_LOGO_TYPE_NONE },
{},
});
#if !FF_HAVE_IMAGE_LOGO
if (logoTypeIsImage(options->type)) {
fputs("Error: Fastfetch was built without image logo support\n", stderr);
exit(477);
}
#endif
} else if (ffStrStartsWithIgnCase(subKey, "color-") && subKey[6] != '\0' && subKey[7] == '\0') // matches "--logo-color-*"
{
// Map the number to an array index, so that '1' -> 0, '2' -> 1, etc.
@@ -151,20 +193,15 @@ bool ffOptionsParseLogoCommandLine(FFOptionsLogo* options, const char* key, cons
return false;
}
} else if (ffStrEqualsIgnCase(key, "--sixel")) {
ffOptionParseString(key, value, &options->source);
options->type = FF_LOGO_TYPE_IMAGE_SIXEL;
logoParseImageFlag(options, key, value, FF_LOGO_TYPE_IMAGE_SIXEL);
} else if (ffStrEqualsIgnCase(key, "--kitty")) {
ffOptionParseString(key, value, &options->source);
options->type = FF_LOGO_TYPE_IMAGE_KITTY;
logoParseImageFlag(options, key, value, FF_LOGO_TYPE_IMAGE_KITTY);
} else if (ffStrEqualsIgnCase(key, "--kitty-direct")) {
ffOptionParseString(key, value, &options->source);
options->type = FF_LOGO_TYPE_IMAGE_KITTY_DIRECT;
logoParseImageFlag(options, key, value, FF_LOGO_TYPE_IMAGE_KITTY_DIRECT);
} else if (ffStrEqualsIgnCase(key, "--kitty-icat")) {
ffOptionParseString(key, value, &options->source);
options->type = FF_LOGO_TYPE_IMAGE_KITTY_ICAT;
logoParseImageFlag(options, key, value, FF_LOGO_TYPE_IMAGE_KITTY_ICAT);
} else if (ffStrEqualsIgnCase(key, "--iterm")) {
ffOptionParseString(key, value, &options->source);
options->type = FF_LOGO_TYPE_IMAGE_ITERM;
logoParseImageFlag(options, key, value, FF_LOGO_TYPE_IMAGE_ITERM);
} else if (ffStrEqualsIgnCase(key, "--raw")) {
ffOptionParseString(key, value, &options->source);
options->type = FF_LOGO_TYPE_IMAGE_RAW;
@@ -278,6 +315,11 @@ const char* ffOptionsParseLogoJsonConfig(FFOptionsLogo* options, yyjson_val* roo
if (error) {
return error;
}
#if !FF_HAVE_IMAGE_LOGO
if (logoTypeIsImage((FFLogoType) value)) {
return "Image logo types are not supported because Fastfetch was built without image logo support";
}
#endif
options->type = (FFLogoType) value;
continue;
} else if (unsafe_yyjson_equals_str(key, "source")) {
@@ -482,6 +524,7 @@ void ffOptionsGenerateLogoJsonConfig(FFdata* data, FFOptionsLogo* options) {
case FF_LOGO_TYPE_COMMAND_RAW:
yyjson_mut_obj_add_str(doc, obj, "type", "command-raw");
break;
#if FF_HAVE_IMAGE_LOGO
case FF_LOGO_TYPE_IMAGE_SIXEL:
yyjson_mut_obj_add_str(doc, obj, "type", "sixel");
break;
@@ -500,6 +543,7 @@ void ffOptionsGenerateLogoJsonConfig(FFdata* data, FFOptionsLogo* options) {
case FF_LOGO_TYPE_IMAGE_CHAFA:
yyjson_mut_obj_add_str(doc, obj, "type", "chafa");
break;
#endif
case FF_LOGO_TYPE_IMAGE_RAW:
yyjson_mut_obj_add_str(doc, obj, "type", "raw");
break;