Libraries and executables
What is a library?
A library consists of:
- name
- (numeric) version number, usually a timestamp like 20180308123401
- (content) hash, uniquely identifying the library
- a list of prerequisite libraries, identified by name+version+hash
- a number of compiled Mix modules
A library lives in:
- the database, as a single record inside the current project, or in
- the database, as a single record outside the current project, or in
- an independent file in qcc format (qcc = QCode container)
An executable has the same format; the two are distinguished by their distinct _rmx_type fields in DB records ("library" and "executable"), but also the isexe field in their headers. The format is defined in code here and here. For both kinds of DB records, the actual bytecode is stored in a subrecord so that you can query just the metadata without pulling in the whole program. (The bytecode field is dataRef.) See DB layout below for details. By convention, the executable has name "$executable", version 0, and hash "x" when we need to use this scheme to refer to something that might be in either a library or the executable. (Note that this version and hash are illegal for libraries.)
When compiled, a library or executable depends on a (possibly empty) set of dependency libraries, which are fixed at a specific version. If you update a library, you should recompile all libraries and executables that use it. There is a special library, "stdlib", which is available directly from the compiler, and is updated when the compiler build is updated. When compiling a library or executable, the current stdlib is saved to the database, so updating the server build does not break linking for existing executables, but once anything has been recompiled the whole app should be, to use a consistent version of the stdlib. It is possible to statically link some or all of the dependency libraries into the executable, or delay linking until load or run time.
Create a library with mixc
$ mixc -app myapp -url <http://localhost:8001> -mklib mylib -directory dir
What it does:
- Scans the directory
dir for .mix files
- Compiles the modules in these files
- Packages everything as a library, and adds it to the current project in the db
- The name of the library is
mylib
- The version is set to a timestamp (but can be overridden)
- The files are also copied into the project
Dependencies:
- every library and every executable is dependent on the standard library
- the standard library is part of the compiler (built into
mixc)
mixc creates a record for the standard library in the db if it is not already present
- a certain version of the compiler is tied to a certain version of the stdlib
- if you upgrade the compiler, you need to rebuild all libraries
- however, this does not apply to executables:
amp can run executables built with old versions of the compiler/stdlib so far the ABI is still compatible
- if you import/push a module that is not available as source code, the compiler searches for the module in a library
- all libraries are searched that have been built with the same version of the compiler
- doesn’t matter whether the lib is in the project or not
- the libraries are added to the list of prerequisites
- if the module is available in several libraries, libraries with higher version number and the same name shadow libraries with lower version numbers
- if there are still several libraries with the searched module, it is undefined which one is taken
- dependencies are recursive but never circular
What does it mean when a library is in the current project?
- member of project = db record of lib references the project record
- the idea is that libraries are part of the project while you are still building them and have the source code
- the source code is also in the project (useful for debugging and displaying errors)
- can wipe out the project with
mixc -clean
- libraries coming from third parties are not part of the project, but you can still put these libs into the db
- normally no source code
- don’t want to delete these libs when cleaning the project as there is no way to rebuild them
- the stdlib is not part of the project
List libraries
$ mixc -app myapp -url <http://localhost:8001> -list-libs
- Outputs a list of libraries (including module names)
- Includes only the latest versions of libs
- Includes only those libs that match
mixc
$ mixc -app myapp -url <http://localhost:8001> -list-all-libs
- Outputs all libs, including outdated and incompatible ones
Create an executable using libraries
$ mixc -app myapp -url <http://localhost:8001> -directory dir