install.libs.R 5.44 KB
Newer Older
Laurae's avatar
Laurae committed
1
2
# User options
use_precompile <- FALSE
3
4
use_gpu <- FALSE
use_mingw <- FALSE
Laurae's avatar
Laurae committed
5

6
if (.Machine$sizeof.pointer != 8L) {
7
  stop("LightGBM only supports 64-bit R, please check the version of R and Rtools.")
Guolin Ke's avatar
Guolin Ke committed
8
9
}

10
R_int_UUID <- .Internal(internalsID())
11
R_ver <- as.double(R.Version()$major) + as.double(R.Version()$minor) / 10.0
12

13
if (!(R_int_UUID == "0310d4b8-ccb1-4bb8-ba94-d36a55f60262"
14
    || R_int_UUID == "2fdf6c18-697a-4ba7-b8ef-11c0d92f1327")) {
15
  print("Warning: unmatched R_INTERNALS_UUID, may cannot run normally.")
16
}
James Lamb's avatar
James Lamb committed
17
18

# Move in CMakeLists.txt
19
20
21
22
23
24
25
write_succeeded <- file.copy(
  "../inst/bin/CMakeLists.txt"
  , "CMakeLists.txt"
  , overwrite = TRUE
)
if (!write_succeeded) {
  stop("Copying CMakeLists.txt failed")
James Lamb's avatar
James Lamb committed
26
27
}

28
29
30
31
# Get some paths
source_dir <- file.path(R_PACKAGE_SOURCE, "src", fsep = "/")
build_dir <- file.path(source_dir, "build", fsep = "/")

