[m-dev.] Determining which grades an installed Mercury compiler supports

Keri Harris keri at gentoo.org
Thu Jul 19 02:28:48 AEST 2018


Hi,

I've run into a couple of interesting issues in how Mercury determines 
which grades it supports. For C grades, the compiler checks for the 
existence of mercury/modules/$grade/mer_std.c, for non-C grades just the 
mercury/modules/$grade directory.

The erlang grade can have problems with this approach since init files 
can be installed into the mercury/module/erlang directory. In 
particular, a problem can arise when a 3rd-party library installs an 
erlang init file, and then Mercury is later reinstalled without support 
for the erlang grade; these residual 3rd-party init files can confuse 
Mercury into believing that it still does support the erlang grade. The 
following sequence of events leads to this:

* compile and install Mercury package such that grade erlang is installed
   - /usr/lib/mercury/modules/erlang/mer_std.init is created

* compile and install mercury_fixed library from mercury/extras/fixed
   - /usr/lib/mercury/modules/erlang/mercury_fixed.init is created

* recompile and install Mercury such that grade erlang is no longer 
installed
   - /usr/lib/mercury/modules/erlang/ still exists

Obviously this problem will only exist if the mercury std libraries and 
3rd party libraries are installed into the same MERCURY_LIBDIR location. 
Likewise, this problem will only exist if the erlang std libraries are 
physically removed as part of the Mercury reinstall. However, both these 
conditions will tend to be satisfied whenever Mercury is 
installed/reinstalled via a package manager. For example, on Gentoo Linux:

% install Mercury with erlang grade
$ USE="erlang" emerge mercury
<snip>

$ mmc --output-libgrades
hlc.gc
erlang
reg.gc

% install libraries from mercury-extras
$ emerge mercury-extras
<snip>

$ ls /usr/lib/mercury/modules/erlang/
mercury_fixed.init  mer_std.init

% reinstall Mercury _without_ erlang grade
$ USE="-erlang" emerge mercury
<snip>

$ mmc --output-libgrades
hlc.gc
erlang
reg.gc

$ ls /usr/lib/mercury/modules/erlang/
mercury_fixed.init

% attempt to reinstall mercury_fixed library from mercury-extras
$ emerge mercury-extras
<snip>
Installing grade erlang
Making Mercury/erlang/x86_64-pc-linux-gnu/Mercury/erls/fixed.erl
** Error: file 
`Mercury/erlang/x86_64-pc-linux-gnu/Mercury/hrls/mercury__array.hrl' not 
found: file `mercury__array.hrl' not found
gmake[2]: *** [Makefile:18: install] Error 1



The modules/java and modules/csharp directories seem immune to the above 
problem as these grades don't appear to ever create init files. However, 
even these grades can cause problems with package managers whenever 
multiple packages share the same MERCURY_LIBDIR location. The 
modules/java and modules/csharp directories will then be 'owned' by 
multiple packages, and package managers will tend to delete empty 
directories belonging to a package whenever that package is uninstalled. 
Thus it's possible for the mercury compiler to lose track of which 
grades it supports. For example on Gentoo Linux:

% install Mercury with java grade
$ USE="java" emerge mercury
<snip>
 >>> /usr/lib/mercury/modules/java/
<snip>

$ mmc --output-libgrades
hlc.gc
java
reg.gc

% install libraries from mercury-extras
$ emerge mercury-extras
<snip>
--- /usr/lib/mercury/modules/java/
<snip>

(Now both the 'mercury' and 'mercury-extras' packages own 
/usr/lib/mercury/modules/java/)

% uninstall libraries from mercury-extras
$ emerge -C mercury-extras
<snip>
<<< /usr/lib/mercury/modules/java/
<snip>

$ mmc --output-libgrades
hlc.gc
reg.gc


I can work around the empty-directory problem easily enough by adding 
zero-byte files into the empty modules/$grade directories when the 
mercury compiler is installed. Then uninstalling any other package that 
also owns the modules/$grade directories won't result in these 
directories being deleted.


Strictly speaking, these issues are more related to bundling Mercury 
with package manager than being inherent to Mercury itself. But both of 
these issues make me wonder if there is a more resilient way of 
determining which grades the compiler supports.



Thanks

Keri


More information about the developers mailing list