📜 ⬆️ ⬇️

Preparing your Inferno applications for standalone installation

So, you wrote a certain application on Limbo , and want to install it on another machine, or distribute via the Internet. Most likely, where this OS Inferno application will be installed is not installed. It is bitter, but more than likely. :) What to do? Educate users of your application to install and configure OS Inferno? Include the complete installation of Inferno (up to 250 MB) in the archive with each of your applications? No, it's much easier!

Let's see how you can cut Inferno to the minimum required for your application to work. To do this, you need to figure out what happens when you start emu - how OS Inferno boots.

Download OS Inferno


The emu emu already contains the OS kernel, all drivers, and the Dis virtual machine . When it starts, it needs the -r parameter to transfer the OS Inferno root directory ( emu itself is not required to be inside this directory, so you can use one emu with several different OS Inferno installations — different installed applications and libraries).

emu loaded, emu simply starts /dis/emuinit.dis (all paths are relative to the root directory of the OS Inferno), which should initialize the system and start either the application or shell passed by the emu parameter. (The Linux kernel does the same thing when, by booting itself, it simply transfers control to / sbin / init.) If you examine the emuinit sources, it turns out that “initializing the system” is very loud, everything is very simple in Inferno, even compared to with the most simplified initialization of Linux .
')
It's all. :) Thus, to obtain a standalone OS Inferno installation with your application, the following files and directories are necessary and sufficient:

Example: Hello World


Let's start with a simple application, without any dependencies. Here it is:
 implement HelloWorld; include "sys.m"; include "draw.m"; HelloWorld: module { init: fn(nil: ref Draw->Context, nil: list of string); }; init(nil: ref Draw->Context, nil: list of string) { sys := load Sys Sys->PATH; sys->print("Hello World!\n"); } 


Save it to helloworld.b , run limbo helloworld.b and you will get helloworld.dis :
 ; ls -l --rw-r--r-- U 0 powerman users 265 Oct 25 02:54 helloworld.b --rw-r--r-- U 0 powerman users 147 Oct 25 02:54 helloworld.dis 

Now let's define the dependencies:
 ; disdep helloworld.dis ; disdep /dis/emuinit.dis /dis/lib/arg.dis /dis/sh.dis /dis/lib/bufio.dis /dis/lib/env.dis /dis/lib/readdir.dis /dis/lib/filepat.dis /dis/lib/string.dis 

helloworld.dis no dependencies, although it uses the Sys module. The fact is that some basic modules are written in C and are built right into emu, including Sys. emuinit.dis many dependencies, but there are only two straight lines - arg and sh. The rest is needed for sh. And sh itself is needed only if we did not specify emu application to be emu parameter. Therefore, we can limit ourselves to one library arg. Go:
 $ mkdir inferno-standalone $ mkdir inferno-standalone/dis $ mkdir inferno-standalone/dis/lib $ cd inferno-standalone/ $ SRC=/usr/local/inferno/ $ cp $SRC/Linux/386/bin/emu ./ $ cp $SRC/dis/emuinit.dis dis/ $ cp $SRC/dis/lib/arg.dis dis/lib/ $ cp $SRC/usr/powerman/helloworld.dis ./ $ ./emu -r. helloworld.dis Hello World! $ 

So, we have standalone installation of helloworld, ready to work on any system with Linux (for other OS you just need to take emu compiled for these OS). Let's see how much it weighs. (By the way, emu under Linux doesn’t strip by default, so it can be noticeably reduced.)
 $ strip emu $ find -type f -printf "%8s %p\n" 1562504 ./emu 147 ./helloworld.dis 652 ./dis/lib/arg.dis 1518 ./dis/emuinit.dis 

Example: Calculator


Now let's take a normal application. For example, a calculator included in standard utilities Inferno. He is heaped enough , by the way.
 ; disdep /dis/calc.dis /dis/lib/arg.dis /dis/lib/bufio.dis /dis/lib/daytime.dis /dis/lib/string.dis /dis/lib/rand.dis $ cp $SRC/dis/calc.dis ./ $ cp $SRC/dis/lib/{bufio,daytime,string,rand}.dis dis/lib/ $ find -type f -printf "%8s %p\n" 32567 ./calc.dis 1562504 ./emu 147 ./helloworld.dis 4630 ./dis/lib/bufio.dis 652 ./dis/lib/arg.dis 209 ./dis/lib/rand.dis 4051 ./dis/lib/string.dis 4701 ./dis/lib/daytime.dis 1518 ./dis/emuinit.dis $ ./emu -r. calc.dis 1+2 3 exit $ ./emu -r. calc.dis 1+2 3 $ 

Wait, what about the emu dependencies?


Yes, there is such a moment. To run emu on another machine there must be all the necessary emu libraries. Fortunately, there are only two libraries. Unfortunately, both refer to X - this is libX11 and libXext.

Basically, these libraries are perfectly set up without having to drag Xorg completely. This is what would have to be installed on a server with Gentoo Linux:
 # emerge -pv x11-libs/libX11 x11-libs/libXext These are the packages that would be merged, in order: Calculating dependencies... done! [ebuild N ] x11-misc/util-macros-1.1.5 47 kB [ebuild N ] x11-proto/xproto-7.0.10 140 kB [ebuild N ] x11-proto/inputproto-1.4.2.1 47 kB [ebuild N ] x11-proto/kbproto-1.0.3 57 kB [ebuild N ] x11-proto/xf86bigfontproto-1.1.2 37 kB [ebuild N ] x11-libs/xtrans-1.0.3 USE="-debug" 101 kB [ebuild N ] x11-proto/bigreqsproto-1.0.2 36 kB [ebuild N ] x11-proto/xcmiscproto-1.1.2 36 kB [ebuild N ] x11-proto/xextproto-7.0.2 67 kB [ebuild N ] x11-libs/libXau-1.0.3 USE="-debug" 225 kB [ebuild N ] x11-libs/libXdmcp-1.0.2 USE="-debug" 216 kB [ebuild N ] x11-libs/libX11-1.1.4 USE="-debug -ipv6 -xcb" 1,540 kB [ebuild N ] x11-libs/libXext-1.0.3 USE="-debug" 256 kB Total: 13 packages (13 new), Size of downloads: 2,799 kB 

But for working on a network application server (which has no GUI), these libraries are absolutely not needed. After all, I can even debug this application in a graphical debugger on my workstation by simply mounting the /prog/ directory from the server where the application is running. To solve this problem, you can use a special version of emu - emu-g , which is built and works without libX11 and libXext.

emu-g

To build emu-g you need to run
 mk CONF=emu-g install 

After that, you can run emu-g instead of emu (by the way, emu-g weighs only 700KB after striping):
 $ emu-g ; pwd /usr/powerman ; wm/wm wm: cannot load $Draw: module not built-in ; 


PS The inferno-strandalone directory in .tgz took 666 KB from me. :-)

Update: added emu-g info.

Source: https://habr.com/ru/post/43180/


All Articles