Skip to content

Commit 8a6edc6

Browse files
zivyArtur-man
andcommitted
Add support for Windows (#82)
Add support for building and testing on Windows OS in a consistent manner to Linux and macOS. On Windows, this uses RTools to provide the necessary build tools. Testing is performed in CircleCI as it offers a more powerful build machine under the free plan. Co-authored-by: Artur-man <artur-man@hotmail.com>
1 parent fc96640 commit 8a6edc6

6 files changed

Lines changed: 157 additions & 5 deletions

File tree

.Rbuildignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
.circleci/
2+
^.*\.Rproj$
3+
^\.Rproj\.user$

.github/workflows/main.yml

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@ jobs:
1717
fail-fast: false
1818
matrix:
1919
R: [ '4.3.1', '4.4.1' ]
20-
os: [ 'macos-15-intel', 'ubuntu-latest' ]
20+
os: [ 'macos-15-intel', 'ubuntu-latest', 'windows-latest']
21+
exclude:
22+
- R: '4.3.1'
23+
os: 'windows-latest'
2124
runs-on: ${{ matrix.os }}
2225
name: ${{ matrix.R }} ${{ matrix.os }} build
2326
env:
@@ -39,18 +42,44 @@ jobs:
3942
sudo apt-get install -y libcurl4-openssl-dev libssh2-1-dev libharfbuzz-dev libfribidi-dev gh &&
4043
sudo rm -rf /var/lib/apt/lists/*
4144
- name: Configuration Information
45+
if: runner.os == 'Linux' || runner.os == 'macOS'
4246
run: |
4347
mkdir ${R_LIBS}
4448
c++ --version
4549
cmake --version
4650
which R
4751
R --version
52+
- name: Configuration Information (Windows)
53+
if: startsWith(matrix.os, 'windows')
54+
shell: pwsh
55+
run: |
56+
New-Item -ItemType Directory -Force -Path "$env:R_LIBS" | Out-Null
57+
g++ --version
58+
cmake --version
59+
Get-Command R.exe
60+
R.exe --version
4861
- name: Install R packages
62+
if: runner.os == 'Linux' || runner.os == 'macOS'
63+
run: |
64+
R -e "install.packages(c('remotes'), lib=c('${R_LIBS}'), repos='https://cloud.r-project.org/')"
65+
- name: Install R packages (Windows)
66+
if: startsWith(matrix.os, 'windows')
67+
shell: pwsh
4968
run: |
50-
R -e "install.packages(c('remotes'), lib=c('${R_LIBS}'), repo='https://cloud.r-project.org/')"
69+
Rscript -e "lib <- Sys.getenv('R_LIBS'); lib <- normalizePath(lib, winslash='/', mustWork=FALSE); dir.create(lib, recursive=TRUE, showWarnings=FALSE); install.packages('remotes', lib=lib, repos='https://cloud.r-project.org/')"
70+
Rscript.exe -e "install.packages(c('remotes', 'desc'), repos='https://cloud.r-project.org/')"
5171
- name: Build and test
72+
if: runner.os == 'Linux' || runner.os == 'macOS'
5273
run: |
5374
set -x
5475
R -e "remotes::install_git(c('.'), lib=c('${R_LIBS}'), configure.vars=c('"MAKEJ=2"'))"
5576
env:
5677
ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS: 2
78+
- name: Build and test (Windows)
79+
if: startsWith(matrix.os, 'windows')
80+
shell: pwsh
81+
env:
82+
ITK_GLOBAL_DEFAULT_NUMBER_OF_THREADS: 2
83+
run: |
84+
$env:MAKEJ="3"
85+
Rcmd.exe INSTALL --build .

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.Rproj.user
2+
.Rhistory
3+
.RData
4+
.Ruserdata
5+
*.Rproj

README.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,13 @@ Use multicore compilation and build additional modules not included in the defau
2626
remotes::install_github("SimpleITK/SimpleITKRInstaller", configure.vars=c("MAKEJ=6", "ADDITIONAL_SITK_MODULES=-DSimpleITK_USE_ELASTIX=ON\\ -DModule_ITKIODCMTK:BOOL=ON"))
2727
```
2828

29+
Note:
30+
On Linux and Mac requires [CMake](https://cmake.org/) and [git](https://git-scm.com/) in the path.
2931

30-
Requires _cmake_ and _git_ in the path.
31-
32-
Tested on Linux and Mac.
32+
On Windows requires [rtools](https://cran.r-project.org/bin/windows/Rtools/) installation and setting the `RTOOLS_HOME` environment variable. For example:
33+
```R
34+
Sys.setenv(RTOOLS_HOME = "C:/rtools45")
35+
```
3336

3437
# How to Cite
3538

configure

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
#
99
export SimpleITKGit=$(Rscript -e "d <- desc::desc(file='DESCRIPTION'); urls <- strsplit(d\$get_field('URL'), ',')[[1]]; cat(trimws(urls[1]))")
1010
export SITKTAG=v$(Rscript -e "cat(desc::desc_get_field('Version', file='DESCRIPTION'))")
11+
# TODO: parse SITKTAG from DESCRIPTION after new release
12+
# export SITKTAG=v$(Rscript -e "cat(desc::desc_get_field('Version', file='DESCRIPTION'))")
13+
export SITKTAG='1899b2'
1114

1215
export PKGBASED=$(pwd)
1316
echo ${PKGBASED}

configure.win

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#!/usr/bin/env sh
2+
set -e
3+
4+
# configure script that will fetch and build SimpleITK, then move the results
5+
# to somewhere that R can install. It takes a long time and uses
6+
# a substantial amount of disk space
7+
#
8+
# Requires rtools (https://cran.r-project.org/bin/windows/Rtools/)
9+
#
10+
11+
# --- Settings ---
12+
# Load shared configuration for all OS (SimpleITK repository URL and tag)
13+
export SimpleITKGit=$(Rscript -e "d <- desc::desc(file='DESCRIPTION'); urls <- strsplit(d\$get_field('URL'), ',')[[1]]; cat(trimws(urls[1]))")
14+
# TODO: parse SITKTAG from DESCRIPTION after new release
15+
# export SITKTAG=v$(Rscript -e "cat(desc::desc_get_field('Version', file='DESCRIPTION'))")
16+
export SITKTAG='1899b2'
17+
18+
PKGBASED=$(pwd)
19+
echo "$PKGBASED"
20+
21+
# --- Check R_HOME and RTOOLS_HOME---
22+
if [ -z "$R_HOME" ]; then
23+
echo "Environment variable \"R_HOME\" is not set!" 1>&2
24+
exit 1
25+
fi
26+
27+
export RTOOLS_HOME="$(ls -d /c/rtools* | head -n 1)"
28+
if [ -z "$RTOOLS_HOME" ]; then
29+
echo "Environment variable \"RTOOLS_HOME\" is not set!" 1>&2
30+
exit 1
31+
fi
32+
33+
# Update PATH to include Rtools binaries
34+
export PATH="${RTOOLS_HOME}/usr/bin:${RTOOLS_HOME}/x86_64-w64-mingw32.static.posix/bin:${PATH}"
35+
36+
# Use Rscript on Windows
37+
RCALL="${R_HOME}/bin/Rscript.exe"
38+
export RCALL
39+
40+
echo "R_LIBS is: ${R_LIBS}"
41+
c++ --version || gcc --version || echo "no c++ compiler found"
42+
cmake --version || echo "cmake not found"
43+
make --version || echo "make not found"
44+
$RCALL --version || echo "R not found"
45+
46+
47+
# --- Build location: short path to avoid ITK limit ---
48+
BUILDDIR="C:/bld"
49+
echo "Using short build directory: $BUILDDIR"
50+
mkdir -p "$BUILDDIR"
51+
52+
# Pull compiler flags from R (optional but kept for parity)
53+
CC="$("${R_HOME}/bin/R.exe" CMD config CC)"
54+
CXX="$("${R_HOME}/bin/R.exe" CMD config CXX)"
55+
CFLAGS="$("${R_HOME}/bin/R.exe" CMD config CFLAGS)"
56+
CXXFLAGS="$("${R_HOME}/bin/R.exe" CMD config CXX11FLAGS)"
57+
CPPFLAGS="$("${R_HOME}/bin/R.exe" CMD config CPPFLAGS)"
58+
export CC CXX CFLAGS CXXFLAGS CPPFLAGS
59+
60+
# Parallelism (default 1 if not provided)
61+
: "${MAKEJ:=1}"
62+
export MAKEJ
63+
64+
# --- Build in SITK directory ---
65+
(
66+
cd "$BUILDDIR"
67+
68+
if [ ! -d SimpleITK ]; then
69+
git clone "$SimpleITKGit"
70+
cd SimpleITK
71+
git checkout "$SITKTAG"
72+
else
73+
cd SimpleITK
74+
git fetch --tags
75+
git checkout "$SITKTAG"
76+
fi
77+
78+
SITK_SRC="$(pwd)"
79+
80+
mkdir -p ../Build
81+
cd ../Build
82+
83+
echo "Path:"
84+
echo $PWD
85+
86+
# Configure with Unix Makefiles (Rtools toolchain)
87+
cmake -G "Unix Makefiles" \
88+
-DWRAP_DEFAULT=OFF \
89+
-DWRAP_R=ON \
90+
-DSimpleITK_BUILD_DISTRIBUTE=ON \
91+
-DBUILD_EXAMPLES=OFF \
92+
-DBUILD_TESTING=OFF \
93+
-DITK_SKIP_PATH_LENGTH_CHECK=ON \
94+
-DCMAKE_BUILD_TYPE=MinSizeRel \
95+
-DITK_USE_BUILD_DIR:BOOL=ON \
96+
${ADDITIONAL_SITK_MODULES} \
97+
"${BUILDDIR}/SimpleITK/SuperBuild/"
98+
99+
echo "Parallel build using -j${MAKEJ}"
100+
echo $PWD
101+
# Build the specific target with parallel jobs
102+
cmake --build . --target SimpleITK-build -- -j"${MAKEJ}"
103+
104+
# Remove ITK-build to save space (if present)
105+
[ -d ITK-build ] && rm -rf ITK-build
106+
107+
# Move wrapped R package into the package root
108+
# TODO: sitkmove.R fails to move for Windows
109+
cp -r SimpleITK-build/Wrapping/R/Packaging/SimpleITK/* "$PKGBASED/."
110+
)

0 commit comments

Comments
 (0)