gsmartcontrol icon indicating copy to clipboard operation
gsmartcontrol copied to clipboard

Feature request: AppImage support.

Open MagicalDrizzle opened this issue 11 months ago • 5 comments

Version and Environment

  • GSmartControl version: 2.0.1
  • OS: Fedora Kinoite 41

Is your feature request related to a problem? Please describe. Fedora Atomic images uses a read-only root filesystem and discourage installing packages the traditional way (i.e dnf) and prioritize Flatpaks/AppImages/brew/"things not installing into /usr"

Describe the solution you'd like It would be nice if gsmartcontrol can be distributed as an AppImage to be able to use it on these systems.

Describe alternatives you've considered Creating a rootful distrobox and installing gsmartcontrol in it, but that's a lot of disk space wasted for just one app. Layering traditional dnf packages in Fedora Atomic is possible - but highly discouraged.

Additional context

  • I had to make gsmartcontrol look for its data files in a portable way (i.e not hardcoding /usr/share) and this is how I managed to do that. (gsc_init.c)
	} else {
		if constexpr(BuildEnv::is_kernel_family_windows()) {
			hz::data_file_add_search_directory("icons", application_dir / "icons");
			hz::data_file_add_search_directory("ui", application_dir / "ui");
			hz::data_file_add_search_directory("doc", application_dir / "doc");
		} else {
			// old
			// hz::data_file_add_search_directory("icons", hz::fs_path_from_string(BuildEnv::package_pkgdata_dir()) / BuildEnv::package_name() / "icons");  // /usr/share/program_name/icons
			// hz::data_file_add_search_directory("ui", hz::fs_path_from_string(BuildEnv::package_pkgdata_dir()) / BuildEnv::package_name() / "ui");  // /usr/share/program_name/ui
			// hz::data_file_add_search_directory("doc", hz::fs_path_from_string(BuildEnv::package_doc_dir()));  // /usr/share/doc/[packages/]gsmartcontrol
			// new
			hz::data_file_add_search_directory("icons", application_dir.parent_path() / "share" / BuildEnv::package_name() / "icons");  // bin/../share/program_name/icons
			hz::data_file_add_search_directory("ui", application_dir.parent_path() / "share" / BuildEnv::package_name() / "ui");  // bin/../share/program_name/ui
			hz::data_file_add_search_directory("doc", application_dir.parent_path() / "share" / "doc" / BuildEnv::package_name());  // bin/../share/doc/[packages/]gsmartcontrol
		}
	}
  • I had to remove the gsmartcontrol-root script and just put the binary in /bin like a regular package (plus changing the desktop file exec entry to match) - because the AppImage format does not support running an embedded binary in it with sudo. This also require the AppImage to be run with sudo.
  • The gsmartcontrol.appdata.in.xml file had to either be deleted or changed a little as currently it does not pass appstreamcli's checks.
    • IDs should be in rDNS format, so <id>dev.shaduri.gsmartcontrol</id> instead of <id>gsmartcontrol</id>
    • Desktop filename must match ID - so <launchable type="desktop-id">dev.shaduri.gsmartcontrol.desktop</launchable> instead of <launchable type="desktop-id">gsmartcontrol.desktop</launchable> (plus the real desktop filename must be changed to match also).

After all that was done I successfully built the AppImage and confirm it works.

MagicalDrizzle avatar Jan 26 '25 08:01 MagicalDrizzle

Hi,

Thanks a lot for the work.

Would you mind sharing the steps you did (aside from patching) to build the AppImage? A script, for example.

Regarding the data file search, since I do not want to lose the pkgdir feature, I'm inclined to add a cmake switch (visible via BuildEnv) for AppImage builds. Do you think there is a better solution?

