Skip to content

Build AppImage packages for all distributions but including Arch Linux packages. Powered by JuNest.

License

Notifications You must be signed in to change notification settings

ivan-hc/ArchImage

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ArchImage is the bundling of Arch Linux packages into an AppImage using JuNest. Hardware accelleration is provided by Conty instead.

This allows you to use the latest programs from Arch Linux and AUR on every distribution, old or newer.

Being this a container into an AppImage, it has its own "bubblewrap" or "proot" to work using its inbuilt resources, including GLIBC, so it can run also on 10+ years old GNU/Linux distributions.

From version 4.2 is available a NEW template that creates AppImages that can work on both systems with or without Namespaces restrictions:

It is the mix of the two previous templates used until version 4.1:

If you have already installed archimage-cli, please run

archimage-cli -s

...to use the latest version.

Archimage combines the flexibility of JuNest with the power of Conty, the two portable Arch Linux containers that run on any other GNU/Linux distribution, offering the ability to package all the software available in the official Arch Linux repositories, the AUR and ChaoticAUR.


Index


Installation

Usage

Tutorial

Hardware Acceleration

Compared to classic AppImage construction

Files removed by default

Customize your script

Drafts

Troubleshooting

Credits

Related projects


Installation

Download the main script and made it executable:

wget https://raw.githubusercontent.com/ivan-hc/ArchImage/main/archimage-cli
chmod a+x ./archimage-cli

USAGE:

archimage-cli [OPTION]
archimage-cli [OPTION] [PROGRAM]

OPTIONS:

-h,--help		Shows this message.
-v,--version	Shows the version.
-b,--build		Create the script to build the AppImage.
-s,--sync		Update archimage-cli to the latest version.

Back to "Index"

What to do

To prevent problems of any kind, dedicate a single directory to the created script, proceed as follows:

  1. create the script;
  2. create an empty directory, the name must not contain spaces, for example "tmp" or "test";
  3. move the script you created to the directory in step 2;
  4. open a terminal in the directory created in step 2;
  5. run the script inside the directory, like this: ./sample-junest.sh

EXAMPLE

In this video I will show all the steps that I will describe in this section (Archimage 3.4.2):

simplescreenrecorder-2024-06-16_21.19.47_edit.mkv.mp4

What NOT to do

Here's what absolutely NOT to do when running a script you created:

  • DO NOT DRAG THE CREATED SCRIPT INTO THE TERMINAL! The script only works if run in place, see point 5 above.
  • DO NOT RUN THE CREATED SCRIPT IN YOUR $HOME DIRECTORY! The script will use the directory where it is run as $HOME. You must follow points 2, 3 and 4 above.
  • DO NOT RUN THE CREATED SCRIPT IN ANY OTHER DIRECTORIES! Create an empty one and dedicate that to the script. Again, just follow points 2, 3 and 4 above.
  • DO NOT USE THE SAME DIRECTORY FOR TWO DIFFERENT APPLICATIONS! Create a new one for each new script created.

Follow the steps at "What to do" and watch the "video example" above.

Referenced issues #19 and #23

Back to "Index"

Step by step guide

Before proceeding, make sure you have understood "What to do" and above all "What NOT to do"!

1. Create the script

Use the option -b or --build, example with "obs-studio"

./archimage-cli -b obs-studio

1

this will download and rename the script NEW-junest.sh on your desktop.

2. Add binary name

The script will ask you if you want to specify the name of the binary or leave blank if the name is the same of [PROGRAM]. In most cases we can leave blank, but for some applications, like OBS Studio, the executable name is different, in our case it is obs

2

If you're not sure about thename of the main executable, use https://archlinux.org/packages/ or read the PKGBUILD if the app is hosted on the AUR. By default, the script will use "yay" to install all the programs in JuNest.

3. Add extra dependencies

The script will ask you to add a list of additional packages you want to include into the AppImage (with the syntax app1 app2 app3...)

3

