Skip to content

Commit

Permalink
Enable Cross Compile with MingW and Cygwin support
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Köhler committed Feb 4, 2022
1 parent 8861abb commit e6e8656
Show file tree
Hide file tree
Showing 13 changed files with 252 additions and 25 deletions.
46 changes: 29 additions & 17 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
stages:
- build
stages:
- build

ubuntu1604:
stage: build
image: docker-registry.csc.mpi-magdeburg.mpg.de:5000/ci-images/minimal/ubuntu:xenial
script:
- apt update && apt install --yes libopenblas-dev libblas-dev liblapack-dev
- mkdir -p build
- mkdir -p build
- cd build
- cmake ../ -DDEBUG=ON
- make
- cmake ../ -DDEBUG=ON
- make
- make test

ubuntu1804:
stage: build
image: docker-registry.csc.mpi-magdeburg.mpg.de:5000/ci-images/minimal/ubuntu:bionic
script:
- apt update && apt install --yes libopenblas-dev libblas-dev liblapack-dev
- mkdir -p build
- mkdir -p build
- cd build
- cmake ../ -DDEBUG=ON
- make
- cmake ../ -DDEBUG=ON
- make
- make test

ubuntu2004:
Expand All @@ -30,29 +30,41 @@ ubuntu2004:
- apt update && apt install --yes libopenblas-dev libblas-dev liblapack-dev
- mkdir -p build
- cd build
- cmake ../ -DDEBUG=ON
- make
- cmake ../ -DDEBUG=ON
- make
- make test

centos7:
stage: build
image: docker-registry.csc.mpi-magdeburg.mpg.de:5000/ci-images/minimal/centos:7-base
script:
- yum install -y cmake3 blas-devel lapack-devel
- yum install -y cmake3 blas-devel lapack-devel
- mkdir -p build
- cd build
- cmake3 ../ -DDEBUG=ON
- make
- cmake3 ../ -DDEBUG=ON
- make
- make test

centos8:
stage: build
image: docker-registry.csc.mpi-magdeburg.mpg.de:5000/ci-images/minimal/centos:8-base
script:
- yum install -y blas-devel lapack-devel
- yum install -y blas-devel lapack-devel
- mkdir -p build
- cd build
- cmake ../ -DDEBUG=ON
- make
- cmake ../ -DDEBUG=ON
- make
- make test

cross-win32:
stage: build
image: docker-registry.csc.mpi-magdeburg.mpg.de:5000/ci-images/minimal/mingw:focal
script:
- bash ./tools/ci/cross-win32.sh

cross-win64:
stage: build
image: docker-registry.csc.mpi-magdeburg.mpg.de:5000/ci-images/minimal/mingw:focal
script:
- bash ./tools/ci/cross-win64.sh

5 changes: 5 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
2022-02-04 Martin Koehler <koehlerm@mpi-magdeburg.mpg.de>

