Skip to content

Commit

Permalink
[R-package] [ci] Add Windows CI for R package (fixes #2335) (#2936)
Browse files Browse the repository at this point in the history
* first test of appveyor

* strings are strings

* lil bit of build script

* fixing paths

* removed unnecessary file

* updated CRAN URL

* added a lot more printing

* fixing paths

* more stuff

* fixed paths

* more stuff

* more path guessing

* even more paths

* more stuff

* moar logz

* and now for something totally different

* please work

* ok could be a thing

* changing directories

* we might be in business

* fixed install syntax

* tryinv mingw

* more mingw

* ignore Suggests check

* trying Azure DevOps

* just run bare minimum for Azure DevOps

* fixed  build dir thing

* trying to set libPaths

* more testing

* trying R 3.6.3

* R 3.6.3

* this feels right

* still messing around with libraries

* more paths

* removed duplication in Windows testing code

* simpler

* fixed conda stuff

* more conda stuff

* more fixes

* fixed testing script

* moved AppVeyor setup to the top

* commenting

* ch-ch-ch-ch-chaaaanges

* paths

* plz work

* fixed conda stuff in Windows CI

* uncommented stuff to test a full build

* fixed quotes and removed some unnecessary stuff

* added install.libs.R change

* quotes are impoortant

* added commented-out stuff back in

* added Windows script, download retries, and MSVC linking

* minor fixes

* cleaned up debugging code in FindLibR

* cleaned up debugging code and moved R first in CI

* fixed vsts-ci indentation

* cut documentation stuff out of MSVC build

* fix R CMD check for Azure

* misc whitespace changes

* Added echoing of build logs from R CMD check

* cut out more documentation tests

* fixed NOTE about imports from Matrix

* moved some changes out of this PR and into #2963

* fixed whitespace stuff

* added check on number of NOTES

* adding better checks

* fixing check on NOTEs

* removing unnecessary variable

* Update .ci/test_r_package_windows.ps1

Co-Authored-By: Nikita Titov <nekit94-08@mail.ru>

* some changes

* fix quoting

* trying MINGW on Azure DevOps

* fixing paths

* more paths

* fixing paths

* testing paths

* fixing slashes

* pinned CTAN mirror

* get better logs

* made sure Azure finds MinGW, fixed search for LIBR_CORE_LIBRARY, stopped building R docs on Azure

* Apply suggestions from code review

Co-Authored-By: Nikita Titov <nekit94-08@mail.ru>

* added CXX, CC for Windows builds and changed back to building docs on all MINGW builds

* stored LIBR_CORE_LIBRARY hints in one variable

* Apply suggestions from code review

Co-Authored-By: Nikita Titov <nekit94-08@mail.ru>

* changes from code review

* increased parallel builds for Azure CI

* Apply suggestions from code review

Co-Authored-By: Nikita Titov <nekit94-08@mail.ru>

Co-authored-by: Nikita Titov <nekit94-08@mail.ru>
  • Loading branch information
jameslamb and StrikerRUS authored Apr 26, 2020
1 parent eedc1a7 commit 2c18a0f
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 9 deletions.
2 changes: 2 additions & 0 deletions .appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ configuration: # a trick to construct a build matrix with multiple Python versi

environment:
matrix:
- COMPILER: MINGW
TASK: r-package
- COMPILER: MSVC
TASK: python
- COMPILER: MINGW
Expand Down
108 changes: 108 additions & 0 deletions .ci/test_r_package_windows.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# Download a file and retry upon failure. This looks like
# an infinite loop but CI-level timeouts will kill it
function Download-File-With-Retries {
param(
[string]$url,
[string]$destfile
)
do {
Write-Output "Downloading ${url}"
sleep 5;
(New-Object System.Net.WebClient).DownloadFile($url, $destfile)
} while(!$?);
}

$env:R_WINDOWS_VERSION = "3.6.3"
$env:R_LIB_PATH = "$env:BUILD_SOURCESDIRECTORY/RLibrary" -replace '[\\]', '/'
$env:PATH = "$env:R_LIB_PATH/Rtools/bin;" + "$env:R_LIB_PATH/R/bin/x64;" + "$env:R_LIB_PATH/miktex/texmfs/install/miktex/bin/x64;" + $env:PATH
$env:CRAN_MIRROR = "https://cloud.r-project.org/"
$env:CTAN_MIRROR = "https://ctan.math.illinois.edu/systems/win32/miktex/tm/packages/"

if ($env:COMPILER -eq "MINGW") {
$env:CXX = "$env:R_LIB_PATH/Rtools/mingw_64/bin/g++.exe"
$env:CC = "$env:R_LIB_PATH/Rtools/mingw_64/bin/gcc.exe"
}

cd $env:BUILD_SOURCESDIRECTORY
tzutil /s "GMT Standard Time"
[Void][System.IO.Directory]::CreateDirectory($env:R_LIB_PATH)

if ($env:COMPILER -eq "MINGW") {
Write-Output "Telling R to use MinGW"
$install_libs = "$env:BUILD_SOURCESDIRECTORY/R-package/src/install.libs.R"
((Get-Content -path $install_libs -Raw) -replace 'use_mingw <- FALSE','use_mingw <- TRUE') | Set-Content -Path $install_libs
}

# download R and RTools
Write-Output "Downloading R and Rtools"
Download-File-With-Retries -url "https://cloud.r-project.org/bin/windows/base/old/$env:R_WINDOWS_VERSION/R-$env:R_WINDOWS_VERSION-win.exe" -destfile "R-win.exe"
Download-File-With-Retries -url "https://cloud.r-project.org/bin/windows/Rtools/Rtools35.exe" -destfile "Rtools.exe"

# Install R
Write-Output "Installing R"
Start-Process -FilePath R-win.exe -NoNewWindow -Wait -ArgumentList "/VERYSILENT /DIR=$env:R_LIB_PATH/R /COMPONENTS=main,x64" ; Check-Output $?
Write-Output "Done installing R"

Write-Output "Installing Rtools"
Start-Process -FilePath Rtools.exe -NoNewWindow -Wait -ArgumentList "/VERYSILENT /DIR=$env:R_LIB_PATH/Rtools" ; Check-Output $?
Write-Output "Done installing Rtools"

# MiKTeX and pandoc can be skipped on non-MINGW builds, since we don't
# build the package documentation for those
if ($env:COMPILER -eq "MINGW") {
Write-Output "Downloading MiKTeX"
Download-File-With-Retries -url "https://miktex.org/download/win/miktexsetup-x64.zip" -destfile "miktexsetup-x64.zip"
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::ExtractToDirectory("miktexsetup-x64.zip", "miktex")
Write-Output "Setting up MiKTeX"
.\miktex\miktexsetup.exe --remote-package-repository="$env:CTAN_MIRROR" --local-package-repository=./miktex/download --package-set=essential --quiet download ; Check-Output $?
Write-Output "Installing MiKTeX"
.\miktex\download\miktexsetup.exe --remote-package-repository="$env:CTAN_MIRROR" --portable="$env:R_LIB_PATH/miktex" --quiet install ; Check-Output $?
Write-Output "Done installing MiKTeX"

initexmf --set-config-value [MPM]AutoInstall=1
conda install -q -y --no-deps pandoc
}

Add-Content .Renviron "R_LIBS=$env:R_LIB_PATH"

Write-Output "Installing dependencies"
$packages = "c('data.table', 'jsonlite', 'Matrix', 'R6', 'testthat'), dependencies = c('Imports', 'Depends', 'LinkingTo')"
Rscript --vanilla -e "options(install.packages.check.source = 'no'); install.packages($packages, repos = '$env:CRAN_MIRROR', type = 'binary', lib = '$env:R_LIB_PATH')" ; Check-Output $?

Write-Output "Building R package"
Rscript build_r.R --skip-install ; Check-Output $?

$PKG_FILE_NAME = Get-Item *.tar.gz
$LOG_FILE_NAME = "lightgbm.Rcheck/00check.log"

$env:_R_CHECK_FORCE_SUGGESTS_ = 0
if ($env:COMPILER -ne "MINGW") {
Write-Output "Running R CMD check without checking documentation"
R.exe CMD check --no-multiarch --no-examples --no-manual --ignore-vignettes ${PKG_FILE_NAME} ; $check_succeeded = $?
} else {
Write-Output "Running R CMD check as CRAN"
R.exe CMD check --no-multiarch --as-cran ${PKG_FILE_NAME} ; $check_succeeded = $?
}

Write-Output "R CMD check build logs:"
Get-Content -Path $env:BUILD_SOURCESDIRECTORY\lightgbm.Rcheck\00install.out

Check-Output $check_succeeded

Write-Output "Looking for issues with R CMD check results"
if (Get-Content "$LOG_FILE_NAME" | Select-String -Pattern "WARNING" -Quiet) {
echo "WARNINGS have been found by R CMD check!"
Check-Output $False
}

$note_str = Get-Content "${LOG_FILE_NAME}" | Select-String -Pattern ' NOTE' | Out-String ; Check-Output $?
$relevant_line = $note_str -match '.*Status: (\d+) NOTE.*'
$NUM_CHECK_NOTES = $matches[1]
$ALLOWED_CHECK_NOTES = 3
if ([int]$NUM_CHECK_NOTES -gt $ALLOWED_CHECK_NOTES) {
Write-Output "Found ${NUM_CHECK_NOTES} NOTEs from R CMD check. Only ${ALLOWED_CHECK_NOTES} are allowed"
Check-Output $False
}

Write-Output "No issues were found checking the R package"
5 changes: 5 additions & 0 deletions .ci/test_windows.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ if (Test-Path env:APPVEYOR) {
$env:BUILD_SOURCESDIRECTORY = $env:APPVEYOR_BUILD_FOLDER
}

if ($env:TASK -eq "r-package") {
& $env:BUILD_SOURCESDIRECTORY\.ci\test_r_package_windows.ps1 ; Check-Output $?
Exit 0
}

# setup for Python
conda init powershell
conda activate
Expand Down
9 changes: 6 additions & 3 deletions .vsts-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
vmImage: 'ubuntu-latest'
container: ubuntu1404
strategy:
maxParallel: 6
maxParallel: 7
matrix:
regular:
TASK: regular
Expand Down Expand Up @@ -76,7 +76,7 @@ jobs:
pool:
vmImage: 'macOS-10.14'
strategy:
maxParallel: 3
maxParallel: 4
matrix:
regular:
TASK: regular
Expand Down Expand Up @@ -117,8 +117,11 @@ jobs:
pool:
vmImage: 'vs2017-win2016'
strategy:
maxParallel: 3
maxParallel: 4
matrix:
r_package:
TASK: r-package
COMPILER: MINGW
regular:
TASK: regular
PYTHON_VERSION: 3.6
Expand Down
1 change: 1 addition & 0 deletions R-package/NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export(saveRDS.lgb.Booster)
export(setinfo)
export(slice)
import(methods)
importFrom(Matrix,Matrix)
importFrom(R6,R6Class)
importFrom(data.table,":=")
importFrom(data.table,as.data.table)
Expand Down
1 change: 1 addition & 0 deletions R-package/R/lightgbm.R
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ NULL

# Various imports
#' @import methods
#' @importFrom Matrix Matrix
#' @importFrom R6 R6Class
#' @useDynLib lib_lightgbm , .registration = TRUE
NULL
Expand Down
26 changes: 20 additions & 6 deletions R-package/src/cmake/modules/FindLibR.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -174,17 +174,31 @@ execute_process(
OUTPUT_VARIABLE LIBR_LIB_DIR
)

set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory")
set(LIBR_EXECUTABLE ${LIBR_EXECUTABLE} CACHE PATH "R executable")
set(LIBR_INCLUDE_DIRS ${LIBR_INCLUDE_DIRS} CACHE PATH "R include directory")
set(LIBR_LIB_DIR ${LIBR_LIB_DIR} CACHE PATH "R shared libraries directory")

# where is R.so / R.dll / libR.so likely to be found?
set(LIBR_PATH_HINTS "${CMAKE_CURRENT_BINARY_DIR}" "${LIBR_LIB_DIR}" "${LIBR_HOME}/bin/${R_ARCH}" "${LIBR_HOME}/bin" "${LIBR_LIBRARIES}")

# look for the core R library
find_library(
LIBR_CORE_LIBRARY
NAMES R
HINTS "${CMAKE_CURRENT_BINARY_DIR}" "${LIBR_LIB_DIR}" "${LIBR_HOME}/bin" "${LIBR_LIBRARIES}"
NAMES R R.dll
HINTS ${LIBR_PATH_HINTS}
)

set(LIBR_HOME ${LIBR_HOME} CACHE PATH "R home directory")
set(LIBR_EXECUTABLE ${LIBR_EXECUTABLE} CACHE PATH "R executable")
set(LIBR_INCLUDE_DIRS ${LIBR_INCLUDE_DIRS} CACHE PATH "R include directory")
set(LIBR_LIB_DIR ${LIBR_LIB_DIR} CACHE PATH "R shared libraries directory")
# starting from CMake 3.17, find_library() will not find .dll files by default
# https://cmake.org/cmake/help/v3.17/release/3.17.html#other-changes
if (WIN32 AND NOT LIBR_CORE_LIBRARY)
find_file(
LIBR_CORE_LIBRARY
NAME R.dll
HINTS ${LIBR_PATH_HINTS}
)
endif()

set(LIBR_CORE_LIBRARY ${LIBR_CORE_LIBRARY} CACHE PATH "R core shared library")

if(WIN32 AND MSVC)
Expand Down
1 change: 1 addition & 0 deletions R-package/src/install.libs.R
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ if (!use_precompile) {
# Check if Windows installation (for gcc vs Visual Studio)
if (WINDOWS) {
if (use_mingw) {
print("Trying to build with MinGW")
cmake_cmd <- paste0(cmake_cmd, " -G \"MinGW Makefiles\" ")
build_cmd <- "mingw32-make.exe _lightgbm"
system(paste0(cmake_cmd, " ..")) # Must build twice for Windows due sh.exe in Rtools
Expand Down

0 comments on commit 2c18a0f

Please sign in to comment.