[m-users.] Product deployment on multiple platforms.

Julien Fischer jfischer at opturion.com
Sun Jul 10 15:02:44 AEST 2022


On Tue, 5 Jul 2022, Sean Charles (emacstheviking) wrote:

> I am close to completing a simple tool that I want to sell /
> donate-ware across multiple platforms using Mercury.

> Has anybody any experience of this?
> Do I build a static image or a linked image, if I state ahead of time what the platform requirements are etc?

Assuming you are using one of the C grades, you'll have three choices:

    1. Do I link against the static or shared versions of any Mercury
       libraries? (That included the standard and runtime libraries.)

    2. Do I link against the static or shared versions of any other
       libraries (e.g. C or C++ ones)?

    3. Some mixture of the above.

(1) is controlled using the --mercury-linkage {static, shared} option.
If you use "shared" (which is the default on most platforms), then you
will need to distibute the required .so, .dylib etc files along with 
your program (since the ones for most Mercury libraries most likely
won't be available the target system). You may also need to arrange
for the dynamic loader to be able to find those .so, .dylib etc files.

Generally, when I've had to distribute packages containing Mercury
components in the past I have used "--mercury-linkage static".  The
one catch with this is that doing so may not be compatible with the
license of a library you are using. (It *is* compatible with the
Mercury core libraries, so if you are using them then you're fine,
otherwise you will need to check.)

(2) is controlled using the --linkage {static, shared} option.
On most modern systems you cannot link against static images of
the system libraries (e.g. against libSystem on macOS), so
--linkage static isn't really an option. This would also affect
any other non-Mercury libraries you are using, so you would need
to ensure they are either available on the target system or shipped
along with your program.

(The above does not apply to Windows since --linkage shared isn't
supported there.)

(3) In the past I have encountered situations where only the .a file
for a non-Mercury library was available and otherwise want to use:

     --mercury-linkage static --linkage shared

At the time the solution was to handle the final linking step manually.
That is, get the Mercury compiler to compile everything to object code
and then invoke the linker separately. Depending on the situation
it may also be possible to just inject the appopriate things into the
linker command line via the Mercruy compiler -- it has quite a few of
command line options for doing just that. In my case, due to ordering
issues that wasn't possible.

> I want to be able to target :-
> 	- Apple, both intel and M1, I have one of each so that's no an issue.
> 	- *nix on intel/amd, I have Ubuntu under emulation on my intel iMac
>        - Pi, I have a Pi4.
>        - Windows, intel/AMD. I can probably use Parallels for that

As Peter mentioned, for Windows you can just use the Mingw64 cross
compiler.  (The current cross compilation script supports 32- and 64-bit
Windows and AArch64 Linux; it would be reasonably easy to support other
platforms so long as there is a usuable GCC or clang cross compiler
available for the platform.)

For macOS, you probably want to look into the use of the lipo tool, in
order to create a universal binary. (I haven't tried it with Mercury
programs myself but there doesn't seem to be any reason it wouldn't

> Has anybody been through the process of supporting multiple platform
> builds of Mercury projects,

Yes, although I just used multiple platforms to build them all.


More information about the users mailing list