* Fix Tests on CYGWIN (GH #2)
* Enable MingW cross compiling

2020-12-10 Martin Koehler <koehlerm@mpi-magdeburg.mpg.de>

* Fix failed tchinc test on aarch64
Expand Down
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CMAKE_MINIMUM_REQUIRED(VERSION 3.1.0)
CMAKE_POLICY(SET CMP0048 NEW)
PROJECT(qrupdate-ng VERSION 1.1.4 LANGUAGES Fortran)
PROJECT(qrupdate-ng VERSION 1.1.5 LANGUAGES Fortran)
ENABLE_TESTING()

# Options
Expand Down
4 changes: 2 additions & 2 deletions CODE
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# code.ini
name: qrupdate-ng
shortname: qrupdate-ng
version: 1.1.4
release-date: 2020-12-10
version: 1.1.5
release-date: 2022-02-04
id: https://github.com/mpimd-csc/qrupdate-ng
id-type: url
author: Martin Koehler, Christian Himpe
Expand Down
45 changes: 44 additions & 1 deletion INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ operating systems, which are supported by CMAKE, should work as well.

Tested Fortran compilers:

* GNU gfortran 4.8.5, 5.4, 7.3, 8.3, 9.2
* GNU gfortran 4.8.5, 5.4, 7.3, 8.3, 9.2, 9.3
* Intel ifort 18.0.1
* IBM XLF 16.1.1

Expand Down Expand Up @@ -77,4 +77,47 @@ and LAPACK could yield the following CMAKE call:
cmake ../ -DBLAS_LIBRARIES=/home/user/software/libblas.a \
-DLAPACK_LIBRARIES=/home/user/software/liblapack.a

## Cross Compiling for Windows
The build system supports cross compiling from Unix-like operating systems to
Windows. Therefore, MingW64 (https://www.mingw-w64.org/) and
Wine (https://www.winehq.org/) need to be present on the system. In case of
Ubuntu 20.04 the following packages are required:
* `mingw-w64`, `mingw-w64-i686-dev` , `mingw-w64-x86-64-dev`
* `gfortran-mingw-w64-i686`, `gfortran-mingw-w64-x86-64`
* `wine32`, `wine64`
* `wget`

Furthermore, BLAS and LAPACK are required in the MingW installation. If this is
not the case, the reference BLAS and LAPACK library can be installed via
```shell
bash ./tools/install-lapack-mingw-i686.sh
```
for the Windows 32-bit environment, and using
```shelll
bash ./tools/install-lapack-mingw-x86_64.sh
```
for the Windows 64-bit environment.

The Windows 32-bit library can then be compiled using
```shell
cmake -S . -B build.win32 \
-DCMAKE_TOOLCHAIN_FILE=$(pwd)/cmake/mingw-w32-i686.cmake \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_PREFIX=$(pwd)/install-win32
make -C build.win32 all
(cd build.win32; ctest -V )
make -C build.win32 install
```

In case of the 64-bit Windows library, the build process looks like
```shell
cmake -S . -B build.win64 \
-DCMAKE_TOOLCHAIN_FILE=$(pwd)/cmake/mingw-w64-x86_64.cmake \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_PREFIX=$(pwd)/install-win32
make -C build.win64 all
(cd build.win64; ctest -V )
make -C build.win64 install
```


3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ qrupdate-ng: A Library for Fast Updating of QR and Cholesky Decompositions
==========================================================================

* License: GPL-3.0-or-later (opensource.org/licenses/GPL-3.0)
* Version: 1.1.4 (2020-12-10)
* Version: 1.1.5 (2022-02-04)
* Authors: M. Koehler (0000-0003-2338-9904), C. Himpe (0000-0003-2194-6754)
* Original Author: Jaroslav Hajek (VZLU Prague)
* Summary: A FORTRAN library for rank-1 matrix decomposition updates

## Supported Matrix Decompositions
Expand Down
36 changes: 36 additions & 0 deletions cmake/mingw-w32-i686.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Sample toolchain file for building for Windows from an Ubuntu Linux system.
#
# Typical usage:
# *) install cross compiler: `sudo apt-get install mingw-w64` or `brew install mingw-w64` on macOS
# *) cmake -DCMAKE_TOOLCHAIN_FILE=~/mingw-w64-x86_64.cmake -G Ninja -B build -S .
# *) ninja -C build


set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX i686-w64-mingw32)

# cross compilers to use for C, C++ and Fortran
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)

# target environment on the build host system
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} ${CMAKE_SOURCE_DIR}/tools/${TOOLCHAIN_PREFIX})

# modify default behavior of FIND_XXX() commands
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS}")

set(Fortran_LOCAL_FLAGS "-static")
set(C_LOCAL_FLAGS "-static")
set(CXX_LOCAL_FLAGS "-static")

#set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc -Wl,-Bstatic -lgfortran -lquadmath -Wl,-Bdynamic")
#set(CMAKE_EXE_LINKER_FLAGS " -static-libgcc -Wl,-Bstatic -lgfortran -lquadmath -Wl,-Bdynamic ${CMAKE_EXE_LINKER_FLAGS} ")