leave blank if no dependency is needed. In our example, we are using Archimage version 4.2, so we don't need add dependencies for obs-studio. Previous versions were less automatic and to build obs-studio we needed to add python. You can add many more packages, according to your needs.

4. Extract dependencies and subdependencies by level

Assign a number to the variable "$extraction_count". The higher the number, the more dependencies will be downloaded separately, the longer the process will be, the bigger the final AppImage package will be... but at the same time the easier our AppImage will work.

4

By default the level is 1, so only the dependencies of the direct dependencies of the application we want to package are extracted. For OBS Studio I set a level of 2, and this is enough to have an AppImage that works out of the box, but only if you include all dependencies and set the "standard configuration". Keep read.

5. Include all dependencies?

Do you want to include all dependencies? Press "y", or leave blank if you want to keep customize (recommended)

5

In my workflows I usually include all dependencies, to remove the extra files after I confirm that the application works.

If you press "N" or leave blank, only the main package will be included, near the libraries and files imported when the script is running.

Please, see the tutorial to learn more on how to investigate on app's malfunctions.

5,5. AUR, whant tu use ChaoticAUR instead? The hidden question

Between question 5 (include all dependencies) and 6 (enable multilib) exists another hidden question

Istantanea_2025-01-12_07-20-18

this question come up only if the program is not hosted on the official repositories, so it come from AUR.

In this case binutils, gzip and base-devel are enabled by default. You can choose to enable ChaoticAUR to save time and resources while compiling the program. For example gimp-git lasts 5 minutes or less from ChaoticAUR, while from AUR it can take 30 minutes or more (with the risk that it fails).

Of course, this question will not come up with obs-studio, since it is on the official Arch Linux repositories.

6. Enable multilib

Want to enable the "multilib" repo? It is usally needed for 32bit libraries, used in programs like WINE and frontends like Bottles

Istantanea_2025-01-12_06-53-42

in our case, we can leave blank or press "N". We don't need 32 bits libraries at all in this case.

7. Enable hardware acceleration for Nvidia users

Do you want to allow hardware acceleration? This will enable Nvidia users to use your application where hardware acceleration is needed

Istantanea_2025-01-12_06-55-57

to learn more on how hardware acceleration works with Archimages, see "Hardware Acceleration".

8. Standard configuration

Standard configuration only enables keywords for Networking and Audio. If you have choosen to include all dependencies at point 5, press "y". This will exit the wizard

8

if you press N or leave blank, you can keep customize the script.

9. binutils and gzip

Junest is a very minimal system, you can choose to include gzip and binutils if you know that none of the previous packages will install them as dependencies.

10. base-devel for AUR

If you need to build something from AUR, enable base-devel with all its related compilers

This is how questions 9 and 10 appear

9-10

11. BINSAVED, LIBSAVED and SHARESAVED

Questions about keywords for binaries in /usr/bin, directories in /usr/share and various files and directories (mostly libraries) in /usr/lib are up to you. For example, if you want to include all Qt related files and directories, write Qt for the question related to the interested path. In my case I included libgallium.so, the search will be done using find and grep

Istantanea_2025-01-12_21-18-09

12. Preset of Audio and Networking keywords

Next two questions are related to a preset of keywords used to check files and libraries for networking and audio, the same that can be enabled in one go at point 8

Istantanea_2025-01-12_07-12-50

Personally I never go further than point 8, and press "y", because the script is simple enough to understand, if you have the patience to read what is written. So i prefer to edit manually my scripts when they are ready.

Ending message

At the end of the wizard you will have a series of suggestions like this

Istantanea_2025-01-12_07-19-02

now you can finally run the script in an empty and dedicated directory.

Again, make sure you have understood "What to do" and above all "What NOT to do"!

Also, see the tutorial to debug and improve your AppImage.


Requirements of an AppImage

To be valid, an AppImage must contain, in the root of the .AppDir directory:

  1. a valid .desktop file (the application one is selected by default, otherwise a custom one is created);
  2. an icon, whose name (without extension) must correspond to the "Icon=" entry of the .desktop file at point 1;
  3. the binary file must be contained in the $PATH (/usr/bin) of the AppImage, and must correspond to the "Exec=" entry of the .desktop file at point 1.

