summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorruki <[email protected]>2025-11-26 23:23:41 +0800
committerruki <[email protected]>2025-11-26 23:23:41 +0800
commit00e764947542e1d05e167b5d5f81b80dd5f054df (patch)
treef63946b0f8aaefaa17f9d52579b7426c86138fe5
parent32717cd979bfd514f9ef1242efc80f91bd261da8 (diff)
improve appimage
-rw-r--r--tests/plugins/pack/console/src/assets/xmake.pngbin0 -> 24378 bytes
-rw-r--r--tests/plugins/pack/console/xmake.lua10
-rw-r--r--xmake/modules/detect/tools/find_appimagetool.lua2
-rw-r--r--xmake/plugins/pack/appimage/main.lua101
4 files changed, 72 insertions, 41 deletions
diff --git a/tests/plugins/pack/console/src/assets/xmake.png b/tests/plugins/pack/console/src/assets/xmake.png
new file mode 100644
index 000000000..be7f6c4f2
--- /dev/null
+++ b/tests/plugins/pack/console/src/assets/xmake.png
Binary files differ
diff --git a/tests/plugins/pack/console/xmake.lua b/tests/plugins/pack/console/xmake.lua
index 244bcaee6..6db4316c5 100644
--- a/tests/plugins/pack/console/xmake.lua
+++ b/tests/plugins/pack/console/xmake.lua
@@ -19,7 +19,7 @@ target("foo")
add_packages("zlib")
xpack("test")
- set_formats("nsis", "srpm", "rpm", "deb", "zip", "targz", "srczip", "srctargz", "runself", "wix", "dmg")
+ set_formats("nsis", "srpm", "rpm", "deb", "zip", "targz", "srczip", "srctargz", "runself", "wix", "dmg", "appimage")
set_title("hello")
set_author("ruki <[email protected]>")
set_description("A test installer.")
@@ -30,7 +30,6 @@ xpack("test")
add_installfiles("src/(assets/*.png)", {prefixdir = "images"})
add_sourcefiles("(src/**)")
add_sourcefiles("xmake.lua")
- set_iconfile("src/assets/xmake.ico")
add_components("LongPath")
on_load(function (package)
@@ -39,6 +38,13 @@ xpack("test")
else
package:set("basename", "test-$(plat)-$(arch)-v$(version)")
end
+ -- set icon file based on format (use PNG for appimage, ICO for other formats)
+ local scriptdir = os.scriptdir()
+ if package:format() == "appimage" then
+ package:set("iconfile", path.join(scriptdir, "src/assets/xmake.png"))
+ else
+ package:set("iconfile", path.join(scriptdir, "src/assets/xmake.ico"))
+ end
end)
after_installcmd(function (package, batchcmds)
diff --git a/xmake/modules/detect/tools/find_appimagetool.lua b/xmake/modules/detect/tools/find_appimagetool.lua
index 385ec2614..f19c9264d 100644
--- a/xmake/modules/detect/tools/find_appimagetool.lua
+++ b/xmake/modules/detect/tools/find_appimagetool.lua
@@ -44,6 +44,8 @@ function main(opt)
-- init options
opt = opt or {}
+ opt.envs = opt.envs or {}
+ opt.envs.APPIMAGE_EXTRACT_AND_RUN = "1"
-- find program
local program = find_program(opt.program or "appimagetool", opt)
diff --git a/xmake/plugins/pack/appimage/main.lua b/xmake/plugins/pack/appimage/main.lua
index 1de6eb569..447bb5714 100644
--- a/xmake/plugins/pack/appimage/main.lua
+++ b/xmake/plugins/pack/appimage/main.lua
@@ -23,6 +23,61 @@ import("core.base.option")
import("lib.detect.find_tool")
import(".batchcmds")
+-- handle icon file
+function _handle_icon(package, appdir, appname)
+ local iconname = nil
+ local iconfile = package:get("iconfile")
+ if iconfile then
+ local iconpath = path.absolute(iconfile)
+ if not os.isfile(iconpath) then
+ raise("icon file not found: %s", iconfile)
+ end
+ local ext = path.extension(iconpath)
+ -- AppImage only supports .png, .svg, .xpm
+ if ext ~= ".png" and ext ~= ".svg" and ext ~= ".xpm" then
+ raise("appimage format only supports .png, .svg, or .xpm icon files, but got: %s", ext)
+ end
+ iconname = appname .. ext
+ -- copy to AppDir root (required for AppImage)
+ os.cp(iconpath, path.join(appdir, iconname))
+ -- also copy to standard location
+ local iconsdir = path.join(appdir, "usr", "share", "icons", "hicolor", "256x256", "apps")
+ os.mkdir(iconsdir)
+ os.cp(iconpath, path.join(iconsdir, iconname))
+ end
+ return iconname
+end
+
+-- create desktop file
+function _create_desktop_file(package, appdir, appname, apptitle, appdescription, main_executable, iconname)
+ local desktopfile = path.join(appdir, appname .. ".desktop")
+ local icon_line = ""
+ if iconname then
+ icon_line = string.format("Icon=%s\n", appname)
+ end
+ local desktop_content = string.format([[
+[Desktop Entry]
+Type=Application
+Name=%s
+Comment=%s
+Exec=usr/bin/%s
+%sCategories=Utility;
+]], apptitle, appdescription, main_executable, icon_line)
+ io.writefile(desktopfile, desktop_content)
+end
+
+-- create AppRun script
+function _create_apprun_script(appdir, main_executable)
+ local apprun = path.join(appdir, "AppRun")
+ local apprun_content = string.format([[
+#!/bin/bash
+HERE="$(dirname "$(readlink -f "${0}")")"
+exec "${HERE}/usr/bin/%s" "$@"
+]], main_executable)
+ io.writefile(apprun, apprun_content)
+ os.vrunv("chmod", {"+x", apprun})
+end
+
-- get main executable from package
function _get_main_executable(package, usrdir)
local main_executable = nil
@@ -69,7 +124,7 @@ function _pack_appimage(package)
assert(package:is_plat("linux"), "appimage format only supports Linux platform!")
-- find appimagetool
- local appimagetool = find_appimagetool()
+ local appimagetool = find_tool("appimagetool")
if not appimagetool then
raise("appimagetool not found! Please install appimagetool.")
end
@@ -109,50 +164,18 @@ function _pack_appimage(package)
local appname = package:name()
local apptitle = package:title() or appname
local appdescription = package:description() or ""
- local appversion = package:version() or "1.0.0"
- -- create .desktop file
- local desktopfile = path.join(appdir, appname .. ".desktop")
- local desktop_content = string.format([[
-[Desktop Entry]
-Type=Application
-Name=%s
-Comment=%s
-Exec=usr/bin/%s
-Icon=%s
-Categories=Utility;
-Version=%s
-]], apptitle, appdescription, main_executable, appname, appversion)
- io.writefile(desktopfile, desktop_content)
+ -- handle icon file
+ local iconname = _handle_icon(package, appdir, appname)
- -- copy icon file if exists
- local iconfile = package:get("iconfile")
- if iconfile then
- local iconpath = path.absolute(iconfile)
- if os.isfile(iconpath) then
- -- copy to AppDir root (required for AppImage)
- local ext = path.extension(iconpath)
- local iconname = appname .. ext
- os.cp(iconpath, path.join(appdir, iconname))
- -- also copy to standard location
- local iconsdir = path.join(appdir, "usr", "share", "icons", "hicolor", "256x256", "apps")
- os.mkdir(iconsdir)
- os.cp(iconpath, path.join(iconsdir, iconname))
- end
- end
+ -- create desktop file
+ _create_desktop_file(package, appdir, appname, apptitle, appdescription, main_executable, iconname)
-- create AppRun script
- local apprun = path.join(appdir, "AppRun")
- local apprun_content = string.format([[
-#!/bin/bash
-HERE="$(dirname "$(readlink -f "${0}")")"
-exec "${HERE}/usr/bin/%s" "$@"
-]], main_executable)
- io.writefile(apprun, apprun_content)
- os.vrunv("chmod", {"+x", apprun})
+ _create_apprun_script(appdir, main_executable)
-- create AppImage using appimagetool
- os.vrunv(appimagetool.program, {appdir, outputfile})
+ os.vrunv(appimagetool.program, {appdir, outputfile}, {envs = {APPIMAGE_EXTRACT_AND_RUN = "1"}})
-- verify AppImage was created
assert(os.isfile(outputfile), "generate %s failed!", outputfile)