Overview

HTTPS SSH

OPAMINGW: Using Cygwin OPAM for MinGW OCaml

This document is for OCaml Version 4.03.0

What is OPAMINGW

At this moment OPAM is highly dependent on Unix. Therefore it is currently impossible to build it with MiNGW OCaml as a Windows native binary. But this does NOT immediately mean that you cannot use OPAM.
OPAMINGW is a hack to use Cygwin built OPAM for MinGW OCaml environment.

Short Summary

  • Better set igncr option of your shell to avoid troubles of \r.
  • Compile OPAM with Cygwin OCaml using opamingw-1.2.2 branch of https://github.com/camlspotter/opam.git
  • Fake a switch 4.03.0. Copy ~/.opam/system directory to ~/.opam/4.03.0, then edit ~/.opam/4.03.0/config/global-config.config to match with the MinGW environment. Build MinGW OCaml 4.03.0 and install it under ~/.opam/4.03.0, with a fix http://caml.inria.fr/mantis/view.php?id=7217. Note that LIBDIR=$(PREFIX)/lib/ocaml not $(PREFIX)/lib.
  • Override the official repo by https://github.com/camlspotter/opam-repository-mingw.git

Install Cygwin

I strongly recommend Cygwin 64. I had looooooooots of strange rebase problems with Cygwin 32 and abandoned it.

Install Cygwin packages

You will need at least the following Cygwin packages to kick start:

  • wget
  • diffutils
  • make
  • ncurses
  • dos2unix
  • gcc-core
  • wget
  • git
  • patch
  • m4
  • unzip
  • mingw64-x86_64-binutils
  • mingw64-x86_64-gcc-core
  • mingw64-x86_64-runtime
  • mingw64-x86_64-pkg-config

The following command may help installing these packages in batch:

your-copy-of-cygwin-upset-x86_64.exe -n -q -P wget,diffutils,make,ncurses,dos2unix,gcc-core,wget,git,patch,m4,unzip,mingw64-x86_64-binutils,mingw64-x86_64-gcc-core,mingw64-x86_64-runtime,mingw64-x86_64-pkg-config

The cross compilers mingw64-x86_64-* are for MinGW 64. If you want to have 32bits version of OCaml system, rename them appropriately as mingw64-i686-*.

Install FlexDLL

You need to install FlexDLL. http://alain.frisch.fr/flexdll/flexdll-bin-0.34.zip worked fine for me.

Check point

Check flexlink is both in Cygwin PATH and in Windows PATH.

Set igncr option to /bin/sh

Many build scripts such as Makefile use backquotes like

   command `ocamlc -where`/stdlib.cma

This is executed Cygwin's shell (/bin/sh if it is Makefile) and since ocamlc is a MinGW app, it is likely to have a trouble of \r char at the end of the line.

You should set your shell option to ignore \r char. In bash, you should have the following in your bashrc:

export SHELLOPTS
set -o igncr

Install Cygwin OCaml

You can use OCaml compiler package from Cygwin. But be careful since this is NOT the OCaml system you are interested in. Once MinGW OCaml is installed, you may feel confused having two OCaml systems in your PATH.

You can build and install your own Cygwin OCaml (4.02.3 or 4.03.0) by yourself. In this case, you may want to install it somewhere non default, so that you can remove them from your PATH once MinGW OCaml is installed. In any case, at this point, change your PATH so that ocamlc command can work in a Cygwin terminal.

Check point

Check Cygwin OCaml is working: ocamlc -version must work in a Cygwin Window.

Install Cygwin OPAM

We need slightly modified OPAM with the following workarounds:

  • Build stops when your are not using Cygwin OCaml compiler.
  • Files in bin sections of xxx.install are installed with .exe extension, if they do not have it already.
  • *.cmxs files are installed with executable bit for dynamic loading

Clone a modified OPAM

Use opamingw-1.2.2 branch of https://github.com/camlspotter/opam.git.

Build

The build is pretty normal. You may want to add --prefix option to ./configure to install opam binary somewhere special (but do not specify somewhere under $HOME/.opam since it confuses opam config env):