If this requirement is not met, no AppImage will be created.


Archimage structure

An Archimage is a Type3 AppImage, i.e. one that does not require libfuse2 to function.

Unlike many other AppImages, its structure, other than the requirements above, resembles a $HOME directory:

App.AppDir/
  |
  |_/App.desktop
  |
  |_/app.png
  |
  |_/.cache/
  |
  |_/.local/share/junest/
  |
  |_/.junest/

Hidden directories are those used in a normal Junest installation:

  • ".junest" contains the Arch Linux system;
  • ".local/share/junest" contains the JuNest files to start Arch Linux in a container;
  • ".cache" is usually empty and used by YAY during the temporary JuNest session.

The Archimage is first built, and then reassembled with only the essential files indicated in the script you created.


Test the AppImage

Once the script has finished and the AppImage has been created, run the AppImage from the terminal, and check that there are no errors (e.g. libraries not found, missing dependencies...):

./Sample-1.2.3-x86_64.AppImage

For more verbose output, use LD_DEBUG, like this:

LD_DEBUG=libs ./Sample-1.2.3-x86_64.AppImage

to see the missing libraries, or

LD_DEBUG=files ./Sample-1.2.3-x86_64.AppImage

to see the missing files.

I redirect you to the guide on the usage of LD_DEBUG, at https://www.bnikolic.co.uk/blog/linux-ld-debug.html

Dotfiles tip

To not flood your $HOME with dotfiles, I recommend creating a .home directory with the same name as the AppImage:

mkdir Sample-1.2.3-x86_64.AppImage.home
./Sample-1.2.3-x86_64.AppImage

I suggest you empty it or remove/recreate it at the end of each test, in order to rewrite the dotfiles using a clean configuration.

Repeat the build

If you encounter any problems after testing, manually edit the script by adding dependencies or keywords in the respective listed variables, then run the script again to build the AppImage.

./sample-junest.sh

This will repeat the construction of the AppImage starting from the shortcomings of the Arch Linux container.

On-screen messages will tell you what's happening.

Wait until the end and try the AppImage again.

Run the tests until you get the desired result.


Back to "Index"

Tutorial

This is a step-by-step tutorial on how to create an Archimage correctly. To write this one I tried to help a user into a comment, so I decided to publish it here too, with the same videos in real time.

In this example I'll build "Signal", available in Arch Linux as "signal-desktop", in "extra" (not an AUR package).

To create the basic script I'll use a standard configuration:

  1. name: signal-desktop
  2. name binary: leave blank, its the same
  3. dependences: none
  4. extraction level: 1, default... leave blank. Whit only one level, the app will be smaller, but will not easily run at first go (for the sake of this tutorial)
  5. include all dependences: y
  6. multilib: nope, leave blank
  7. hardware acceleration: nope, leave blank
  8. use defaults: y

like this:

simplescreenrecorder-2025-01-12_07.47.28.mkv.mp4

Once I created the script, I create a "tmp" directory (you can name it the way you want) and I put the script into it.

I run the script and after 2 minutes I got the AppImage.

The AppImage is 296 MB. Here is what happens when I run it:

simplescreenrecorder-2024-10-11_21.19.40.mkv.mp4

as expected, it does not work at first attempt. To fix it you can start to read the logs and see what files are missing, like this

simplescreenrecorder-2024-10-11_21.21.17.mkv.mp4

it is looking for a missing module named "xapp-gtk3-module", contained into a package to search on Google (or in my case via "Startpage"), in this case the package is "xapp". You can enter the page of the package and read the content, under "Package content".

All you need to do is to take note of the missing package and then add to dependences, like this:

simplescreenrecorder-2024-10-11_21.25.28.mkv.mp4

and as you can see, "xapp" is downloaded and then it wil be extracted with all the other packages listed during this process in the "deps" directory.

