


To develop useful multi-file applications, you will also need to know how to compile a stand-alone executable which can be invoked from the command line or scripts like any other Linux executable.
In this section we will present a complete worked-out example of implementing a simple clone of the Linux factor program, which prints out the prime factorization of each argument it is given.
Our solution consists of the following four files:
Using these we will compile a factor executable image using the standard Mythryl /usr/bin/build-an-executable-mythryl-heap-image script which gets installed with the other standard Mythryl programs when you do a make install.
The following transcript shows the contents of the required files and also the compilation process:
linux$ cat factor.api
api Factor {
factors: Int -> List(Int);
};
linux$ cat factor.pkg
package factor {
fun factor_helper (i, trial_divisor, known_factors) = {
if (trial_divisor > i) reverse known_factors;
else
if (i % trial_divisor != 0) factor_helper (i, trial_divisor + 1, known_factors);
else factor_helper (i/trial_divisor, trial_divisor, trial_divisor ! known_factors);
fi;
fi;
};
fun factors( i ) = {
if (i <= 1) [i];
else factor_helper (i, 2, []);
fi;
};
};
linux$ cat main.pkg
package main: api {
main: ((String, List( String ))) -> winix__premicrothread::process::Status;
}
{
include trap_control_c; # trap_control_c is from src/lib/std/trap-control-c.pkg
fun print_to_stderr msg
=
file::write
(
file::stderr,
string::cat msg
);
fun print_factors( number, factors ) = {
printf "%d:" number;
map (printf " %d") factors;
printf "\n";
};
fun factor_number( arg ) = {
number = the (int::from_string arg);
print_factors( number, factor::factors( number ) );
};
fun factor_args args = {
apply factor_number args;
};
fun main (name, args) = {
fun run_program ()
=
factor_args args;
{ catch_interrupt_signal run_program;
winix__premicrothread::process::success;
}
except
CONTROL_C_SIGNAL
=>
{ print_to_stderr [name, ": Interrupt\n"];
winix__premicrothread::process::failure;
};
any =>
{ print_to_stderr [ name,
": uncaught exception ",
exceptions::exception_message any,
"\n"
];
winix__premicrothread::process::failure;
};
end ;
};
};
linux$ cat factor.lib
LIBRARY_EXPORTS
api Factor
pkg factor
pkg main
LIBRARY_COMPONENTS
$ROOT/src/lib/std/standard.lib
factor.api
factor.pkg
main.pkg
linux$ build-an-executable-mythryl-heap-image factor.lib main::main
_build-an-executable-mythryl-heap-image: Starting.
_build-an-executable-mythryl-heap-image: main=main::main (III)
_build-an-executable-mythryl-heap-image: main=main::main (after sed)
_build-an-executable-mythryl-heap-image: Listing tmp-makelib-pid-26077-export.pkg:
pkg xyzzy_plugh { my _ = lib7::spawn_to_disk ("factor", main::main); };
_build-an-executable-mythryl-heap-image: Listing .lib file:
SUBLIBRARY_EXPORTS pkg xyzzy_plugh SUBLIBRARY_COMPONENTS $ROOT/src/lib/std/standard.lib factor.lib tmp-makelib-pid-26077-export.pkg
_build-an-executable-mythryl-heap-image: Doing: "/usr/bin/mythryld" --build-an-executable-mythryl-heap-image "factor.lib" "tmp-makelib-pid-26077-export.lib" "factor" "tmp-makelib-pid-26077.COMPILED_FILES_TO_LOAD" "tmp-makelib-pid-26077.LINKARGS"
parse/libfile-parser-g.pkg: Reading make file factor.lib on behalf of <toplevel>
app/makelib/compilable/thawedlib-tome.pkg: Parsing source file factor.api
app/makelib/compilable/thawedlib-tome.pkg: Parsing source file factor.pkg
app/makelib/compilable/thawedlib-tome.pkg: Parsing source file main.pkg
.../compile/compile-in-dependency-order-g.pkg: Compiling source file factor.api to object file factor.api.compiled
.../compile/compile-in-dependency-order-g.pkg: Compiling source file factor.pkg to object file factor.pkg.compiled
.../compile/compile-in-dependency-order-g.pkg: Compiling source file main.pkg to object file main.pkg.compiled
parse/libfile-parser-g.pkg: Reading make file tmp-makelib-pid-26077-export.lib on behalf of <toplevel>
parse/libfile-parser-g.pkg: Reading make file factor.lib on behalf of <toplevel>
app/makelib/compilable/thawedlib-tome.pkg: Parsing source file tmp-makelib-pid-26077-export.pkg
.../compile/compile-in-dependency-order-g.pkg: Compiling source file tmp-makelib-pid-26077-export.pkg to object file tmp-makelib-pid-26077-export.pkg.compiled
src/app/makelib/main/makelib-g.pkg: Creating file 'tmp-makelib-pid-26077.COMPILED_FILES_TO_LOAD'
src/app/makelib/main/makelib-g.pkg: Creating file 'tmp-makelib-pid-26077.LINKARGS'
_build-an-executable-mythryl-heap-image: Doing: "/usr/bin/mythryl-ld" `cat "tmp-makelib-pid-26077.LINKARGS"`
----------------------------------------------------
bin/mythryl-ld: Starting
bin/mythryl-ld: Exec()'ing /pub/home/cynbe/src/mythryl/mythryl7/mythryl7.110.58/mythryl7.110.58/bin/mythryl-runtime-intel32 --runtime-compiledfiles-to-load=tmp-makelib-pid-26077.COMPILED_FILES_TO_LOAD --runtime-heap=mythryld
src/c/main/load-compiledfiles.c: Writing load log to mythryld-26088.load.log
src/c/main/load-compiledfiles.c: Reading file tmp-makelib-pid-26077.COMPILED_FILES_TO_LOAD
.../lib/heap/export-fun.c: Writing executable (heap image) /pub/home/cynbe/src/mythryl/mythryl7/mythryl7.110.58/mythryl7.110.58/factor
linux$ ./factor 23 24
23: 23
24: 2 2 2 3
linux$
The above code is largely self-explanatory; you should have little difficulty adapting it to your own needs.
For your convenience, the above code is shipped in the src/app/tut/factor/ directory in the Mythryl source code distribution.
For a serious application, you will probably want to put the illustrated build-an-executable-mythryl-heap-image call in your application’s Linux Makefile. (The Mythryl makelib is not intended to replace Linux make, but rather to work with it in complementary fashion. Each does well things the other does poorly.)
The main.pkg file is mostly boilerplate that you can use unchanged in your own application except for changing the run_program function to run the code appropriate to your application.
A serious application will have many more source files and perhaps application-specific .lib libraries. Just add them to the factor.lib file (presumably appropriately renamed for your application) and Mythryl’s makelib will take care of compiling everything in the right order. (Unlike Linux make, Mythryl makelib deduces needed dependency relationships directly from the source code.)
A nontrivial application will probably support various command line options. You may wish to process them using the process_commandline package, which is a Mythryl port of the GNU getopt C package.