35 changes: 35 additions & 0 deletions cmake/mingw-w64-x86_64.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# Sample toolchain file for building for Windows from an Ubuntu Linux system.
#
# Typical usage:
# *) install cross compiler: `sudo apt-get install mingw-w64` or `brew install mingw-w64` on macOS
# *) cmake -DCMAKE_TOOLCHAIN_FILE=~/mingw-w64-x86_64.cmake -G Ninja -B build -S .
# *) ninja -C build


set(CMAKE_SYSTEM_NAME Windows)
set(TOOLCHAIN_PREFIX x86_64-w64-mingw32)

# cross compilers to use for C, C++ and Fortran
set(CMAKE_C_COMPILER ${TOOLCHAIN_PREFIX}-gcc)
set(CMAKE_CXX_COMPILER ${TOOLCHAIN_PREFIX}-g++)
set(CMAKE_Fortran_COMPILER ${TOOLCHAIN_PREFIX}-gfortran)
set(CMAKE_RC_COMPILER ${TOOLCHAIN_PREFIX}-windres)

# target environment on the build host system
set(CMAKE_FIND_ROOT_PATH /usr/${TOOLCHAIN_PREFIX} ${CMAKE_SOURCE_DIR}/tools/${TOOLCHAIN_PREFIX})

# modify default behavior of FIND_XXX() commands
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ")
set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ")

set(Fortran_LOCAL_FLAGS "-static")
set(C_LOCAL_FLAGS "-static")
set(CXX_LOCAL_FLAGS "-static")

# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static -Os")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static -Os")
59 changes: 56 additions & 3 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,64 @@ SET(TEST_PRGM
tqrinc
tqrinr
tqrshc
)
)


IF ( CMAKE_CROSSCOMPILING AND CMAKE_SYSTEM_NAME MATCHES Windows )
SET(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} ${Fortran_LOCAL_FLAGS}")
FIND_PROGRAM(WINE NAMES wine wine32 wine64)
IF ( NOT WINE )
MESSAGE(FATAL_ERROR "Wine not found")
ELSE()
MESSAGE(STATUS "Wine found: ${WINE}")
ENDIF()

EXECUTE_PROCESS(COMMAND ${CMAKE_C_COMPILER} -print-search-dirs
COMMAND grep programs
COMMAND cut -d= -f2
COMMAND sed -e "s/:/;/g"
COMMAND tr -d "\n" OUTPUT_VARIABLE WINEPATH_TMP)
SET(WINEPATH)
SET(ENVPATH_TMP "$ENV{WINEPATH}")
FOREACH ( P IN LISTS ENVPATH_TMP)
SET(WINEPATH "${WINEPATH}\\;${P}")
ENDFOREACH()
FOREACH ( P IN LISTS CMAKE_FIND_ROOT_PATH )
SET(WINEPATH "${WINEPATH}\\;${P}/bin")
SET(WINEPATH "${WINEPATH}\\;${P}/lib")
ENDFOREACH()


FOREACH ( P IN LISTS WINEPATH_TMP )
SET(WINEPATH "${WINEPATH}\\;${P}")
ENDFOREACH()

SET(WINEPATH "${CMAKE_BINARY_DIR}/src\\;${WINEPATH}")
MESSAGE(STATUS "Setting WINEPATH for tests to ${WINEPATH}")
ENDIF()

IF (CMAKE_SYSTEM_NAME MATCHES "CYGWIN")
MESSAGE(STATUS "CYGWIN build")
MESSAGE("Set additional PATH for tests to ${CMAKE_BINARY_DIR}/src:/usr/lib/lapack")
SET(ADDPATH "${CMAKE_BINARY_DIR}/src:/usr/lib/lapack")
ENDIF()