Now the AppImage is increased of 0,1 MB, let we see if it works...

simplescreenrecorder-2024-10-11_21.28.40.mkv.mp4

also this time it is not working, but I've found that there is a missing library "libgnomekbdui", contained in the "libgnomekbd" package... so I'll do the same as I did with xapp.

Now the package is 296,2 MB... let we see if it runs...

simplescreenrecorder-2024-10-11_21.34.44.mkv.mp4

this time it is missing the library "libudev.so", I'll add the keyword "libudev" to $LIBSAVED, to fetch all files under /usr/lib containing this keyword, for this will be added all depending libraries and it too will be bundled in the AppImage.

In case it is not saved, search the package containing that library as I did with "xapp" and "libgnomekbd".

Now the package is 296,3 MB... let se again:

simplescreenrecorder-2024-10-11_21.40.48.mkv.mp4

Magic!

If the app works, you are good with it. Anyway it is still suggested to find missing libraries t mede it work as better as you can.

If you feel that the package is too big, use a tool like Baobab or "du" to find the big files or the ones that you think are unneeded.

You can also disable/comment the rsync command referencing to the content of the "deps" directory, not to include them all, and add only the keyworkd of missing libraries you will see usind LD_DEBUG, one by one.

To test the debloating, sun theAppRun script into the AppDir directory, it will run the program as it were the AppImage. Try to move elsewhere all files you think are unneeded, run the AppRun and see if it works. It the app still works without the files and directories you moved, take note of what you can remove and add the commands in the script, maybe under the "_remove_more_bloatwares" function.

If you do all this correctly, the package will be even smaller.


Back to "Index"

Hardware Acceleration

If you are an Nvidia user, hardware accelleration is provided by Conty. At first start it will copy Nvidia libraries locally to allow the builtin Arch Linux container the use of hardware accelleration.

According to the Conty project, the drivers will be placed in a "Conty" directory located in $HOME/.local/share. If you already use a Conty container or run other Archimages v4 or higher, you will be able to use the same drivers.

The check is enabled in the AppRun, the script inside the AppImage, using the variable NVIDIA_ON with a value equal to 1. To disable it, simply assign a different value to this variable, for example 0. The creators of the AppImage will be able to decide whether to enable it during the creation of the script, via archimage-cli, from version 4 onwards, or they can enable it manually.

  • Archimage v4 was able to download a script that used a mini conty.sh to compile the Nvidia drivers using the official online installer, and it took a few minutes to complete the process
  • Archimage v4.1 instead is able to intercept the drivers installed on the system and copy them locally, taking less than a second

It is recommended to keep your Archimages up to date with the portion of the code available in new releases.

