build_r.R 3.44 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
.handle_result(result)

102
# Build the package (do not touch this line!)
James Lamb's avatar
James Lamb committed
103
104
105
# 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
106
.run_shell_command("R", c("CMD", "build", "lightgbm_r", "--keep-empty-dirs"))
James Lamb's avatar
James Lamb committed
107
108
109

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

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