diff --git a/.gitignore b/.gitignore
index 75b7f9586e991652adac6bc5251fee5b007b641b..45da259866ebbcb381427b67b1110f719cfca72d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -37,6 +37,7 @@
 *.vsp
 *.y4m
 *.zip
+*.DirIcon
 *~
 
 /bin
@@ -67,6 +68,8 @@ packages/desktop/aegisub.desktop
 packages/desktop/aegisub.desktop.template
 packages/win_installer/vendor
 src/aegisub
+Aegisub/aegisub
+Aegisub/usr/bin/aegisub
 src/libresrc/bitmap.cpp
 src/libresrc/bitmap.h
 src/libresrc/default_config.cpp
diff --git a/Aegisub/Aegisub.desktop b/Aegisub/Aegisub.desktop
new file mode 100644
index 0000000000000000000000000000000000000000..c630bbaf8a0924fbe733b75393ccccf8da029136
--- /dev/null
+++ b/Aegisub/Aegisub.desktop
@@ -0,0 +1,13 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=Aegisub
+Icon=aegisub-icon
+GenericName=Subtitle Editor
+Comment=Create and edit subtitles for film and videos.
+Keywords=subtitles;video;audio;text
+Terminal=false
+Categories=AudioVideo;AudioVideoEditing;
+MimeType=application/x-srt;text/plain;text/x-ass;text/x-microdvd;text/x-ssa;
+StartupNotify=true
+Exec=aegisub
diff --git a/Aegisub/AppRun b/Aegisub/AppRun
new file mode 100755
index 0000000000000000000000000000000000000000..27f3ec957763def5b0499550b8f622378b73b0fa
--- /dev/null
+++ b/Aegisub/AppRun
@@ -0,0 +1,9 @@
+#!/bin/sh
+
+HERE=$(dirname $(readlink -f "$0"))
+export LC_ALL="en_US.UTF-8"
+export LD_LIBRARY_PATH="$HERE/usr/lib"
+EXEC=$(grep -e '^Exec=.*' "$HERE"/*.desktop | head -n 1 | cut -d "=" -f 2 | cut -d " " -f 1)
+ldd $(which $EXEC)
+export PATH="$HERE/usr/bin"
+exec $EXEC $@
diff --git a/Aegisub/aegisub-icon.png b/Aegisub/aegisub-icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..fbbd14dc9f46796622c457b781c1388d45353788
Binary files /dev/null and b/Aegisub/aegisub-icon.png differ
diff --git a/appimage/.gitkeep b/Aegisub/usr/bin/.gitkeep
similarity index 100%
rename from appimage/.gitkeep
rename to Aegisub/usr/bin/.gitkeep
diff --git a/Aegisub/usr/lib/.gitkeep b/Aegisub/usr/lib/.gitkeep
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Makefile.target b/Makefile.target
index fd40d87bfe92fcac59f3b8719433ab3308e6ee25..202cb590de0a8ca7af88e2d55241784ba4d62743 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -1,5 +1,5 @@
 ifneq (yes, $(INCLUDING_CHILD_MAKEFILES))
-COMMANDS := all install clean distclean test depclean osx-bundle osx-dmg test-automation test-libaegisub style tags
+COMMANDS := all install clean distclean test depclean osx-bundle osx-dmg test-automation test-libaegisub style tags appimage
 .PHONY: $(COMMANDS)
 .DEFAULT_GOAL := all
 
@@ -95,6 +95,11 @@ style:
 tags:
 	./tools/tags.bash
 
+appimage: src/aegisub
+	cp $^ Aegisub/usr/bin/aegisub
+	./tools/copy-libs.lua Aegisub/usr/bin/aegisub Aegisub/usr/lib
+	./tools/appimagetool.AppImage Aegisub
+
 # The actual build rules
 .SUFFIXES:
 
diff --git a/configure.ac b/configure.ac
index cc202d8ea6852279867a7a8cf10d52c3f53ec04c..658f066da08b2f5adaad20d23881ff7f028967be 100644
--- a/configure.ac
+++ b/configure.ac
@@ -191,8 +191,9 @@ AC_ARG_ENABLE([appimage],
               [AEGISUB_APPIMAGE_ENABLED=no])
 AS_IF([test "x$AEGISUB_APPIMAGE_ENABLED" = "xyes"], [
        AC_MSG_CHECKING([Downloading AppImage creation tool])
-       wget https://github.com/probonopd/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage \
+       wget https://github.com/probonopd/AppImageKit/releases/download/continuous/appimagetool-`arch`.AppImage \
            -O tools/appimagetool.AppImage -o config.wget.log
+       chmod 00700 tools/appimagetool.AppImage
        AS_IF([test $? -eq 0 ], [
            AC_MSG_RESULT([done])
         ], [
diff --git a/header.mk b/header.mk
index a9ce1d77872210a4a51f4d7794ab138ffe33756c..c82d739747dcf2bdb166a25dfa609b7f172cbb36 100644
--- a/header.mk
+++ b/header.mk
@@ -38,6 +38,10 @@ DISTCLEANFILES += \
 	$(TOP)autom4te.cache \
 	$(TOP)aclocal.m4 \
 
+CLEANFILES += \
+	$(TOP)Aegisub/usr/bin/aegisub \
+	$(wildcard $(TOP)Aegisub/usr/lib/*)
+
 define MKDIR_INSTALL
 @$(BIN_MKDIR_P) $(dir $@)
 $(BIN_INSTALL) -m644 $< $@
diff --git a/tools/copy-libs.lua b/tools/copy-libs.lua
new file mode 100755
index 0000000000000000000000000000000000000000..eb674ab20a795f66a19b7279d08a502e8b72311b
--- /dev/null
+++ b/tools/copy-libs.lua
@@ -0,0 +1,76 @@
+#!/usr/bin/env lua
+-- Needs awk and a shell (usually bash / sh) and ldd, which is a Linux utility.
+-- Thus run only this script on a Linux env or where the .so files can be found
+-- with the ldd command.
+
+if not arg or #arg ~= 2 then os.exit(1) end
+
+io.stdout:write(string.format('Running for file %s\n', arg[1]))
+io.stdout:write(string.format('Dest folder is %s\n',   arg[2]))
+
+-- Libs tables
+LIBS_WRITE = {}
+LIBS_READ  = {}
+
+-- Capture the output of a command
+function os.capture(cmd)
+    local f = assert(io.popen(cmd, 'r'))
+    local s = assert(f:read('*a'))
+    f:close()
+    return s
+end
+
+-- Simple copy of a table, it doesn't work with metatables and recursive tables
+function copy_simple(obj)
+    if type(obj) ~= 'table' then return obj end
+    local res = {}
+    for k, v in pairs(obj) do res[copy_simple(k)] = copy_simple(v) end
+    return res
+end
+
+-- Add the content of t2 in t1
+function concatenate(t1, t2)
+    for name, file in pairs(t2) do
+        t1[name] = file
+    end
+end
+
+-- Get the number of elements in a table
+function tablelength(T)
+    local count = 0
+    for _ in pairs(T) do count = count + 1 end
+    return count
+end
+
+-- The ldd command line utility, but in lua
+function ldd(file)
+    local libs = {}
+    local cmd  = string.format('ldd %s | awk \'$2 = "=>" && $3 { print $1 " " $3 }\'', arg[1])
+    local out  = os.capture(cmd)
+
+    for name, file in out:gmatch("([^\n ]*) ([^\n ]*)[\n]") do
+        libs[name] = file
+    end
+
+    return libs
+end
+
+-- Add NEEDS for each lib while there are some added. It's like a dataflow algorithme.
+LIBS_WRITE = ldd(arg[1])
+while tablelength(LIBS_READ) ~= tablelength(LIBS_WRITE) do
+    LIBS_READ = copy_simple(LIBS_WRITE)
+
+    for name, file in pairs(LIBS_READ) do
+        concatenate(LIBS_WRITE, ldd(file))
+    end
+end
+
+io.stdout:write(string.format("Cleaning %s", arg[2]))
+os.execute(string.format("rm -f %s/*", arg[2]))
+
+for name, file in pairs(LIBS_WRITE) do
+    local cmd = string.format('cp %s %s/%s && chmod 555 %s/%s',
+                              file, arg[2], name, arg[2], name)
+    os.execute(cmd)
+end
+io.stdout:write(string.format("Copied %d libraries to %s\n", tablelength(LIBS_WRITE), arg[2]))