Laurae's avatar
Laurae committed
32
33
34
35
# Check for precompilation
if (!use_precompile) {

  # Prepare building package
36
37
38
39
40
  dir.create(
    build_dir
    , recursive = TRUE
    , showWarnings = FALSE
  )
Laurae's avatar
Laurae committed
41
  setwd(build_dir)
42

43
  # Prepare installation steps
Guolin Ke's avatar
Guolin Ke committed
44
  cmake_cmd <- "cmake "
45
  build_cmd <- "make _lightgbm"
46
  lib_folder <- file.path(source_dir, fsep = "/")
47

Guolin Ke's avatar
Guolin Ke committed
48
49
50
  if (use_gpu) {
    cmake_cmd <- paste0(cmake_cmd, " -DUSE_GPU=ON ")
  }
51
52
53
  if (R_ver >= 3.5) {
    cmake_cmd <- paste0(cmake_cmd, " -DUSE_R35=ON ")
  }
54
  cmake_cmd <- paste0(cmake_cmd, " -DBUILD_FOR_R=ON ")
Guolin Ke's avatar
Guolin Ke committed
55

56
57
58
59
60
61
62
63
64
65
66
  # Pass in R version, used to help find R executable for linking
  R_version_string <- paste(
    R.Version()[["major"]]
    , R.Version()[["minor"]]
    , sep = "."
  )
  cmake_cmd <- sprintf(
    paste0(cmake_cmd, " -DCMAKE_R_VERSION='%s' ")
    , R_version_string
  )

67
  # Check if Windows installation (for gcc vs Visual Studio)
Laurae's avatar
Laurae committed
68
69
  if (WINDOWS) {
    if (use_mingw) {
70
      print("Trying to build with MinGW")
Guolin Ke's avatar
Guolin Ke committed
71
      cmake_cmd <- paste0(cmake_cmd, " -G \"MinGW Makefiles\" ")
72
      build_cmd <- "mingw32-make.exe _lightgbm"
73
      system(paste0(cmake_cmd, " ..")) # Must build twice for Windows due sh.exe in Rtools
Laurae's avatar
Laurae committed
74
    } else {
Guolin Ke's avatar
Guolin Ke committed
75
      local_vs_def <- ""
76
77
78
79
80
      vs_versions <- c(
        "Visual Studio 16 2019"
        , "Visual Studio 15 2017"
        , "Visual Studio 14 2015"
      )
81
      for (vs in vs_versions) {
82
        print(paste0("Trying to build with: '", vs, "'"))
83
        vs_def <- paste0(" -G \"", vs, "\" -A x64")
Guolin Ke's avatar
Guolin Ke committed
84
85
        tmp_cmake_cmd <- paste0(cmake_cmd, vs_def)
        try_vs <- system(paste0(tmp_cmake_cmd, " .."))
86
87
        if (try_vs == 0L) {
          local_vs_def <- vs_def
88
          print(paste0("Building with '", vs, "' succeeded"))
Guolin Ke's avatar
Guolin Ke committed
89
          break
90
91
        } else {
          unlink("./*", recursive = TRUE) # Clean up build directory
Guolin Ke's avatar
Guolin Ke committed
92
93
        }
      }
94
      if (try_vs == 1L) {
95
96
        print("Building with Visual Studio failed. Attempted with MinGW")
        cmake_cmd <- paste0(cmake_cmd, " -G \"MinGW Makefiles\" ")
97
        system(paste0(cmake_cmd, " ..")) # Must build twice for Windows due sh.exe in Rtools
98
        build_cmd <- "mingw32-make.exe _lightgbm"
99
      } else {
Guolin Ke's avatar
Guolin Ke committed
100
        cmake_cmd <- paste0(cmake_cmd, local_vs_def)
101
        build_cmd <- "cmake --build . --target _lightgbm --config Release"
102
        lib_folder <- file.path(source_dir, "Release", fsep = "/")
103
      }
104
105
    }
  }
106

Laurae's avatar
Laurae committed
107
108
  # Install
  system(paste0(cmake_cmd, " .."))
109
110
111
112
113

  # R CMD check complains about the .NOTPARALLEL directive created in the cmake
  # Makefile. We don't need it here anyway since targets are built serially, so trying
  # to remove it with this hack
  generated_makefile <- file.path(
114
    build_dir
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
    , "Makefile"
  )
  if (file.exists(generated_makefile)) {
    makefile_txt <- readLines(
      con = generated_makefile
    )
    makefile_txt <- gsub(
      pattern = ".*NOTPARALLEL.*"
      , replacement = ""
      , x = makefile_txt
    )
    writeLines(
      text = makefile_txt
      , con = generated_makefile
      , sep = "\n"
    )
  }

Laurae's avatar
Laurae committed
133
  system(build_cmd)
134
  src <- file.path(lib_folder, paste0("lib_lightgbm", SHLIB_EXT), fsep = "/")
135

Laurae's avatar
Laurae committed
136
} else {
137

Laurae's avatar
Laurae committed
138
  # Has precompiled package
139
  lib_folder <- file.path(R_PACKAGE_SOURCE, "../", fsep = "/")
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
  shared_object_file <- file.path(
    lib_folder
    , paste0("lib_lightgbm", SHLIB_EXT)
    , fsep = "/"
  )
  release_file <- file.path(
    lib_folder
    , paste0("Release/lib_lightgbm", SHLIB_EXT)
    , fsep = "/"
  )
  windows_shared_object_file <- file.path(
    lib_folder
    , paste0("/windows/x64/DLL/lib_lightgbm", SHLIB_EXT)
    , fsep = "/"
  )
  if (file.exists(shared_object_file)) {
    src <- shared_object_file
  } else if (file.exists(release_file)) {
    src <- release_file
Laurae's avatar
Laurae committed
159
  } else {
160
161
    # Expected result: installation will fail if it is not here or any other
    src <- windows_shared_object_file
162
163
164
  }
}

165
166
167
168
# Packages with install.libs.R need to copy some artifacts into the
# expected places in the package structure.
# see https://cran.r-project.org/doc/manuals/r-devel/R-exts.html#Package-subdirectories,
# especially the paragraph on install.libs.R
169
dest <- file.path(R_PACKAGE_DIR, paste0("libs", R_ARCH), fsep = "/")
170
dir.create(dest, recursive = TRUE, showWarnings = FALSE)
Laurae's avatar
Laurae committed
171
if (file.exists(src)) {
172
  print(paste0("Found library file: ", src, " to move to ", dest))
173
  file.copy(src, dest, overwrite = TRUE)
174
175
176
177
178
179

  symbols_file <- file.path(source_dir, "symbols.rds")
  if (file.exists(symbols_file)) {
    file.copy(symbols_file, dest, overwrite = TRUE)
  }

180
} else {
Laurae's avatar
Laurae committed
181
  stop(paste0("Cannot find lib_lightgbm", SHLIB_EXT))
182
}
183
184
185
186
187

# clean up the "build" directory
if (dir.exists(build_dir)) {
  print("Removing 'build/' directory")
  unlink(
188
    x = build_dir
189
190
191
192
    , recursive = TRUE
    , force = TRUE
  )
}