Click here to see the part of the AppRun that handles Nvidia drivers
[ -z "$NVIDIA_ON" ] && NVIDIA_ON=1
if [ "$NVIDIA_ON" = 1 ]; then
   DATADIR="${XDG_DATA_HOME:-$HOME/.local/share}"
   CONTY_DIR="${DATADIR}/Conty/overlayfs_shared"
   [ -f /sys/module/nvidia/version ] && nvidia_driver_version="$(cat /sys/module/nvidia/version)"
   if [ -n "$nvidia_driver_version" ]; then
      mkdir -p "${CONTY_DIR}"/nvidia "${CONTY_DIR}"/up/usr/lib "${CONTY_DIR}"/up/usr/share
      nvidia_data_dirs="egl glvnd nvidia vulkan"
      for d in $nvidia_data_dirs; do [ ! -d "${CONTY_DIR}"/up/usr/share/"$d" ] && ln -s /usr/share/"$d" "${CONTY_DIR}"/up/usr/share/ 2>/dev/null; done
      [ ! -f "${CONTY_DIR}"/nvidia/current-nvidia-version ] && echo "${nvidia_driver_version}" > "${CONTY_DIR}"/nvidia/current-nvidia-version
      [ -f "${CONTY_DIR}"/nvidia/current-nvidia-version ] && nvidia_driver_conty=$(cat "${CONTY_DIR}"/nvidia/current-nvidia-version)
      if [ "${nvidia_driver_version}" != "${nvidia_driver_conty}" ]; then
         rm -f "${CONTY_DIR}"/up/usr/lib/*; echo "${nvidia_driver_version}" > "${CONTY_DIR}"/nvidia/current-nvidia-version
      fi
      /sbin/ldconfig -p > "${CONTY_DIR}"/nvidia/host_libs
      grep -i "nvidia\|libcuda" "${CONTY_DIR}"/nvidia/host_libs | cut -d ">" -f 2 > "${CONTY_DIR}"/nvidia/host_nvidia_libs
      libnv_paths=$(grep "libnv" "${CONTY_DIR}"/nvidia/host_libs | cut -d ">" -f 2)
      for f in $libnv_paths; do strings "${f}" | grep -qi -m 1 "nvidia" && echo "${f}" >> "${CONTY_DIR}"/nvidia/host_nvidia_libs; done
      nvidia_libs=$(cat "${CONTY_DIR}"/nvidia/host_nvidia_libs)
      for n in $nvidia_libs; do libname=$(echo "$n" | sed 's:.*/::') && [ ! -f "${CONTY_DIR}"/up/usr/lib/"$libname" ] && cp "$n" "${CONTY_DIR}"/up/usr/lib/; done
      libvdpau_nvidia="${CONTY_DIR}/up/usr/lib/libvdpau_nvidia.so"
      if ! test -f "${libvdpau_nvidia}*"; then cp "$(find /usr/lib -type f -name 'libvdpau_nvidia.so*' -print -quit 2>/dev/null | head -1)" "${CONTY_DIR}"/up/usr/lib/; fi
      [ -f "${libvdpau_nvidia}"."${nvidia_driver_version}" ] && [ ! -f "${libvdpau_nvidia}" ] && ln -s "${libvdpau_nvidia}"."${nvidia_driver_version}" "${libvdpau_nvidia}"
      [ -d "${CONTY_DIR}"/up/usr/lib ] && export LD_LIBRARY_PATH="${LD_LIBRARY_PATH}":"${CONTY_DIR}"/up/usr/lib:"${LD_LIBRARY_PATH}"
      [ -d "${CONTY_DIR}"/up/usr/share ] && export XDG_DATA_DIRS="${XDG_DATA_DIRS}":"${CONTY_DIR}"/up/usr/share:"${XDG_DATA_DIRS}"
   fi
fi

For the existing Archimages, its enough to add this part to the AppRun.

By default the value inside the templates and AppRuns is set to "0"

NVIDIA_ON=0

NOTE, make sure your release has Archimage version 4.1 or higher in the file name.


Back to "Index"

Compared to classic AppImage construction

In the past AppImages were built using .deb packages or guessing instructions to make them work. With the "ArchImage" method all you have to do is the reverse, i.e. "delete" what is no longer needed.

For example, an OBS Studio ArchImage equals 650MB in total, I managed to get it to 260MB by removing what wasn't necessary, while now (since Archimage2.x was released) is about 180MB.

This is a list of the AppImages I've built until I wrote this brief guide:

Advantages

  • compatibility with all versions of Linux starting from kernel 2.6, therefore also older distributions than those normally indicated by the classic AppImage developers;
  • easy and immediate compilation;
  • AppRun script very minimal and easy to configure;
  • all programs for Arch Linux within AppImage's reach, therefore one of the most extensive software parks in the GNU/Linux panorama.

Disadvantages

  • the AppImage can be bloated if you don't set a list of removable items manually

Drafts

You can download some experimental scripts made with this tool and to which I have not dedicated a repository (also because I have too many) at the following link:

https://github.com/ivan-hc/ArchImage/tree/main/drafts

in my experiments, if I uploaded them here, it means that they work quite well or at least start the graphical interface. I have not looked into their operation. If you want, you can download them and modify them to your liking, or even open a dedicated repository.


Files removed by default

The following function is responsible of removals of unneeded files and directories, you can find it to the end of the script

