PeaceFounder / AppBundler.jl

Bundle your Julia application
MIT License
53 stars 3 forks source link

Clarify README #3

Open PallHaraldsson opened 9 months ago

PallHaraldsson commented 9 months ago

Hi,

Reading through the README, I think the package works on all three platforms to make (GUI) apps already, but I want to know does it for sure make one file (for each) that you can download and install by double-clicking by end-users, in one step and it installs and runs? At least on Windows (and also for Linux)?

AppBundler expects an application folder which contains main.jl, Project.toml and Manifest.toml. The application entry point is the main.jl, which allows starting the application with julia --project=. main.jl from the project directory. A Project.toml contains many adjustable template variables under a [bundle] section.

That's all you need at a minimum, and I think at installation the dependencies will be downloaded for you? Or bundled with? I've seen suggested that Julia itself could NOT be bundled rather referred to. I'm ok with whatever that works for now, but cool if the bundled could be really small. In all cases source code is distributed (compressed) and you end up with it decompressed, not compiled, but that's a possible add-on with PackageCompiler.jl? And it doesn't make your work redundant, more like they are complementary and could work together.

The configuration of the bundle sits in a meta folder from where files take precedence over the AppBunlder recepies folder.

2 typos: AppBunlder recepies -> AppBundler recipes

bundle_app(MacOS(:x86_64), "MyApp", "build/MyApp-x64.app")

That implies 64-bit, x86. I don't care too much about 32-bit, on Windows, I suppose it could be done and ARM build etc. for Macs. x86_64 may be safer for now, also to work for older macs. Can you make a "fat binary" i.e. the first step is x86 since good enough, and it dynamically chooses ARM Julia or x86 Julia?

For Linux, the extension .snap and Windows .zip for destination determines whether the output is compressed, which can be overridden by compress=false in the keyword arguments.

This is a bit unclear, .snap is compressed. And .zip is too (on all platforms) but you get a MSIX bundle on Windows?! I suppose it is compressed and .snap and all you distribute, so when do you want uncompressed?

The resulting bundles can be easily tested on the resulting platforms. The testing phase works without any postprocessing as follows:

You can just double-click to test (with or) without postprocessing on at least MacOS (so then since it works, why does it need any postprocessing?). I understand the rest as you must do post-processing on the platform, as a developer, not end-user. But hypothetically it would not be needed, could be done on e.g. Linux for a Windows bundle.

Note that you will face difficulties when using AppBundler from Windows for Linux, macOS and other UNIX operating systems, as Windows does not have a concept of execution bit. By hand, you could set chmod +x to every executable on the resulting platform. Technically, this can be resolved by directly bundling files into a tar archive and processing the incoming archives without extraction, but this will not happen. Thus, it is better to use WSL when bundling for other platforms on Windows.

I suggest something like "AppBundler apps made with Windows for other platforms: Linux macOS and other UNIX operating systems. Since Windows".. At first I read as from "Windows for Linux" as if that were a thing, you confusing with WSL. or wine. You mean you can "cross-compile" except no compilation done, but can you also make one bundle that works on app platforms?

For snap, it is also worth mentioning the snap try myapp command, which allows one to install an application without squashing.

Rather without unsquashing (use unsquashfs)? Or did that refer to mksquashfs?

For Windows, one has to install makappx, signtool, and editbin installed with WindowsSDK.

typo for MakeAppx?!

You need those tools, i.e. "cross-compiling" from Linux is maybe not possible, or would work with wine?

Installation of Windows SDK fails.

[I'm unclear why, or only on non-Windows/Parallels, but I think you're saying not a problem.]

Set julia.exe to be Windows application editbin /SUBSYSTEM:WINDOWS myapp\julia\bin\julia.exe

That part is to make it a GUI Windows app (to not get a console window). Since the GUI vs console distinction isn't there on other platforms, can it be stated this works for non-GUI programs too? On non-Windows at least. And on Windows if you skip that step.

JanisErdmanis commented 9 months ago

Hi!

The recommended building environment is Linux and MacOS, which can produce bundles for all other platforms. On Windows, one is recommended to use WSL; otherwise, one is limited to the Windows platform as the destination.

The package works for all three platforms to produce GUI applications. However, the Mac and Windows apps need a post-processing step on their host platform to make one file clickable by end users. I have excessively tested and worked on so that apps run with a single click install.

That's all you need at a minimum, and I think at installation the dependencies will be downloaded for you? Or bundled with?

In all cases source code is distributed (compressed) and you end up with it decompressed, not compiled, but that's a possible add-on with PackageCompiler.jl?

The installation dependencies are bundled with the app so the application can be started in a networkless environment. Also, this is done so that it is possible to run precompilation, which is important to provide a somewhat acceptable end-user experience. Future versions will likely feature an optional package builder script that allows a compilation of the bundles into apps on the respective platforms using PackageCompiler.

I've seen suggested that Julia itself could NOT be bundled rather referred to. I'm ok with whatever that works for now, but cool if the bundled could be really small.

A GUI app bundle is 200 MB in size with a Julia bundle. A lot of work is done by compression on the respective bundle formats. I prefer to bundle Julia as it assures that if one of the platforms experiences a bug, I can reproduce the exact environment on other platforms to know if it was caused by Julia or me, the application developer.