FOREACH(TEST_CODE ${TEST_PRGM})
ADD_EXECUTABLE(${TEST_CODE} ${TEST_CODE}.f)
TARGET_LINK_LIBRARIES(${TEST_CODE} utils qrupdate)
ADD_TEST(NAME test_${TEST_CODE} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${TEST_CODE})
TARGET_LINK_LIBRARIES(${TEST_CODE} utils qrupdate )
IF ( CMAKE_CROSSCOMPILING )
IF ( CMAKE_SYSTEM_NAME MATCHES Windows)
ADD_TEST(NAME test_${TEST_CODE} COMMAND ${WINE} ${CMAKE_CURRENT_BINARY_DIR}/${TEST_CODE}${CMAKE_EXECUTABLE_SUFFIX})
SET_TESTS_PROPERTIES(test_${TEST_CODE} PROPERTIES ENVIRONMENT "WINEPATH=${WINEPATH}")
ELSE()
MESSAGE(WARNING "Cross-Compile checks are only possible from Linux to Windows.")
ENDIF()
ELSE ()
ADD_TEST(NAME test_${TEST_CODE} COMMAND ${CMAKE_CURRENT_BINARY_DIR}/${TEST_CODE})
IF ( ADDPATH )
SET_TESTS_PROPERTIES(test_${TEST_CODE} PROPERTIES ENVIRONMENT "PATH=${ADDPATH}:$ENV{PATH}")
ENDIF()
ENDIF()
ENDFOREACH()

7 changes: 7 additions & 0 deletions tools/ci/cross-win32.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
set -x
(cd tools/; bash install-lapack-mingw-i686.sh)
cmake -S . -B build.win32 -DCMAKE_TOOLCHAIN_FILE=$(pwd)/cmake/mingw-w32-i686.cmake -DBUILD_SHARED_LIBS=ON
make -C build.win32 all
(cd build.win32; ctest -V )

7 changes: 7 additions & 0 deletions tools/ci/cross-win64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
#!/bin/bash
set -x
(cd tools/; bash install-lapack-mingw-x86_64.sh)
cmake -S . -B build.win64 -DCMAKE_TOOLCHAIN_FILE=$(pwd)/cmake/mingw-w64-x86_64.cmake -DBUILD_SHARED_LIBS=ON
make -C build.win64 all
(cd build.win64; ctest -V )

13 changes: 13 additions & 0 deletions tools/install-lapack-mingw-i686.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/bin/bash
set -x

[ -d build-lapack-win32 ] && rm -rf build-lapack-win32

[ -e v3.10.0.tar.gz ] || wget -c https://github.com/Reference-LAPACK/lapack/archive/refs/tags/v3.10.0.tar.gz
tar xf v3.10.0.tar.gz
cmake -S lapack-3.10.0 -B build-lapack-win32 \
-DCMAKE_TOOLCHAIN_FILE=$(pwd)/../cmake/mingw-w32-i686.cmake \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_PREFIX=`dirname $(realpath $0)`/i686-w64-mingw32
make -C build-lapack-win32 -j 4
make -C build-lapack-win32 install
15 changes: 15 additions & 0 deletions tools/install-lapack-mingw-x86_64.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/bash

#!/bin/bash
set -x

[ -d build-lapack-win64 ] && rm -rf build-lapack-win64

[ -e v3.10.0.tar.gz ] || wget -c https://github.com/Reference-LAPACK/lapack/archive/refs/tags/v3.10.0.tar.gz
tar xf v3.10.0.tar.gz
cmake -S lapack-3.10.0 -B build-lapack-win64 \
-DCMAKE_TOOLCHAIN_FILE=$(pwd)/../cmake/mingw-w64-x86_64.cmake \
-DBUILD_SHARED_LIBS=ON \
-DCMAKE_INSTALL_PREFIX=`dirname $(realpath $0)`/x86_64-w64-mingw32
make -C build-lapack-win64 -j 4
make -C build-lapack-win64 install

0 comments on commit e6e8656

Please sign in to comment.