Skip to content

Commit

Permalink
Merge pull request #3155 from dra27/windows-bootstrap
Browse files Browse the repository at this point in the history
Windows bootstrap
  • Loading branch information
AltGr authored Jan 12, 2018
2 parents 8896266 + 2a54a90 commit 268f073
Show file tree
Hide file tree
Showing 18 changed files with 1,665 additions and 49 deletions.
1 change: 1 addition & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
*.zsh text eol=lf
configure text eol=lf
configure.ac text eol=lf
msvs-detect text eol=lf
check_linker text eol=lf
*.m4 text eol=lf

Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ src_ext/*.tbz
src_ext/*.tar.gz
src_ext/archives/*
src_ext/*.download
src_ext/jbuild-ignore
*.tar.bz2
*.annot
*.tar.gz
Expand Down
21 changes: 18 additions & 3 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ OPAMINSTALLER_FLAGS += --mandir "$(DESTDIR)$(mandir)"
ifdef OCAMLFIND
ifndef DESTDIR
ifneq ($(OCAMLFIND),no)
LIBINSTALL_DIR ?= $(shell $(OCAMLFIND) printconf destdir)
LIBINSTALL_DIR ?= $(shell PATH="$(PATH)" $(OCAMLFIND) printconf destdir)
endif
endif
endif
Expand Down Expand Up @@ -156,11 +156,26 @@ configure: configure.ac m4/*.m4
release-%:
$(MAKE) -C release TAG="$*"

cold:
env MAKE=$(MAKE) ./shell/bootstrap-ocaml.sh
ifeq ($(OCAML_PORT),)
ifneq ($(COMSPEC),)
ifeq ($(shell which gcc 2>/dev/null),)
OCAML_PORT=auto
endif
endif
endif

.PHONY: compiler cold
compiler:
env MAKE=$(MAKE) ./shell/bootstrap-ocaml.sh $(OCAML_PORT)

cold: compiler
env PATH="`pwd`/bootstrap/ocaml/bin:$$PATH" ./configure $(CONFIGURE_ARGS)
env PATH="`pwd`/bootstrap/ocaml/bin:$$PATH" $(MAKE) lib-ext
env PATH="`pwd`/bootstrap/ocaml/bin:$$PATH" $(MAKE)

cold-%:
env PATH="`pwd`/bootstrap/ocaml/bin:$$PATH" $(MAKE) $*

.PHONY: run-appveyor-test
run-appveyor-test:
env PATH="`pwd`/bootstrap/ocaml/bin:$$PATH" ./appveyor_test.sh
8 changes: 6 additions & 2 deletions Makefile.config.in
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ PACKS = $(filter-out no,@OCAML_PKG_unix@ @OCAML_PKG_bigarray@ @OCAML_PKG_extlib@

CONF_OCAMLFLAGS = @CONF_OCAMLFLAGS@

MCCS_DISABLED = @MCCS_DISABLED@
MCCS_ENABLED = @MCCS_ENABLED@

OCAMLLIB = @OCAMLLIB@

OCAMLFIND = @OCAMLFIND@
OCAML = @OCAML@
Expand All @@ -21,9 +23,11 @@ EXE = @EXE@
WIN32 = @WIN32@

PATH:=@PATH_PREPEND@$(PATH)
INCLUDE:=@INC_PREPEND@$(INCLUDE)
LIB:=@LIB_PREPEND@$(LIB)

LIB_PREFIX = @LIB_PREFIX@
CPATH = @CPATH@
LIBRARY_PATH = @LIBRARY_PATH@

export OCAMLVERSION OCAMLFIND OCAML OCAMLC OCAMLOPT EXE PATH CPATH LIBRARY_PATH
export OCAMLVERSION OCAMLFIND OCAML OCAMLC OCAMLOPT EXE PATH INCLUDE LIB CPATH LIBRARY_PATH OCAMLLIB
71 changes: 71 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,77 @@ it as a second step.
If you are developing OPAM, you may enable developer features by including the
`--enable-developer-mode` parameter with `./configure`.

## Compiling on Native Windows

```
BUILDING ON WINDOWS IS A WORK-IN-PROGRESS AND THESE INSTRUCTIONS WILL EVOLVE!
```

Cygwin (https://www.cygwin.com/setup-x86_64.exe) is always required to build opam on
Windows. Both the 64-bit and 32-bit versions of Cygwin may be used (you can build
32-bit opam using 64-bit Cygwin and vice versa though note that you must be running
64-bit Windows in order to build the 64-bit version).

The following Cygwin packages are required:
* From Devel - `make`
* From Devel - `patch` (not required if OCaml and all required packages are
pre-installed)
* From Devel - `mingw64-i686-gcc-core` & `mingw64-x86_64-gcc-core` (not required if
building with MSVC)

Alternatively, having downloaded Cygwin's setup program, Cygwin can be installed
using the following command line:

`setup-x86_64 --root=C:\cygwin64 --quiet-mode --no-desktop --no-startmenu --packages=make,mingw64-i686-gcc-core,mingw64-x86_64-gcc-core,patch`

The `--no-desktop` and `--no-startmenu` switches may be omitted in order to create
shortcuts on the Desktop and Start Menu respectively. Executed this way, setup will
still be interactive, but the packages will have been pre-selected. To make setup
fully unattended, choose a mirror URL from https://cygwin.com/mirrors.lst and add
the --site switch to the command line
(e.g. `--site=http://www.mirrorservice.org/sites/sourceware.org/pub/cygwin/`).

It is recommended that you set the `CYGWIN` environment variable to
`nodosfilewarning winsymlinks:native`.

Cygwin is started either from a shortcut or by running:

```
C:\cygwin64\bin\mintty -
```

It is recommended that opam be built outside Cygwin's root
(so in `/cygdrive/c/...`). From an elevated Cygwin shell, edit `/etc/fstab` and
ensure that the file's content is exactly:

```
none /cygdrive cygdrive noacl,binary,posix=0,user 0 0
```

The change is the addition of the `noacl` option to the mount instructions for
`/cygdrive` and this stops from Cygwin from attempting to emulate POSIX permissions
over NTFS (which can result in strange and unnecessary permissions showing up in
Windows Explorer). It is necessary to close and restart all Cygwin terminal windows
after changing `/etc/fstab`.

opam is able to be built **without** a pre-installed OCaml compiler. For the MSVC
ports of OCaml, the Microsoft Windows SDK 7 or later or Microsoft Visual Studio is
required (https://www.microsoft.com/en-gb/download/details.aspx?id=8442 - either x86
or x64 may be installed, as appropriate to your system). It is not necessary to
modify PATH, INCLUDE or LIB - opam's build system will automatically detect the
required changes.

If OCaml is not pre-installed, run:
```
make compiler [OCAML_PORT=mingw64|mingw|msvc64|msvc|auto]
```
The `OCAML_PORT` variable determines which flavour of Windows OCaml is compiled -
`auto` will attempt to guess. As long as `gcc` is **not** installed in Cygwin
(i.e. the native C compiler *for Cygwin*), `OCAML_PORT` does not need to be
specified and `auto` will be assumed.

You can then `configure` and build opam as above.

## Compiling without OCaml

`make cold` is provided as a facility to compile OCaml, then bootstrap opam.
Expand Down
49 changes: 49 additions & 0 deletions appveyor.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
From 083bae674ad77b6b5b5fafbff25b20473655cb2a Mon Sep 17 00:00:00 2001
From: David Allsopp <david.allsopp@metastack.com>
Date: Wed, 27 Dec 2017 10:37:12 +0200
Subject: [PATCH] Use dra27 jbuilder/ocaml-mccs/flexdll

- Need unreleased ocaml-mccs 1.1+5 to build mccs on Windows.
- Need unreleased jbuilder beta17 to build mccs on MSVC.
- Need unreleased flexdll 0.38 to build mccs on mingw.
---
src_ext/Makefile | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)

diff --git a/src_ext/Makefile b/src_ext/Makefile
index 64fdd8af..d1457b5f 100644
--- a/src_ext/Makefile
+++ b/src_ext/Makefile
@@ -28,8 +28,8 @@ MD5_cudf = a4c0e652e56e74c7b388a43f9258d119
URL_dose3 = https://gforge.inria.fr/frs/download.php/file/36063/dose3-5.0.1.tar.gz
MD5_dose3 = e7d4b1840383c6732f29a47c08ba5650

-URL_mccs = https://github.com/AltGr/ocaml-mccs/archive/1.1+4.tar.gz
-MD5_mccs = 1ff2d73ab5c69e1fb58160213fc2d4c9
+URL_mccs = https://github.com/dra27/ocaml-mccs/archive/1.1+4-dra27.tar.gz
+MD5_mccs = 08e80e39a0d960c01955a970d13afb29

URL_opam-file-format = https://github.com/ocaml/opam-file-format/archive/2.0.0-beta5.tar.gz
MD5_opam-file-format = 5408798ca3af6e36379dd34b1b618b9c
@@ -37,14 +37,14 @@ MD5_opam-file-format = 5408798ca3af6e36379dd34b1b618b9c
URL_result = https://github.com/janestreet/result/archive/1.2.tar.gz
MD5_result = 3d5b66c5526918f0f2ca9d6811ef09c8

-URL_jbuilder = https://github.com/janestreet/jbuilder/archive/08050696fb701dafcd1372aadfaa800a50bc01ca.tar.gz
-MD5_jbuilder = 53b65232ebb5fd319acf90922342615d
+URL_jbuilder = https://github.com/dra27/jbuilder/archive/fix-copy.tar.gz
+MD5_jbuilder = cbf9d2e783feab1f4a61fea35ec96118

URL_ocaml = http://caml.inria.fr/pub/distrib/ocaml-4.06/ocaml-4.06.0.tar.gz
MD5_ocaml = 66e5439eb63dbb8b8224cba5d1b20947

-URL_flexdll = https://github.com/alainfrisch/flexdll/archive/0.37.tar.gz
-MD5_flexdll = cc456a89382e60d84130cddd53977486
+URL_flexdll = https://github.com/dra27/flexdll/archive/linking-c++.tar.gz
+MD5_flexdll = 75bd0efc328ad9f8f2e01414464d217b

ifndef FETCH
ifneq ($(shell command -v curl 2>/dev/null),)
--
2.12.0.windows.1

34 changes: 23 additions & 11 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
platform:
- x86
- x64

image: Visual Studio 2017

environment:
global:
CYG_ROOT: C:/cygwin
CYG_ROOT: cygwin64
CYG_ARCH: x86_64
OCAML_PORT:
CYG_CACHE: C:/cygwin/var/cache/setup
CYG_MIRROR: http://mirrors.kernel.org/sourceware/cygwin/
matrix:
-
- CYG_ROOT: cygwin
CYG_ARCH: x86
- CYG_ROOT: cygwin64
CYG_ARCH: x86_64
- OCAML_PORT: msvc
- OCAML_PORT: msvc64
- OCAML_PORT: mingw
- OCAML_PORT: mingw64

cache:
- C:\projects\opam\bootstrap
- C:\projects\opam\src_ext\archives

init:
- 'echo System architecture: %PLATFORM%'
- "echo System architecture: %PLATFORM%"

install:
- 'appveyor DownloadFile http://cygwin.com/setup-%CYG_ARCH%.exe -FileName setup.exe'
- 'setup.exe -gqnNdO -R "%CYG_ROOT%" -s "%CYG_MIRROR%" -l "%CYG_CACHE%" -P make,git,gcc-core,gcc-g++,ocaml,ocaml-camlp4,ocaml-compiler-libs,libncurses-devel,unzip,libmpfr-devel,patch,flexdll,libglpk-devel >NUL'
- '%CYG_ROOT%/bin/bash -lc "cygcheck -dc cygwin gcc-core"'
- call "%APPVEYOR_BUILD_FOLDER%\appveyor_build.cmd" install

build_script:
- '%CYG_ROOT%/bin/bash -lc "cd \"$OLDPWD\" && env DJDIR="workaround" ./configure && make lib-ext && make && make install"'
- '%CYG_ROOT%/bin/bash -lc "opam init -y -a"'
- '%CYG_ROOT%/bin/bash -lc "opam config env"'
- '%CYG_ROOT%/bin/bash -lc "opam install -y -v ocamlfind"'
- call "%APPVEYOR_BUILD_FOLDER%\appveyor_build.cmd" build

test_script:
- call "%APPVEYOR_BUILD_FOLDER%\appveyor_build.cmd" test
131 changes: 131 additions & 0 deletions appveyor_build.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
@rem ***********************************************************************
@rem * *
@rem * opam *
@rem * *
@rem * David Allsopp, OCaml Labs, Cambridge. *
@rem * *
@rem * Copyright 2018 MetaStack Solutions Ltd. *
@rem * *
@rem * All rights reserved. This file is distributed under the terms of *
@rem * the GNU Lesser General Public License version 2.1, with the *
@rem * special exception on linking described in the file LICENSE. *
@rem * *
@rem ***********************************************************************

@rem BE CAREFUL ALTERING THIS FILE TO ENSURE THAT ERRORS PROPAGATE
@rem IF A COMMAND SHOULD FAIL IT PROBABLY NEEDS TO END WITH
@rem || exit /b 1
@rem BASICALLY, DO THE TESTING IN BASH...

@rem Do not call setlocal!
@echo off

goto %1

goto :EOF

:CheckPackage
"%CYG_ROOT%\bin\bash.exe" -lc "cygcheck -dc %1" | findstr %1 > nul
if %ERRORLEVEL% equ 1 (
echo Cygwin package %1 will be installed
set CYGWIN_INSTALL_PACKAGES=%CYGWIN_INSTALL_PACKAGES%,%1
)
goto :EOF

:UpgradeCygwin
if "%CYGWIN_INSTALL_PACKAGES%" neq "" "%CYG_ROOT%\setup-%CYG_ARCH%.exe" --quiet-mode --no-shortcuts --no-startmenu --no-desktop --only-site --root "%CYG_ROOT%" --site "%CYG_MIRROR%" --local-package-dir "%CYG_CACHE%" --packages %CYGWIN_INSTALL_PACKAGES:~1% > nul
for %%P in (%CYGWIN_COMMANDS%) do "%CYG_ROOT%\bin\bash.exe" -lc "%%P --help" > nul || set CYGWIN_UPGRADE_REQUIRED=1
"%CYG_ROOT%\bin\bash.exe" -lc "cygcheck -dc %CYGWIN_PACKAGES%"
if %CYGWIN_UPGRADE_REQUIRED% equ 1 (
echo Cygwin package upgrade required - please go and drink coffee
"%CYG_ROOT%\setup-%CYG_ARCH%.exe" --quiet-mode --no-shortcuts --no-startmenu --no-desktop --only-site --root "%CYG_ROOT%" --site "%CYG_MIRROR%" --local-package-dir "%CYG_CACHE%" --upgrade-also > nul
"%CYG_ROOT%\bin\bash.exe" -lc "cygcheck -dc %CYGWIN_PACKAGES%"
)
goto :EOF

:install
set CYG_ROOT=C:\%CYG_ROOT%

cd "%APPVEYOR_BUILD_FOLDER%"

rem CYGWIN_PACKAGES is the list of required Cygwin packages (cygwin is included
rem in the list just so that the Cygwin version is always displayed on the log).
rem CYGWIN_COMMANDS is a corresponding command to run with --version to test
rem whether the package works. This is used to verify whether the installation
rem needs upgrading.
set CYGWIN_PACKAGES=cygwin make patch curl diffutils tar unzip
set CYGWIN_COMMANDS=cygcheck make patch curl diff tar unzip

if "%OCAML_PORT%" equ "mingw" (
set CYGWIN_PACKAGES=%CYGWIN_PACKAGES% mingw64-i686-gcc-g++
set CYGWIN_COMMANDS=%CYGWIN_COMMANDS% i686-w64-mingw32-g++
)
if "%OCAML_PORT%" equ "mingw64" (
set CYGWIN_PACKAGES=%CYGWIN_PACKAGES% mingw64-x86_64-gcc-g++
set CYGWIN_COMMANDS=%CYGWIN_COMMANDS% x86_64-w64-mingw32-g++
)
if "%OCAML_PORT%" equ "" (
set CYGWIN_PACKAGES=%CYGWIN_PACKAGES% gcc-g++ flexdll
set CYGWIN_COMMANDS=%CYGWIN_COMMANDS% g++ flexlink
)

set CYGWIN_INSTALL_PACKAGES=
set CYGWIN_UPGRADE_REQUIRED=0

for %%P in (%CYGWIN_PACKAGES%) do call :CheckPackage %%P
call :UpgradeCygwin

rem Use dra27 jbuilder/ocaml-mccs/flexdll for native ports
if "%OCAML_PORT%" neq "" git apply appveyor.patch

set INSTALLED_URL=
for /f "tokens=3" %%U in ('findstr /C:"URL_ocaml = " src_ext\Makefile') do set OCAML_URL=%%U
for /f "tokens=3" %%U in ('findstr /C:"URL_flexdll = " src_ext\Makefile') do set FLEXDLL_URL=%%U
if exist bootstrap\installed-tarball for /f "delims=" %%U in ('type bootstrap\installed-tarball') do set INSTALLED_URL=%%U
if "%INSTALLED_URL%" neq "%OCAML_URL% %FLEXDLL_URL%" if exist bootstrap\nul (
echo Required: %OCAML_URL% %FLEXDLL_URL%
echo Compiled: %INSTALLED_URL%
echo Re-building bootstrap compiling
rd /s/q bootstrap
if exist src_ext\archives\nul rd /s/q src_ext\archives
)

"%CYG_ROOT%\bin\bash.exe" -lc "cd $APPVEYOR_BUILD_FOLDER && make -C src_ext cache-archives" || exit /b 1

if not exist bootstrap\nul (
"%CYG_ROOT%\bin\bash.exe" -lc "cd $APPVEYOR_BUILD_FOLDER && make compiler" || exit /b 1
if "%CYG_ARCH%%OCAML_PORT%" equ "x86_64" (
"%CYG_ROOT%\bin\bash.exe" -lc "cd $APPVEYOR_BUILD_FOLDER && rebase -b 0x7cd20000 bootstrap/ocaml/lib/ocaml/stublibs/dllunix.so" || exit /b 1
"%CYG_ROOT%\bin\bash.exe" -lc "cd $APPVEYOR_BUILD_FOLDER && rebase -b 0x7cd20000 bootstrap/ocaml/lib/ocaml/stublibs/dllthreads.so" || exit /b 1
)
if exist bootstrap\ocaml-*.tar.gz del bootstrap\ocaml-*.tar.gz
if "%OCAML_PORT%" neq "" if exist bootstrap\flexdll-*.tar.gz del bootstrap\flexdll-*.tar.gz
del bootstrap\ocaml\bin\*.byte.exe
if "%OCAML_PORT%" equ "" (
del bootstrap\ocaml\lib\ocaml\expunge.exe
) else (
del bootstrap\ocaml\lib\expunge.exe
)
for /f %%D in ('dir /b/ad bootstrap\ocaml-*') do (
rd /s/q bootstrap\%%D
if "%OCAML_PORT%" equ "" (
rem Directory needs to exist, as the Cygwin bootstraps OCAMLLIB refers to it
md bootstrap\%%D
)
)
)

goto :EOF

:build
if "%OCAML_PORT%" equ "" (
rem make install doesn't yet work for the native Windows builds
set POST_COMMAND=^&^& make opam-installer install
)
"%CYG_ROOT%\bin\bash.exe" -lc "cd $APPVEYOR_BUILD_FOLDER && ./configure && make lib-ext && make opam %POST_COMMAND%" || exit /b 1
goto :EOF

:test
rem Can't yet do an opam init with the native Windows builds
if "%OCAML_PORT%" equ "" "%CYG_ROOT%\bin\bash.exe" -lc "make -C $APPVEYOR_BUILD_FOLDER run-appveyor-test" || exit /b 1
goto :EOF
5 changes: 5 additions & 0 deletions appveyor_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/bin/bash

opam init -y -a
eval $(opam config env)
opam install -y -v ocamlfind
Loading

0 comments on commit 268f073

Please sign in to comment.