$ ./configure --prefix <somewhere>
$ make lib-ext
$ make
$ make install

After the installation, make sure to change your Cygwin dotRC so that opam command is available in your shell.

Check point

See opam is available in your PATH.

opam init

$ opam init
...
...
Do you want OPAM to modify ~/.bash_profile and ~/.ocamlinit?
(default is 'no', use 'f' to name a file other than ~/.bash_profile)
    [N/y/f]

Answer whatever you like but do not forget tweak things if you answer N or f.

This creates a switch called system, using Cygwin OCaml compiler you used to build OPAM. We do not really use this system compiler set. We only make use of the files under system for templates for MinGW OCaml compiler sets.

Make a fake switch 4.03.0

After several try-and-errors, I think the easiest way to install an MinGW OCaml compiler system with Cygwin OPAM is to fake a switch.

$ cd $HOME/.opam
$ echo "4.03.0 4.03.0" >> aliases
$ cp -a system 4.03.0

Let's call cygpath -m $HOME/.opam/4.03.0 as $OPAM_ROOT.

Fix $OPAM_ROOT/config/global-config.config

Fix the pathes in $OPAM_ROOT/config/global-config.config by $OPAM_ROOT. Something like:

user: "your name here"
group: "your group here"
make: "make"
os: "cygwin"
root: "c:/your-cygwin-place/home/your-name/.opam"
prefix: "c:/your-cygwin-place/home/your-name/.opam/4.03.0"
lib: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/lib"
bin: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/bin"
sbin: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/sbin"
doc: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/doc"
stublibs: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/lib/stublibs"
toplevel: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/lib/toplevel"
man: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/man"
share: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/share"
etc: "c:/your-cygwin-place/home/your-name/.opam/4.03.0/etc"

I am not sure about os field. So far it does not affect installation of packages.

Install MinGW OCaml

DON'T use binary installers.
You need to compile it by yourself, then install under $OPAM_ROOT.

Installation

Read "The native Win32 and Win64 ports built with Mingw" section of ocaml-4.03.0/README.win32.adoc and follow the instructions.

Do NOT install it under c:/ocamlmgw64, the default place. Install it under $OPAM_ROOT. Set PREFIX and LIBDIR as follows:

PREFIX=/home/<yourname>/.opam/4.03.0 # $OPAM_ROOT
LIBDIR=$(PREFIX)/lib/ocaml

Do not forget to change LIBDIR. opam assumes OCaml's library directory is not $OPAM_ROOT/lib but $OPAM_ROOT/ocaml/lib.

Check point

See $OPAM_ROOT/bin/ocamlc is working.

Switch to the faked switch

$ opam switch 4.03.0

It may say something like

[ERROR] You current switch uses the system compiler, but no OCaml compiler has
        been found in the current path.

but simply ignore it.

Check the output of opam config env. Check CAML_LD_LIBRARY_PATH is equal to $OPAM_ROOT/lib/ocaml/stublibs.

Finally,

$ eval `opam config env`

to change your env vars.

Potential problems

OCAML_TOPLEVEL_PATH has a Cygwin PATH which is not appropriate for MinGW OCaml. You may want to override it. (I rarely use toplevel and have not had troubles yet.)

Add special OPAM repo for OPAMINGW

Many OCaml libraries and applications are not tested with MinGW OCaml and therefore they need small fixes. The following OPAM repo provides a small set of these workarounds:

$ opam repo add opamingw https://github.com/camlspotter/opam-repository-mingw.git
$ opam update

Some notes of workarounds

Some core tools have required the following fixes:

ocamlbuild

  • -install-lib-dir option has no effect. This is required since Oasis's setup.ml has a special case for Win32 at ocamlbuild executions to add this option with no longer correct place in OPAM environment.
  • A small workaround for a bug of its new hygiene check. (It will be addressed in the next release of ocamlbuild.)

omake

I use Gerd Stolpmann's 0.10.0 with some fixes for MinGW.

DONE!

Yes it's done. At least for installation of OPAM is done.

Start installing some OPAM packages and yell "They are not tested under MinGW at all!!!"

The fun starts.