Both "mmake" and "mmc --make" have mechanisms for installing a library to a target given directory. The name of this target directory is often called the install prefix, because the full pathname of all the installed files will include this name as a prefix.
The install process will copy files with the following suffixes to subdirectories of the install target directory. (In the rest of this document, we will refer to this list as the "library suffix list".)
Note that common values of --library-extension include .a and .lib, while common values of --shared-library-extension include .so, .dylib and .dll.
This document is intended to describe where (i.e. in which directories) files with each of the above suffixes are, or should be, installed. Specifically,
The rest of this document will identify these two "scenarios" as LEGACY and PROPOSED respectively.
But before we can get to either of those, we need some background on where these files are stored in workspaces.
When the Mercury project started, we always stored all compiler-generated files, including all files with a suffix in the library suffix list, in the directory that stored the Mercury source files they were derived from. We refer to this directory as the "current directory", since that is the logical place to have as your current directory (in the Unix sense) when working on that code.
As the number of modules in e.g. the compiler directory grew, and as the number of files with different suffixes associated with a given module also grew, the number of files in the current directory became a problem. One problem was simply aesthetics: the output of "ls" in the current directory contained lots of "clutter". Another problem was more serious. Some of the Unix systems we used then had algorithms for filename lookups whose complexity was linear in the number of entries in a directory. This meant that the runtimes of tasks such as generating the .int3 file for each module in the directory was half-quadratic in the number of modules: for each of N modules, each of which had M associated files, the task of looking up that module's directory entry had to scan (on average) at least (N/2)*M other directory entries.
We implemented the --use-subdirs option to solve both problems. (The second problem has since gone away, since pretty much all modern versions of Unix, and other OSs, have file lookup algorithms whose complexity is logarithmic in the number of entries in the directory, achieved by using data structures such as B-trees. The first problem still remains.) When --use-subdirs is specified, the compiler still puts the kinds of files that are explicitly intended to be looked at by the programmer, such .err files and HLDS/MLDS dumps, into the current directory, but it puts all other kinds of files into another directory.
The compiler associates with each extension an extension directory name. It originally created this nam from the extension itself, by deleting the initial dot and adding a final "s". For example, for the .int3 extension, the extension directory name is "int3s". The final "s" is intended to denote the plural form of the extension. This is because with --use-subdirs, the compiler stores all files with e.g. the .int3 extension in the directory named "Mercury/int3s".
We have since created some exceptions from the above rule. For example, for the .class extension, the extension directory name is "classes", replacing the old, ugly ".classs" (sic).
The general rule is: if ExtDir is the extension directory name for the extension .Ext, then for a module whose fully qualified module name is Fqmn, the compiler will put its .Ext file into "Mercury/ExtDir/Fqmn.Ext".
This scheme works well if you do all your work in the same grade. If you want to work on the same code in two or more different grades, e.g. because you want to switch to a debug grade to hunt down a bug, or if you want to switch back to the original grade once you have found the bug, you have a problem: you have to nuke the Mercury directory and rebuild it from scratch every time you want to switch grade. This takes a nontrivial amount of time, and therefore usually takes you any out of any "flow" state you had. The --use-subdirs option does not help with this problem at all.
We therefore added another option, --use-grade-subdirs, to solve this problem.
There are only three legal combinations of the settings of these options:
The fourth, illegal combination, --no-use-subdirs and --use-grade-subdirs, is actually unreachable, because --use-grade-subdirs implicitly implies --use-subdirs.
We classify extensions into two sets:
For the non-grade-specific extensions, the compiler puts their files
LEGACY For the grade-specific extensions, the compiler puts their files
where Grade is a canonical representation of the grade and TargetArch is a canonical representation of the target ISA (instruction set architecture), with both being in a form that is suitable as a directory name component.
Note that while some kinds of files with grade-specific extensions, such as .o, are dependent on the target ISA, files with other grade-specific extensions, such as .mih, are NOT, so including the TargetArch component in their path names is overkill.
PROPOSED For the grade-specific extensions, the compiler should put their files
The point of using "MercurySystem" instead of "Mercury" is to allow LEGACY and PROPOSED directory structures to coexist for the transition period. After that period is over, we can go back to using just "Mercury".
Note that to prepare for the implementation of the PROPOSED install structure, compiler/file_names.m makes a distinction between non-architecture-specific and architecture-specific extensions. It redefines the term grade-specific (gs) to refer to only the former, and introduces the term grade-and-architecture-specific (gas) to refer to the latter.
The following shows, for each kind of file we install for a library, where those files are installed both in the LEGACY and in the PROPOSED install directory structures.
LEGACY Prefix/lib/mercury/ints Prefix/lib/mercury/ints/Mercury/int0s PROPOSED Prefix/MercurySystem/int0s
LEGACY Prefix/lib/mercury/ints Prefix/lib/mercury/ints/Mercury/ints PROPOSED Prefix/MercurySystem/int1s
LEGACY Prefix/lib/mercury/ints Prefix/lib/mercury/ints/Mercury/int2s PROPOSED Prefix/MercurySystem/int2s
LEGACY Prefix/lib/mercury/ints Prefix/lib/mercury/ints/Mercury/int3s PROPOSED Prefix/MercurySystem/int3s
LEGACY Prefix/lib/mercury/ints Prefix/lib/mercury/ints/Mercury/opts Prefix/lib/mercury/ints/Grade Prefix/lib/mercury/ints/Grade/Mercury/opts PROPOSED Prefix/MercurySystem/opts/Grade
NOTE: LEGACY installs .opt files, which are grade-specific, to non-grade-specific directories. The non-grade-specific directory will end up with the .opt file for the default grade. If this directory is before the grade-specific directory in the search path, searches in non-default grades may nevertheless find the .opt file for the default grade.
LEGACY Prefix/lib/mercury/ints Prefix/lib/mercury/ints/Mercury/module_deps PROPOSED Prefix/MercurySystem/module_deps/Grade
LEGACY Prefix/lib/mercury/ints/Grade Prefix/lib/mercury/ints/Grade/Mercury/analyses PROPOSED Prefix/MercurySystem/analyses/Grade
LEGACY Prefix/lib/mercury/inc Prefix/lib/mercury/ints Prefix/lib/mercury/ints/Mercury/mhs PROPOSED Prefix/lib/mercury/inc (possibly, for backward compatibility) Prefix/MercurySystem/mhs
LEGACY Prefix/lib/mercury/lib/Grade/inc Prefix/lib/mercury/lib/Grade/inc/Mercury/mihs Prefix/lib/mercury/lib/ints Prefix/lib/mercury/lib/ints/Mercury/mihs PROPOSED Prefix/lib/mercury/inc/Grade/inc (possibly, for backward compatibility) Prefix/MercurySystem/mihs/Grade
NOTE: LEGACY installs .mih files, which are grade-specific, to non-grade-specific directories. The non-grade-specific directory will end up with the .mih file for the grade that is installed last. (The install process differs between .opt and .mih files.) If the non-grade-specific directory is before the grade-specific directory in the search path, searches in not-installed-last grades may nevertheless find the .opt file for the installed-last grade.
Note that the install locations marked as "possible" for backward compatibility are not yet implemented.
LEGACY Prefix/lib/mercury/modules/Grade PROPOSED Prefix/MercurySystem/inits/Grade
LEGACY Prefix/lib/mercury/lib/Grade PROPOSED Prefix/MercurySystem/lib/Grade/TargetArch
LEGACY Prefix/lib/mercury/lib/Grade PROPOSED Prefix/MercurySystem/lib/Grade
LEGACY Prefix/lib/mercury/lib/Grade PROPOSED Prefix/MercurySystem/lib/Grade
The following shows the overall structure of a library install directory under the PROPOSED rules. This table uses main_module to refer to the top module of the library, and moduleN to refer to any module of the library, whether it is the top module or not. As above, LE and SLE stand for the values of the --library-extension and --shared-library-extension options.
// non-grade-specific files Prefix/MercurySystem/int0s/ moduleN.int0 Prefix/MercurySystem/int1s/ moduleN.int Prefix/MercurySystem/int2s/ moduleN.int2 Prefix/MercurySystem/int3s/ moduleN.int3 Prefix/MercurySystem/mhs/ moduleN.mh // grade-specific but not architecture-specific files Prefix/MercurySystem/opts/ Grade/moduleN.opt Prefix/MercurySystem/trans_opts/ Grade/moduleN.trans_opt Prefix/MercurySystem/module_deps/ Grade/moduleN.module_dep Prefix/MercurySystem/analyses/ Grade/moduleN.analysis Prefix/MercurySystem/mihs/ Grade/moduleN.mih Prefix/MercurySystem/inits/ Grade/main_module.init Prefix/MercurySystem/lib/ Grade/main_module.jar Prefix/MercurySystem/lib/ Grade/main_module.dll // grade-specific and architecture-specific files Prefix/MercurySystem/lib/ Grade/TargetArch/main_module.LE Prefix/MercurySystem/lib/ Grade/TargetArch/main_module.SLE
The principles governing the PROPOSED directory structure are the following.
XXX The above structure violates this for Prefix/MercurySystem/lib/Grade, since it would contain both e.g. main_module.dll, a regular file, and TargetArch, a directory.
XXX Should we replace Grade/TargetArch with e.g. Grade:TargetArch? Or should we install .jar and .dll files to Prefix/MercurySystem/jars/Grade/main_module.jar and Prefix/MercurySystem/dlls/Grade/main_module.dll respectively? The latter solution seems cleaner.
For any directory Dir named in such an argument, when looking for Fqmn.Ext, mmc would search
A simple way to do this would be for the --workspace-library-dir option to be a special option that adds its argument to both the list maintained by --mercury-library-dir and to a second, separate list. After getopt has done its job, we would convert the second list to a set. Thereafter, we would search the --mercury-library-dir list almost as usual, with the one difference being that we would treat any entry on that list that is also in this set as being an argument of --workspace-library-dir.
XXX INSTALL Many of these files contain almost-duplicate copies of the same entries. It should be possible to factor out their commonalities.
XXX INSTALL There may be other files, such as bindist/bindist.Makefile.in.