build_r.R 3.39 KB
Newer Older
1
# For macOS users who have decided to use gcc
2
# (replace 8 with version of gcc installed on your machine)
James Lamb's avatar
James Lamb committed
3
4
5
6
7
# NOTE: your gcc / g++ from Homebrew is probably in /usr/local/bin
#export CXX=/usr/local/bin/g++-8 CC=/usr/local/bin/gcc-8
# Sys.setenv("CXX" = "/usr/local/bin/g++-8")
# Sys.setenv("CC" = "/usr/local/bin/gcc-8")

8
9
10
args <- commandArgs(trailingOnly = TRUE)
INSTALL_AFTER_BUILD <- !("--skip-install" %in% args)

James Lamb's avatar
James Lamb committed
11
12
# R returns FALSE (not a non-zero exit code) if a file copy operation
# breaks. Let's fix that
13
14
15
16
.handle_result <- function(res) {
  if (!res) {
    stop("Copying files failed!")
  }
James Lamb's avatar
James Lamb committed
17
18
}

19
# system() will not raise an R exception if the process called
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# fails. Wrapping it here to get that behavior.
#
# system() introduces a lot of overhead, at least on Windows,
# so trying processx if it is available
.run_shell_command <- function(cmd, args, strict = TRUE) {
    on_windows <- .Platform$OS.type == "windows"
    has_processx <- suppressMessages({
      suppressWarnings({
        require("processx")  # nolint
      })
    })
    if (has_processx && on_windows) {
      result <- processx::run(
        command = cmd
        , args = args
        , windows_verbatim_args = TRUE
        , error_on_status = FALSE
        , echo = TRUE
      )
      exit_code <- result$status
    } else {
      if (on_windows) {
        message(paste0(
          "Using system() to run shell commands. Installing "
          , "'processx' with install.packages('processx') might "
          , "make this faster."
        ))
      }
      cmd <- paste0(cmd, " ", paste0(args, collapse = " "))
      exit_code <- system(cmd)
    }

    if (exit_code != 0L && isTRUE(strict)) {
53
54
        stop(paste0("Command failed with exit code: ", exit_code))
    }
55
    return(invisible(exit_code))
56
57
}

James Lamb's avatar
James Lamb committed
58
59
60
61
62
# Make a new temporary folder to work in
unlink(x = "lightgbm_r", recursive = TRUE)
dir.create("lightgbm_r")

# copy in the relevant files
63
64
65
66
67
68
result <- file.copy(
  from = "R-package/./"
  , to = "lightgbm_r/"
  , recursive = TRUE
  , overwrite = TRUE
)
James Lamb's avatar
James Lamb committed
69
70
.handle_result(result)

71
72
73
74
75
76
result <- file.copy(
  from = "include/"
  , to = file.path("lightgbm_r", "src/")
  , recursive = TRUE
  , overwrite = TRUE
)
James Lamb's avatar
James Lamb committed
77
78
.handle_result(result)

79
80
81
82
83
84
result <- file.copy(
  from = "src/"
  , to = file.path("lightgbm_r", "src/")
  , recursive = TRUE
  , overwrite = TRUE
)
Gao Tao's avatar
Gao Tao committed
85
86
.handle_result(result)

87
88
89
90
91
92
result <- file.copy(
  from = "compute/"
  , to = file.path("lightgbm_r", "src/")
  , recursive = TRUE
  , overwrite = TRUE
)
James Lamb's avatar
James Lamb committed
93
94
.handle_result(result)

95
96
97
98
99
result <- file.copy(
  from = "CMakeLists.txt"
  , to = file.path("lightgbm_r", "inst", "bin/")
  , overwrite = TRUE
)
James Lamb's avatar
James Lamb committed
100
101
102
103
104
.handle_result(result)

# NOTE: --keep-empty-dirs is necessary to keep the deep paths expected
#       by CMake while also meeting the CRAN req to create object files
#       on demand
105
.run_shell_command("R", c("CMD", "build", "lightgbm_r", "--keep-empty-dirs"))
James Lamb's avatar
James Lamb committed
106
107
108

# Install the package
version <- gsub(
109
110
111
  "Version: ",
  "",
  grep(
112
113
114
    "Version: "
    , readLines(con = file.path("lightgbm_r", "DESCRIPTION"))
    , value = TRUE
115
  )
James Lamb's avatar
James Lamb committed
116
117
118
)
tarball <- file.path(getwd(), sprintf("lightgbm_%s.tar.gz", version))

119
120
install_cmd <- "R"
install_args <- c("CMD", "INSTALL", "--no-multiarch", "--with-keep.source", tarball)
121
if (INSTALL_AFTER_BUILD) {
122
  .run_shell_command(install_cmd, install_args)
123
} else {
124
  cmd <- paste0(install_cmd, " ", paste0(install_args, collapse = " "))
125
126
  print(sprintf("Skipping installation. Install the package with command '%s'", cmd))
}