_remove_more_bloatwares() {
	etc_remove="makepkg.conf pacman"
	for r in $etc_remove; do
		rm -Rf ./"$APP".AppDir/.junest/etc/"$r"*
	done
	bin_remove="gcc"
	for r in $bin_remove; do
		rm -Rf ./"$APP".AppDir/.junest/usr/bin/"$r"*
	done
	lib_remove="gcc"
	for r in $lib_remove; do
		rm -Rf ./"$APP".AppDir/.junest/usr/lib/"$r"*
	done
	share_remove="gcc"
	for r in $share_remove; do
		rm -Rf ./"$APP".AppDir/.junest/usr/share/"$r"*
	done
	echo Y | rm -Rf ./"$APP".AppDir/.cache/yay/*
	find ./"$APP".AppDir/.junest/usr/share/doc/* -not -iname "*$BIN*" -a -not -name "." -delete 2> /dev/null #REMOVE ALL DOCUMENTATION NOT RELATED TO THE APP
	find ./"$APP".AppDir/.junest/usr/share/locale/*/*/* -not -iname "*$BIN*" -a -not -name "." -delete 2> /dev/null #REMOVE ALL ADDITIONAL LOCALE FILES
	rm -Rf ./"$APP".AppDir/.junest/home # remove the inbuilt home
	rm -Rf ./"$APP".AppDir/.junest/usr/include # files related to the compiler
	rm -Rf ./"$APP".AppDir/.junest/usr/share/man # AppImages are not ment to have man command
	rm -Rf ./"$APP".AppDir/.junest/usr/lib/python*/__pycache__/* # if python is installed, removing this directory can save several megabytes
	#rm -Rf ./"$APP".AppDir/.junest/usr/lib/libgallium*
	#rm -Rf ./"$APP".AppDir/.junest/usr/lib/libgo.so*
	#rm -Rf ./"$APP".AppDir/.junest/usr/lib/libLLVM* # included in the compilation phase, can sometimes be excluded for daily use
	rm -Rf ./"$APP".AppDir/.junest/var/* # remove all packages downloaded with the package manager
}

it contains 4 variables:

  • etc_remove to remove files in /etc
  • bin_remove to remove files in /usr/bin
  • lib_remove to remove files and directories in /usr/lib
  • share_remove to remove files and directories in /usr/share

it is enough to add the name or the first keywords of the names you want to remove. For example if you add z in share_remove, all directories starting with "z" will be removed. If you add icons/Adwaita/cursors/ in share_remove, all files under /usr/share/icons/Adwaita/cursors/ will be removed.

A known list of big ligraries is also commented in this function (libgallium, libgo.so and libLLVM), uncomment if the app works without them.

The find commands of the abofe function will remove languages and documentation not related to "$BIN" (the binary name of the app, in most cases the value is BIN="$APP", but it may change, depending on the script you have created.


Customize your script

Once you created the script, it is yours and only yours. You can add/remove functions as you like.

Of course, DO IT ON YOUR OWN RISK!


Back to "Index"

Troubleshooting

  1. If the AppImage is already bundled, extract the AppImage using ./*.AppImage --appimage-extract
  2. Execute the AppRun file:
./AppRun

In case you wont to parse dotfiles in your $HOME directory, use the AppDir itself as a custom $HOME, like this:

cd ./*.AppDir
HOME="$(dirname "$(readlink -f $0)")"
./AppRun

It is now possible to read errors related to the application.

For more verbose output, use LD_DEBUG, like this (for example, to know what are the missing libraries):

LD_DEBUG=libs ./AppRun

I redirect you to the guide on the usage of LD_DEBUG, at https://www.bnikolic.co.uk/blog/linux-ld-debug.html

See also

If you have any doubts you can open an issue or search for a solution among the existing ones (here).


Back to "Index"

Credits

This project wont be possible without:


Related projects


ko-fi.com PayPal.me "Index"

About

Build AppImage packages for all distributions but including Arch Linux packages. Powered by JuNest.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages