Sunday, May 27, 2018

How to build the Elm platform from the source on Windows.

This is a brief guideline to explain how to build the Elm platform on Windows from its source. The guideline is based on the original instruction from https://github.com/elm-lang/elm-platform.

1. Preliminaries

1.1 GHC and Cabal


This is for building Elm 0.18 from the source code. It demands GHC 7.10.x and Cabal >=1.1.8, which can be downloaded from

 - https://www.haskell.org/ghc/download.html
 - https://www.haskell.org/cabal/download.html

 For my Windows 10 on x86_64, I downloaded GHC 7.10.3 and Cabal 2.2.0.0.

After downloading the two packages, you first unpack the GHC package into a directory named, say, C:\work\ghc. The unpacking the packages resulted in directory ghc-7.10.3 including

 - C:\Work\ghc\ghc-7.10.3\bin

After unpacking the Cabal package, you will simply get cabal.exe. Then copy the Cabal executable into the GHC binary directory mentioned above.

Then set path to include the GHC binary directory. Test it by opening a Dos terminal to run ghc --version and cabal --version.




1.2 MinGWS and msys

Install MinGWS and msys. 

 - mingw-get-setup.exe   from http://www.mingw.org/
    (to install mingw-developer-toolkit, mingw32-base, mingw32-gcc-g++, msys-base)

 - MSYS-1.0.11.exe    from http://www.mingw.org/wiki/MSYS or  http://downloads.sourceforge.net/mingw/MSYS-1.0.11.exe

You need to add the paths to the executables to your path environment.

 - C:\MinGW\bin
 - C:\msys\1.0\bin

At first, I thought the installation of MinGWS and msys is enough to make it to build Elm-Platform on Windows successfully. But it failed. Actually, I cannot explain the exact reason, but it seems to need shell script facilities to be successful. For example, I cannot execute C:\msys\1.0\bin\awk on Dos terminal. Is this because awk does not have .exe nor .bat as its extension? 


1.3 Ubuntu terminal on Windows 10