ashaduri avatar Feb 03 '25 10:02 ashaduri

  1. Patch the source code and build with -DCMAKE_INSTALL_PREFIX=/usr, then DESTDIR=gsmartcontrol make install to create the base appimage folder, named gsmartcontrol.
  2. Patch the gsmartcontrol.appdata.in.xml file as above, and change the desktop entry filename to match.
  3. Remove the gsmartcontrol-root script from /bin, put the original binary and delete the empty /sbin folder (more or less launching the app the "standard way" due to appimage limitations), then change the desktop entry Exec line to gsmartcontrol
  4. Download linuxdeploy-static-x86_64.AppImage from here: https://github.com/linuxdeploy/linuxdeploy/releases/latest and run ./linuxdeploy-static-x86_64.AppImage --appdir path/to/gsmartcontrol (the folder we created in step 1)
  • If it fails with some weird error about stripping (happens on Fedora 41), try running the command again with NO_STRIP=1
  1. Download appimagetool-x86_64.AppImage from https://github.com/AppImage/appimagetool/releases/tag/continuous, and run VERSION=2.0.1 ./appimagetool-x86_64.AppImage /path/to/gsmartcontrol (the folder we created in step 1)

That should be all!

MagicalDrizzle avatar Feb 04 '25 15:02 MagicalDrizzle

Thanks, I'll try to set it up using CI.

ashaduri avatar Feb 05 '25 12:02 ashaduri

Here's a draft script I wrote for Open Build Service! I hope it will be helpful.


app: gsmartcontrol

# resources required at build time
build:
  # packages which get installed in the build enviroment.
  # These are NOT part of the resulting image.
  packages:
#    - linuxdeploy # required tooling, see script section
    - cmake
    - ninja
    - libgtkmm3

  files:
    - https://github.com/ashaduri/gsmartcontrol/archive/refs/tags/v2.0.1.tar.gz
    - https://github.com/linuxdeploy/linuxdeploy/releases/download/2.0.0-alpha-1-20241106/linuxdeploy-static-x86_64.AppImage
    - https://gist.githubusercontent.com/MagicalDrizzle/575baac0a056fae33f8281fa5030679d/raw/f7c9d73ca9b46cb6f5816157c9286d5cba873341/gsmartcontrol.patch

script:
  - chmod +x $BUILD_SOURCE_DIR/linuxdeploy-static-x86_64.AppImage
  - tar xf v*.tar.gz -C $BUILD_SOURCE_DIR
  - cp gsmartcontrol.patch $BUILD_SOURCE_DIR/gsmartcontrol-*/
# patch source
  - patch -d $BUILD_SOURCE_DIR/gsmartcontrol-* -p1 -i gsmartcontrol.patch
  - sed -i 's/gsmartcontrol-root/gsmartcontrol/' $BUILD_SOURCE_DIR/gsmartcontrol-*/data/gsmartcontrol.in.desktop
# build
  - cd $BUILD_SOURCE_DIR/gsmartcontrol-*
  - mkdir build && cd build
  - cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/usr -G Ninja ..
  - ninja -j4
  - DESTDIR=$(readlink -f $BUILD_APPDIR) ninja install; find $BUILD_APPDIR/
# patch appdir
  - mv $BUILD_APPDIR/usr/share/applications/gsmartcontrol.desktop $BUILD_APPDIR/usr/share/applications/dev.shaduri.gsmartcontrol.desktop
  - mv $BUILD_APPDIR/usr/sbin/gsmartcontrol $BUILD_APPDIR/usr/bin
  - rm $BUILD_APPDIR/bin/gsmartcontrol-root; rmdir $BUILD_APPDIR/usr/sbin

# create the image file
  - VERSION=2.0.1
  - unset LD_LIBRARY_PATH
  - $BUILD_SOURCE_DIR/linuxdeploy-static-x86_64.AppImage --appdir $BUILD_APPDIR --desktop-file=$BUILD_APPDIR/usr/share/applications/dev.shaduri.gsmartcontrol.desktop 

MagicalDrizzle avatar Feb 15 '25 14:02 MagicalDrizzle

@MagicalDrizzle Thanks for the script, I'll try it with OBS.

ashaduri avatar Feb 19 '25 09:02 ashaduri