2 typos: AppBunlder recepies -> AppBundler recipes

I will have a look at it.

That implies 64-bit, x86. I don't care too much about 32-bit, on Windows, I suppose it could be done and ARM build etc. for Macs. x86_64 may be safer for now, also to work for older macs. Can you make a "fat binary" i.e. the first step is x86 since good enough, and it dynamically chooses ARM Julia or x86 Julia?

Older Windows versions are unsupported, as I rely on the MSIX package format, which offers some sandboxing capabilities and clean app uninstallation. I don't plan to support other Windows recipes, but if one wishes, AppBundler offers a great starting point for dev-users to implement them on their own.

This is a bit unclear, .snap is compressed. And .zip is too (on all platforms) but you get a MSIX bundle on Windows?! I suppose it is compressed and .snap and all you distribute, so when do you want uncompressed?

To get MSIX to bundle, the building product from AppBundler needs to be post-processed on Windows with makeappx, signtool and editbin. This can't be automated much further as, at the moment, Julia does not offer the ability to do cross-platform compilation/precompilation, and thus, that needs to be done on the host system for a smooth experience.

I understand the rest as you must do post-processing on the platform, as a developer, not end-user. But hypothetically it would not be needed, could be done on e.g. Linux for a Windows bundle.

The bundles for Linux and MacOS can be double-clicked to run. On Windows, the folder hierarchy is such that it can be registered to a system with a single command so it can be run from a start menu. This is useful for debugging purposes, but in general, one would do a post-processing step of the bundles before distributing them to the end users.

Windows for Linux

I meant Windows Subsystem for Linux (WSL). I will correct that in the readme.

For snap, it is also worth mentioning the snap try myapp command, which allows one to install an application without squashing.

This is a useful information for debugging the bundle. One first unsquashfs which then can be tried with snap try command. This is analogous to AppPackage -register AppxManifest.xml on Windows.

typo for MakeAppx?!

Typo indeed.

You need those tools, i.e. "cross-compiling" from Linux is maybe not possible, or would work with wine?

I have had thoughts about this. I guess Wine would have no issues with running these command-line applications. The problem is of a legal nature. Microsoft keeps the rights for distribution of their software; thus, it excludes putting these binaries as an artefact.

An alternative route would be to use open-source alternatives. There seems to be a tool with the name MakeMSIX, which seems to be open source and also usable from Linux, but I no longer can't pinpoint the repo where I saw it. The other thing that would be needed is the edition, which ChatGPT seems to be able to implement in C.

In this scenario, one could probably try to run Julia through Wine to do an optional precompilation/compilation step. This is something which is defientelly worth to be explored in the future to make AppBunder easier to use.

That part is to make it a GUI Windows app (to not get a console window). Since the GUI vs console distinction isn't there on other platforms, can it be stated this works for non-GUI programs too? On non-Windows at least. And on Windows if you skip that step.

I lost what you have meant in this one. Perhaps you can paraphrase.

PallHaraldsson commented 9 months ago

AppBundler.jl offers recipes for building Julia GUI applications in modern desktop application installer formats. It uses Snap for Linux, MSIX for Windows ..

Which is a good thing, i.e. GUI apps. What I mean is that in Linux at least there's no specific executable (ELF) type for GUI and other for non-GUI. Of course you program them very differently but I think your tool, and snap, isn't restricted to GUI apps.

On Windows there IS a specific type for GUI/Windows apps, and why you need editbin. I suppose it could also be used with PackageCompiler.jl and I was curious how people could actually make GUI apps for Windows (without a console window popping up). I was just thinking if non-GUI apps could also be done with your package (or restricted to "GUI"), then without running editbin. It's not something you (or I) need; to know, so not a huge priority. I suppose MSIX is just for Windowed apps anyway.

The installation dependencies are bundled with the app so the application can be started in a networkless environment.

That's great, as a default, and 200 MB, while a big overhead, isn't too uncommon in the modern world...

I prefer to bundle Julia as it assures that if one of the platforms experiences a bug

That's understandable. Julia has reproducible environments, so with a Manifest you could be sure you have the exact dependencies. That also applies to Julia itself, or I think you can point to an exact (stable) version, though probably shouldn't be default to do. If people would use a master Julia, then in theory an exact commit too, though I'm not sure about getting access to them or exact RC.

Windows 7 still has some market share (at least in China), and Windows 10 (but not 11) is still supported with 32-bit, for almost 2 years more. I'm not saying 32-bit or older versions should have any priority. Some apps could still use 32-bit and work on 64-bit too, but 64-bit apps (as the default) will not work on 32-bit.

What should be a priority, is the future; for some, not you, is explore Android (and iOS) Julia apps, for world domination... [Python with e.g. Kivy has worked on iOS, and Python will support iOS officially as a 3rd tier platform for the first time with Python 3.13, according to an interesting PEP on it.]

Then not APK (Google migrating from, though not all others), rather: https://developer.android.com/guide/app-bundle

Publishing with Android App Bundles helps your users to install your app with the smallest downloads possible and increases the compressed download size limit to 200 MB. That is, when a user downloads your app, the total size of the compressed APKs required to install your app (for example, the base APK + configuration APKs) must be no more than 200 MB.