So, the next trial is to use the Ubuntu terminal on Windows, which provides shell environments. 

 - https://docs.microsoft.com/en-us/windows/wsl/install-win10

 - https://tutorials.ubuntu.com/tutorial/tutorial-ubuntu-on-windows#0


   (which will be redirectd to Microsoft App store, https://www.microsoft.com/en-us/store/p/ubuntu/9nblggh4msv6)

After your successful installation of the Ubuntu terminal on Windows 10, do launch the Ubuntu terminal from the Windows start menu. 


khchoi@LAPTOP-KE15PJ8N:/mnt/c/work/elmbuild$ ls
BuildFromSource.hs  

khchoi@LAPTOP-KE15PJ8N:/mnt/c/work/elmbuild$ df
Filesystem     1K-blocks      Used Available Use% Mounted on
rootfs         498799612 121793964 377005648  25% /
none           498799612 121793964 377005648  25% /dev
none           498799612 121793964 377005648  25% /run
none           498799612 121793964 377005648  25% /run/lock
none           498799612 121793964 377005648  25% /run/shm
none           498799612 121793964 377005648  25% /run/user
C:             498799612 121793964 377005648  25% /mnt/c


As you see above, my folder is /mnt/c/work/elmbuild where BuildFromSource.hs is. In the next, I will tell you where you can download this haskell file. 

Note that /mnt/c is a (virtual) path to the C drive on Windows viewed from the Ubuntu side.

In conclusion, you are in the directory, elmbuild, in the Ubuntu terminal.



2. Building Elm-Platform

With the Ubuntu terminal, I assume that you are in /mnt/c/work/elmbuild/. 

Then you proceed as the Elm instruction tells you:

 - curl https://raw.githubusercontent.com/elm-lang/elm-platform/master/installers/BuildFromSource.hs > BuildFromSource.hs

 - runhaskell.exe BuildFromSource.hs 0.18



Note that I installed the Window version of GHC, and so the executable files all have .exe as an extension. On the Ubuntu terminal, you must say runhaskell.exe, not runhaskell, which would be OK if you installed the Linux version of GHC. 

If you have a little fortune, you will see a bunch of logs saying cloning source codes from GitHub and building them by GHC and so on. 

The building will lead to a compilation error as follows.


Installed blaze-html-0.9.0.1
Resolving dependencies...
Notice: installing into a sandbox located at
C:\Work\elmbuild\Elm-Platform\0.18\.cabal-sandbox
Configuring elm-compiler-0.18...
Building elm-compiler-0.18...
Installed elm-compiler-0.18
Configuring elm-package-0.18...
Building elm-package-0.18...
Failed to install elm-package-0.18
Build log ( C:\Work\elmbuild\Elm-Platform\0.18\.cabal-sandbox\logs\ghc-7.10.3\elm-package-0.18-5b9PWczZoztJ6nOvjcNrfc.log ):
Preprocessing executable 'elm-package' for elm-package-0.18..
Building executable 'elm-package' for elm-package-0.18..
[ 1 of 27] Compiling Utils.Paths      ( src\Utils\Paths.hs, dist\dist-sandbox-25b26694\build\elm-package\elm-package-tmp\Utils\Paths.o )

src\Utils\Paths.hs:15:27: Not in scope: ‘N.toFilePath’

src\Utils\Paths.hs:19:26:
    Not in scope: ‘Package.versiontoString’
    Perhaps you meant one of these:
      ‘Package.versionToString’ (imported from Elm.Package),
      ‘Package.versionFromString’ (imported from Elm.Package)
cabal: Leaving directory 'C:\Work\elmbuild\Elm-Platform\0.18\elm-package'
cabal: Error: some packages failed to install:
elm-make-0.18-EdAAG7jYG0T1gF34nRbUyL depends on elm-make-0.18 which failed to
install.
elm-package-0.18-5b9PWczZoztJ6nOvjcNrfc failed during the building phase. The
exception was:
ExitFailure 1
elm-repl-0.18-CfO4RJPUoASJxV81yVDYp2 depends on elm-repl-0.18 which failed to
install.

This compilation error can be fixed by changing Line 15 and Line 19 in elm-pakcage/src/Utils/Path.hs, as follows:


  1 module Utils.Paths where
  2
  3 import System.FilePath
  4
  5 import qualified Elm.Package as Package
  6
  7 internals = "_internals"
  8
  9 libDir = "public" </> "catalog"
 10
 11 json = "docs.json"
 12 index = "index.elm"
 13 listing = "public" </> "libraries.json"
 14
 15 library name = libDir </> N.toFilePath name
    =>
    library name = libDir </> Package.toFilePath name    
 16
 17 libraryVersion :: Package.Name -> Package.Version -> FilePath
 18 libraryVersion name version =
 19         library name </> Package.versiontoString version
    =>      library name </> Package.versionToString version


Here is a patch for the change above.



diff --git a/src/Utils/Paths.hs b/src/Utils/Paths.hs
index f0752c5..e746787 100644
--- a/src/Utils/Paths.hs
+++ b/src/Utils/Paths.hs
@@ -12,9 +12,9 @@ json = "docs.json"
 index = "index.elm"
 listing = "public" </> "libraries.json"
 
-library name = libDir </> N.toFilePath name
+library name = libDir </> Package.toFilePath name
 
 libraryVersion :: Package.Name -> Package.Version -> FilePath
 libraryVersion name version =
- library name </> Package.versiontoString version
+ library name </> Package.versionToString version
 

Then rerun runhaskell BuildFromSource.hs 0.18. You will succeed in building Elm-platform.

To see it work, change your current directory to Elm-Platform/0.18/.cabal-sandbox/bin/. Then run elm-repl.exe and see a good thing as follows:



khchoi@LAPTOP-KE15PJ8N:/mnt/c/work/elmbuild/Elm-Platform/0.18$ ./.cabal-sandbox/bin/elm-repl.exe
---- elm-repl 0.18.0 -----------------------------------------------------------
 :help for help, :exit to exit, more at 
--------------------------------------------------------------------------------
> 1+1
2 : number
>



In fact, I found out that you can run elm-repl on the Dos terminal as well. 


C:\Work\elmbuild\Elm-Platform\0.18> cabal exec elm-repl
---- elm-repl 0.18.0 -----------------------------------------------------------
 :help for help, :exit to exit, more at 
--------------------------------------------------------------------------------
> 1+1
2 : number


Be careful! The first run of elm-repl may get terminated abnormally. But from the second run, it will work without any problem.

In conclusion, you build the Elm-Platform on the Ubuntu terminal, but you run it on the Dos terminal. This looks very natural on Windows 10!


Have a good luck!!