CMakeLists.txt 19 KB
Newer Older
1
2
3
4
5
6
7
option(USE_MPI "Enable MPI-based distributed learning" OFF)
option(USE_OPENMP "Enable OpenMP" ON)
option(USE_GPU "Enable GPU-accelerated training" OFF)
option(USE_SWIG "Enable SWIG to generate Java API" OFF)
option(USE_HDFS "Enable HDFS support (EXPERIMENTAL)" OFF)
option(USE_TIMETAG "Set to ON to output time costs" OFF)
option(USE_CUDA "Enable CUDA-accelerated training (EXPERIMENTAL)" OFF)
8
option(USE_CUDA_EXP "Enable CUDA-accelerated training with more acceleration (EXPERIMENTAL)" OFF)
9
10
11
option(USE_DEBUG "Set to ON for Debug mode" OFF)
option(USE_SANITIZER "Use santizer flags" OFF)
set(
12
13
14
15
16
17
18
  ENABLED_SANITIZERS
  "address" "leak" "undefined"
  CACHE
  STRING
  "Semicolon separated list of sanitizer names, e.g., 'address;leak'. \
Supported sanitizers are address, leak, undefined and thread."
)
19
20
21
22
option(BUILD_CPP_TEST "Build C++ tests with Google Test" OFF)
option(BUILD_STATIC_LIB "Build static library" OFF)
option(__BUILD_FOR_R "Set to ON if building lib_lightgbm for use with the R package" OFF)
option(__INTEGRATE_OPENCL "Set to ON if building LightGBM with the OpenCL ICD Loader and its dependencies included" OFF)
23

24
if(APPLE)
25
  option(APPLE_OUTPUT_DYLIB "Output dylib shared library" OFF)
26
endif()
27

28
29
30
if(__INTEGRATE_OPENCL)
  cmake_minimum_required(VERSION 3.11)
elseif(USE_GPU OR APPLE)
31
  cmake_minimum_required(VERSION 3.2)
32
elseif(USE_CUDA OR USE_CUDA_EXP)
33
  cmake_minimum_required(VERSION 3.16)
34
else()
35
  cmake_minimum_required(VERSION 3.0)
36
endif()
Guolin Ke's avatar
Guolin Ke committed
37

38
project(lightgbm LANGUAGES C CXX)
Guolin Ke's avatar
Guolin Ke committed
39

40
41
42
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/modules")

#-- Sanitizer
43
if(USE_SANITIZER)
44
45
  if(MSVC)
    message(FATAL_ERROR "Sanitizers are not supported with MSVC.")
46
  endif()
47
48
  include(cmake/Sanitizer.cmake)
  enable_sanitizers("${ENABLED_SANITIZERS}")
49
endif()
50

51
52
53
54
55
56
if(__INTEGRATE_OPENCL)
  set(__INTEGRATE_OPENCL ON CACHE BOOL "" FORCE)
  set(USE_GPU OFF CACHE BOOL "" FORCE)
  message(STATUS "Building library with integrated OpenCL components")
endif()

Qiwei Ye's avatar
Qiwei Ye committed
57
58
59
60
61
62
63
64
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.8.2")
    message(FATAL_ERROR "Insufficient gcc version")
  endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "3.8")
    message(FATAL_ERROR "Insufficient Clang version")
  endif()
65
66
67
68
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
  if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS "8.1.0")
    message(FATAL_ERROR "Insufficient AppleClang version")
  endif()
69
  cmake_minimum_required(VERSION 3.16)
70
71
elseif(MSVC)
  if(MSVC_VERSION LESS 1900)
72
73
74
75
    message(
      FATAL_ERROR
      "The compiler ${CMAKE_CXX_COMPILER} doesn't support required C++11 features. Please use a newer MSVC."
    )
76
77
  endif()
  cmake_minimum_required(VERSION 3.8)
78
endif()
Guolin Ke's avatar
Guolin Ke committed
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
if(USE_SWIG)
  find_package(SWIG REQUIRED)
  find_package(Java REQUIRED)
  find_package(JNI REQUIRED)
  include(UseJava)
  include(UseSWIG)
  set(SWIG_CXX_EXTENSION "cxx")
  set(SWIG_EXTRA_LIBRARIES "")
  set(SWIG_JAVA_EXTRA_FILE_EXTENSIONS ".java" "JNI.java")
  set(SWIG_MODULE_JAVA_LANGUAGE "JAVA")
  set(SWIG_MODULE_JAVA_SWIG_LANGUAGE_FLAG "java")
  set(CMAKE_SWIG_OUTDIR "${CMAKE_CURRENT_BINARY_DIR}/java")
  include_directories(Java_INCLUDE_DIRS)
  include_directories(JNI_INCLUDE_DIRS)
  include_directories($ENV{JAVA_HOME}/include)
95
  if(WIN32)
96
      file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/com/microsoft/ml/lightgbm/windows/x86_64")
97
      include_directories($ENV{JAVA_HOME}/include/win32)
98
  elseif(APPLE)
99
      file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/com/microsoft/ml/lightgbm/osx/x86_64")
100
      include_directories($ENV{JAVA_HOME}/include/darwin)
101
  else()
102
      file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/com/microsoft/ml/lightgbm/linux/x86_64")
103
104
      include_directories($ENV{JAVA_HOME}/include/linux)
  endif()
105
endif()
106

107
set(EIGEN_DIR "${PROJECT_SOURCE_DIR}/external_libs/eigen")
108
109
include_directories(${EIGEN_DIR})

110
# See https://gitlab.com/libeigen/eigen/-/blob/master/COPYING.README
111
add_definitions(-DEIGEN_MPL2_ONLY)
112

113
if(__BUILD_FOR_R)
114
115
116
117
118
    find_package(LibR REQUIRED)
    message(STATUS "LIBR_EXECUTABLE: ${LIBR_EXECUTABLE}")
    message(STATUS "LIBR_INCLUDE_DIRS: ${LIBR_INCLUDE_DIRS}")
    message(STATUS "LIBR_CORE_LIBRARY: ${LIBR_CORE_LIBRARY}")
    include_directories(${LIBR_INCLUDE_DIRS})
119
    add_definitions(-DLGB_R_BUILD)
120
endif()
121

122
if(USE_TIMETAG)
123
    add_definitions(-DTIMETAG)
124
endif()
125

Guolin Ke's avatar
Guolin Ke committed
126
if(USE_DEBUG)
127
    add_definitions(-DDEBUG)
128
endif()
Guolin Ke's avatar
Guolin Ke committed
129

Guolin Ke's avatar
Guolin Ke committed
130
if(USE_MPI)
Guolin Ke's avatar
Guolin Ke committed
131
    find_package(MPI REQUIRED)
132
    add_definitions(-DUSE_MPI)
Guolin Ke's avatar
Guolin Ke committed
133
else()
134
    add_definitions(-DUSE_SOCKET)
135
endif()
Guolin Ke's avatar
Guolin Ke committed
136

137
if(USE_CUDA OR USE_CUDA_EXP)
138
    set(CMAKE_CUDA_HOST_COMPILER "${CMAKE_CXX_COMPILER}")
139
    enable_language(CUDA)
140
    set(USE_OPENMP ON CACHE BOOL "CUDA requires OpenMP" FORCE)
141
endif()
142

143
144
if(USE_OPENMP)
    find_package(OpenMP REQUIRED)
145
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
146
endif()
Guolin Ke's avatar
Guolin Ke committed
147

148
if(USE_GPU)
149
    set(BOOST_COMPUTE_HEADER_DIR ${PROJECT_SOURCE_DIR}/external_libs/compute/include)
150
    include_directories(${BOOST_COMPUTE_HEADER_DIR})
151
152
    find_package(OpenCL REQUIRED)
    include_directories(${OpenCL_INCLUDE_DIRS})
153
    message(STATUS "OpenCL include directory: " ${OpenCL_INCLUDE_DIRS})
154
    if(WIN32)
Guolin Ke's avatar
Guolin Ke committed
155
156
        set(Boost_USE_STATIC_LIBS ON)
    endif()
157
    find_package(Boost 1.56.0 COMPONENTS filesystem system REQUIRED)
158
    if(WIN32)
159
        # disable autolinking in boost
160
        add_definitions(-DBOOST_ALL_NO_LIB)
161
    endif()
Guolin Ke's avatar
Guolin Ke committed
162
    include_directories(${Boost_INCLUDE_DIRS})
163
    add_definitions(-DUSE_GPU)
164
endif()
165

166
167
if(__INTEGRATE_OPENCL)
    if(WIN32)
168
        include(cmake/IntegratedOpenCL.cmake)
169
        add_definitions(-DUSE_GPU)
170
171
    else()
        message(FATAL_ERROR "Integrated OpenCL build is available only for Windows")
172
173
    endif()
endif()
174

175
176
177
178
179
180
if(USE_CUDA OR USE_CUDA_EXP)
    if(USE_CUDA)
      find_package(CUDA 9.0 REQUIRED)
    else()
      find_package(CUDA 10.0 REQUIRED)
    endif()
181
    include_directories(${CUDA_INCLUDE_DIRS})
182
    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -Xcompiler=${OpenMP_CXX_FLAGS} -Xcompiler=-fPIC -Xcompiler=-Wall")
183
184
185
186
187

    set(CUDA_ARCHS "6.0" "6.1" "6.2" "7.0")
    if(CUDA_VERSION VERSION_GREATER_EQUAL "10.0")
        list(APPEND CUDA_ARCHS "7.5")
    endif()
188
189
190
191
192
193
    if(CUDA_VERSION VERSION_GREATER_EQUAL "11.0")
        list(APPEND CUDA_ARCHS "8.0")
    endif()
    if(CUDA_VERSION VERSION_GREATER_EQUAL "11.1")
        list(APPEND CUDA_ARCHS "8.6")
    endif()
194
195
    list(POP_BACK CUDA_ARCHS CUDA_LAST_SUPPORTED_ARCH)
    list(APPEND CUDA_ARCHS "${CUDA_LAST_SUPPORTED_ARCH}+PTX")
196
    cuda_select_nvcc_arch_flags(CUDA_ARCH_FLAGS ${CUDA_ARCHS})
197
    string(REPLACE ";" " " CUDA_ARCH_FLAGS "${CUDA_ARCH_FLAGS}")
198

199
    set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} ${CUDA_ARCH_FLAGS}")
200
    if(USE_DEBUG)
201
      set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -g")
202
    else()
203
      set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -O3 -lineinfo")
204
205
206
    endif()
    message(STATUS "CMAKE_CUDA_FLAGS: ${CMAKE_CUDA_FLAGS}")

207
208
209
210
211
212
    if(USE_CUDA)
      add_definitions(-DUSE_CUDA)
    elseif(USE_CUDA_EXP)
      add_definitions(-DUSE_CUDA_EXP)
    endif()

213
    if(NOT DEFINED CMAKE_CUDA_STANDARD)
214
215
216
217
      set(CMAKE_CUDA_STANDARD 11)
      set(CMAKE_CUDA_STANDARD_REQUIRED ON)
    endif()

218
219
220
221
    set(
      BASE_DEFINES
      -DPOWER_FEATURE_WORKGROUPS=12
      -DUSE_CONSTANT_BUF=0
222
    )
223
224
225
226
    set(
      ALLFEATS_DEFINES
      ${BASE_DEFINES}
      -DENABLE_ALL_FEATURES
227
    )
228
229
230
231
    set(
      FULLDATA_DEFINES
      ${ALLFEATS_DEFINES}
      -DIGNORE_INDICES
232
233
234
235
236
237
238
239
    )

    message(STATUS "ALLFEATS_DEFINES: ${ALLFEATS_DEFINES}")
    message(STATUS "FULLDATA_DEFINES: ${FULLDATA_DEFINES}")

    function(add_histogram hsize hname hadd hconst hdir)
      add_library(histo${hsize}${hname} OBJECT src/treelearner/kernels/histogram${hsize}.cu)
      set_target_properties(histo${hsize}${hname} PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
240
      set_target_properties(histo${hsize}${hname} PROPERTIES CUDA_ARCHITECTURES OFF)
241
242
243
244
245
      if(hadd)
        list(APPEND histograms histo${hsize}${hname})
        set(histograms ${histograms} PARENT_SCOPE)
      endif()
      target_compile_definitions(
246
247
        histo${hsize}${hname}
        PRIVATE
248
249
250
251
252
        -DCONST_HESSIAN=${hconst}
        ${hdir}
      )
    endfunction()

253
    foreach(hsize _16_64_256)
254
255
256
257
258
259
260
      add_histogram("${hsize}" "_sp_const" "True" "1" "${BASE_DEFINES}")
      add_histogram("${hsize}" "_sp" "True" "0" "${BASE_DEFINES}")
      add_histogram("${hsize}" "-allfeats_sp_const" "False" "1" "${ALLFEATS_DEFINES}")
      add_histogram("${hsize}" "-allfeats_sp" "False" "0" "${ALLFEATS_DEFINES}")
      add_histogram("${hsize}" "-fulldata_sp_const" "True" "1" "${FULLDATA_DEFINES}")
      add_histogram("${hsize}" "-fulldata_sp" "True" "0" "${FULLDATA_DEFINES}")
    endforeach()
261
endif()
262

263
264
265
266
267
if(USE_HDFS)
    find_package(JNI REQUIRED)
    find_path(HDFS_INCLUDE_DIR hdfs.h REQUIRED)
    find_library(HDFS_LIB NAMES hdfs REQUIRED)
    include_directories(${HDFS_INCLUDE_DIR})
268
269
    add_definitions(-DUSE_HDFS)
    set(HDFS_CXX_LIBRARIES ${HDFS_LIB} ${JAVA_JVM_LIBRARY})
270
endif()
271

272
273
274
275
276
277
278
279
280
281
282
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <xmmintrin.h>
int main() {
  int a = 0;
  _mm_prefetch(&a, _MM_HINT_NTA);
  return 0;
}
" MM_PREFETCH)

if(${MM_PREFETCH})
283
  message(STATUS "Using _mm_prefetch")
284
  add_definitions(-DMM_PREFETCH)
285
286
endif()

287
288
289
290
291
292
293
294
295
296
297
include(CheckCXXSourceCompiles)
check_cxx_source_compiles("
#include <mm_malloc.h>
int main() {
  char *a = (char*)_mm_malloc(8, 16);
  _mm_free(a);
  return 0;
}
" MM_MALLOC)

if(${MM_MALLOC})
298
  message(STATUS "Using _mm_malloc")
299
  add_definitions(-DMM_MALLOC)
300
301
endif()

Guolin Ke's avatar
Guolin Ke committed
302
if(UNIX OR MINGW OR CYGWIN)
303
  set(
304
305
306
307
    CMAKE_CXX_FLAGS
    "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -Wextra -Wall -Wno-ignored-attributes -Wno-unknown-pragmas -Wno-return-type"
  )
  if(USE_DEBUG)
308
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0")
309
  else()
310
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
311
312
  endif()
  if(USE_SWIG)
313
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-strict-aliasing")
314
315
  endif()
  if(NOT USE_OPENMP)
316
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unknown-pragmas -Wno-unused-private-field")
317
318
  endif()
  if(__BUILD_FOR_R AND CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
319
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-cast-function-type")
320
  endif()
Guolin Ke's avatar
Guolin Ke committed
321
322
endif()

Nikita Titov's avatar
Nikita Titov committed
323
if(WIN32 AND MINGW)
324
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libstdc++")
Nikita Titov's avatar
Nikita Titov committed
325
326
endif()

Guolin Ke's avatar
Guolin Ke committed
327
if(MSVC)
328
    set(
329
      variables
Guolin Ke's avatar
Guolin Ke committed
330
331
332
333
334
335
336
337
338
        CMAKE_C_FLAGS_DEBUG
        CMAKE_C_FLAGS_MINSIZEREL
        CMAKE_C_FLAGS_RELEASE
        CMAKE_C_FLAGS_RELWITHDEBINFO
        CMAKE_CXX_FLAGS_DEBUG
        CMAKE_CXX_FLAGS_MINSIZEREL
        CMAKE_CXX_FLAGS_RELEASE
        CMAKE_CXX_FLAGS_RELWITHDEBINFO
    )
339
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4 /MP")
Guolin Ke's avatar
Guolin Ke committed
340
    if(USE_DEBUG)
341
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /Od")
Guolin Ke's avatar
Guolin Ke committed
342
    else()
343
        set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /Ob2 /Oi /Ot /Oy")
Guolin Ke's avatar
Guolin Ke committed
344
    endif()
Guolin Ke's avatar
Guolin Ke committed
345
else()
346
347
348
    if(NOT BUILD_STATIC_LIB)
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
    endif()
Guolin Ke's avatar
Guolin Ke committed
349
    if(NOT USE_DEBUG)
350
      set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -funroll-loops")
Guolin Ke's avatar
Guolin Ke committed
351
    endif()
352
endif()
Guolin Ke's avatar
Guolin Ke committed
353

354
set(LightGBM_HEADER_DIR ${PROJECT_SOURCE_DIR}/include)
Guolin Ke's avatar
Guolin Ke committed
355

356
357
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR})
Guolin Ke's avatar
Guolin Ke committed
358

359
include_directories(${LightGBM_HEADER_DIR})
Guolin Ke's avatar
Guolin Ke committed
360
361

if(APPLE)
362
  if(APPLE_OUTPUT_DYLIB)
363
    set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib")
364
  else()
365
    set(CMAKE_SHARED_LIBRARY_SUFFIX ".so")
366
  endif()
367
endif()
Guolin Ke's avatar
Guolin Ke committed
368
369
370

if(USE_MPI)
  include_directories(${MPI_CXX_INCLUDE_PATH})
371
endif()
Guolin Ke's avatar
Guolin Ke committed
372

373
374
375
376
377
378
379
380
381
file(
    GLOB
    SOURCES
      src/boosting/*.cpp
      src/io/*.cpp
      src/metric/*.cpp
      src/objective/*.cpp
      src/network/*.cpp
      src/treelearner/*.cpp
382
if(USE_CUDA OR USE_CUDA_EXP)
383
      src/treelearner/*.cu
384
endif()
385
386
387
388
389
390
391
392
if(USE_CUDA_EXP)
      src/treelearner/cuda/*.cpp
      src/treelearner/cuda/*.cu
      src/io/cuda/*.cu
      src/io/cuda/*.cpp
      src/cuda/*.cpp
      src/cuda/*.cu
endif()
Guolin Ke's avatar
Guolin Ke committed
393
394
)

395
396
397
398
add_library(lightgbm_objs OBJECT ${SOURCES})

add_executable(lightgbm src/main.cpp src/application/application.cpp)
target_link_libraries(lightgbm PRIVATE lightgbm_objs)
399

400
set(API_SOURCES "src/c_api.cpp")
401
402
# Only build the R part of the library if building for
# use with the R package
403
if(__BUILD_FOR_R)
404
  list(APPEND API_SOURCES "src/lightgbm_R.cpp")
405
endif()
406

407
408
add_library(lightgbm_capi_objs OBJECT ${API_SOURCES})

409
if(BUILD_STATIC_LIB)
410
  add_library(_lightgbm STATIC)
411
else()
412
  add_library(_lightgbm SHARED)
413
endif()
414
# LightGBM headers include openmp, cuda, R etc. headers,
415
416
# thus PUBLIC is required for building _lightgbm_swig target.
target_link_libraries(_lightgbm PUBLIC lightgbm_capi_objs lightgbm_objs)
417

418
if(MSVC)
419
  set_target_properties(_lightgbm PROPERTIES OUTPUT_NAME "lib_lightgbm")
420
endif()
421

422
423
if(USE_SWIG)
  set_property(SOURCE swig/lightgbmlib.i PROPERTY CPLUSPLUS ON)
424
  list(APPEND swig_options -package com.microsoft.ml.lightgbm)
425
426
427
  set_property(SOURCE swig/lightgbmlib.i PROPERTY SWIG_FLAGS "${swig_options}")
  swig_add_module(_lightgbm_swig java swig/lightgbmlib.i)
  swig_link_libraries(_lightgbm_swig _lightgbm)
428
  # needed to ensure Linux build does not have lib prefix specified twice, e.g. liblib_lightgbm_swig
429
  set_target_properties(_lightgbm_swig PROPERTIES PREFIX "")
430
  # needed in some versions of CMake for VS and MinGW builds to ensure output dll has lib prefix
431
432
433
  set_target_properties(_lightgbm_swig PROPERTIES OUTPUT_NAME "lib_lightgbm_swig")
  if(WIN32)
    if(MINGW OR CYGWIN)
434
435
436
        add_custom_command(
            TARGET _lightgbm_swig
            POST_BUILD
437
            COMMAND "${Java_JAVAC_EXECUTABLE}" -d . java/*.java
438
439
440
441
442
443
444
445
446
447
448
449
450
451
            COMMAND
              "${CMAKE_COMMAND}"
              -E
              copy_if_different
              "${PROJECT_SOURCE_DIR}/lib_lightgbm.dll"
              com/microsoft/ml/lightgbm/windows/x86_64
            COMMAND
              "${CMAKE_COMMAND}"
              -E
              copy_if_different
              "${PROJECT_SOURCE_DIR}/lib_lightgbm_swig.dll"
              com/microsoft/ml/lightgbm/windows/x86_64
            COMMAND "${Java_JAR_EXECUTABLE}" -cf lightgbmlib.jar com
        )
452
    else()
453
454
455
        add_custom_command(
            TARGET _lightgbm_swig
            POST_BUILD
456
457
            COMMAND "${Java_JAVAC_EXECUTABLE}" -d . java/*.java
            COMMAND cp "${PROJECT_SOURCE_DIR}/Release/*.dll" com/microsoft/ml/lightgbm/windows/x86_64
458
459
            COMMAND "${Java_JAR_EXECUTABLE}" -cf lightgbmlib.jar com
        )
460
    endif()
461
  elseif(APPLE)
462
463
464
465
466
467
468
469
470
471
472
    add_custom_command(
        TARGET _lightgbm_swig
        POST_BUILD
        COMMAND "${Java_JAVAC_EXECUTABLE}" -d . java/*.java
        COMMAND cp "${PROJECT_SOURCE_DIR}/*.dylib" com/microsoft/ml/lightgbm/osx/x86_64
        COMMAND
          cp
          "${PROJECT_SOURCE_DIR}/lib_lightgbm_swig.jnilib"
          com/microsoft/ml/lightgbm/osx/x86_64/lib_lightgbm_swig.dylib
        COMMAND "${Java_JAR_EXECUTABLE}" -cf lightgbmlib.jar com
    )
473
  else()
474
475
476
477
478
479
480
    add_custom_command(
        TARGET _lightgbm_swig
        POST_BUILD
        COMMAND "${Java_JAVAC_EXECUTABLE}" -d . java/*.java
        COMMAND cp "${PROJECT_SOURCE_DIR}/*.so" com/microsoft/ml/lightgbm/linux/x86_64
        COMMAND "${Java_JAR_EXECUTABLE}" -cf lightgbmlib.jar com
    )
481
  endif()
482
endif()
Guolin Ke's avatar
Guolin Ke committed
483
484

if(USE_MPI)
485
  target_link_libraries(lightgbm_objs PUBLIC ${MPI_CXX_LIBRARIES})
486
endif()
Guolin Ke's avatar
Guolin Ke committed
487

fanliwen's avatar
fanliwen committed
488
if(USE_OPENMP)
489
490
491
492
493
494
495
496
497
498
  if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
    target_link_libraries(lightgbm_objs PUBLIC OpenMP::OpenMP_CXX)
    # c_api headers also includes OpenMP headers, thus compiling
    # lightgbm_capi_objs needs include directory for OpenMP.
    # Specifying OpenMP in target_link_libraries will get include directory
    # requirements for compilation.
    # This uses CMake's Transitive Usage Requirements. Refer to CMake doc:
    # https://cmake.org/cmake/help/v3.16/manual/cmake-buildsystem.7.html#transitive-usage-requirements
    target_link_libraries(lightgbm_capi_objs PUBLIC OpenMP::OpenMP_CXX)
  endif()
499
endif()
fanliwen's avatar
fanliwen committed
500

501
if(USE_GPU)
502
  target_link_libraries(lightgbm_objs PUBLIC ${OpenCL_LIBRARY} ${Boost_LIBRARIES})
503
endif()
504

505
if(__INTEGRATE_OPENCL)
506
  # targets OpenCL and Boost are added in IntegratedOpenCL.cmake
507
  add_dependencies(lightgbm_objs OpenCL Boost)
508
  # variables INTEGRATED_OPENCL_* are set in IntegratedOpenCL.cmake
509
510
511
  target_include_directories(lightgbm_objs PRIVATE ${INTEGRATED_OPENCL_INCLUDES})
  target_compile_definitions(lightgbm_objs PRIVATE ${INTEGRATED_OPENCL_DEFINITIONS})
  target_link_libraries(lightgbm_objs PUBLIC ${INTEGRATED_OPENCL_LIBRARIES})
512
513
endif()

514
if(USE_CUDA OR USE_CUDA_EXP)
515
516
517
518
519
  # Disable cmake warning about policy CMP0104. Refer to issue #3754 and PR #4268.
  # Custom target properties does not propagate, thus we need to specify for
  # each target that contains or depends on cuda source.
  set_target_properties(lightgbm_objs PROPERTIES CUDA_ARCHITECTURES OFF)
  set_target_properties(_lightgbm PROPERTIES CUDA_ARCHITECTURES OFF)
520
  set_target_properties(lightgbm PROPERTIES CUDA_ARCHITECTURES OFF)
521

522
523
  set_target_properties(lightgbm_objs PROPERTIES CUDA_SEPARABLE_COMPILATION ON)

524
525
526
  # Device linking is not supported for object libraries.
  # Thus we have to specify them on final targets.
  set_target_properties(lightgbm PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)
527
  set_target_properties(_lightgbm PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)
528
529
530
531
532
533

  # histograms are list of object libraries. Linking object library to other
  # object libraries only gets usage requirements, the linked objects won't be
  # used. Thus we have to call target_link_libraries on final targets here.
  target_link_libraries(lightgbm PRIVATE ${histograms})
  target_link_libraries(_lightgbm PRIVATE ${histograms})
534
endif()
535

536
if(USE_HDFS)
537
  target_link_libraries(lightgbm_objs PUBLIC ${HDFS_CXX_LIBRARIES})
538
endif()
539

540
541
if(WIN32)
    if(MINGW OR CYGWIN)
542
      target_link_libraries(lightgbm_objs PUBLIC Ws2_32 IPHLPAPI)
543
544
    endif()
endif()
Guolin Ke's avatar
Guolin Ke committed
545

546
if(__BUILD_FOR_R)
547
548
  # utils/log.h and capi uses R headers, thus both object libraries need to link
  # with R lib.
549
  if(MSVC)
550
    set(R_LIB ${LIBR_MSVC_CORE_LIBRARY})
551
  else()
552
    set(R_LIB ${LIBR_CORE_LIBRARY})
553
  endif()
554
555
  target_link_libraries(lightgbm_objs PUBLIC ${R_LIB})
  target_link_libraries(lightgbm_capi_objs PUBLIC ${R_LIB})
556
endif()
557

558
559
560
561
562
563
564
565
566
#-- Google C++ tests
if(BUILD_CPP_TEST)
  find_package(GTest CONFIG)
  if(NOT GTEST_FOUND)
    message(STATUS "Did not find Google Test in the system root. Fetching Google Test now...")
    include(FetchContent)
    FetchContent_Declare(
      googletest
      GIT_REPOSITORY https://github.com/google/googletest.git
567
      GIT_TAG        release-1.11.0
568
569
570
571
    )
    FetchContent_MakeAvailable(googletest)
    add_library(GTest::GTest ALIAS gtest)
  endif()
572
573
574
575
576
577
578
579
580
581
582
583
584
585
  file(GLOB CPP_TEST_SOURCES tests/cpp_tests/*.cpp)
  if(MSVC)
    set(
      CompilerFlags
        CMAKE_CXX_FLAGS
        CMAKE_CXX_FLAGS_DEBUG
        CMAKE_CXX_FLAGS_RELEASE
        CMAKE_C_FLAGS
        CMAKE_C_FLAGS_DEBUG
        CMAKE_C_FLAGS_RELEASE
    )
    foreach(CompilerFlag ${CompilerFlags})
      string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
    endforeach()
586
  endif()
587
588
  add_executable(testlightgbm ${CPP_TEST_SOURCES})
  target_link_libraries(testlightgbm PRIVATE lightgbm_objs GTest::GTest)
589
590
endif()

591
592
593
594
595
596
install(
  TARGETS lightgbm _lightgbm
  RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin
  LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
  ARCHIVE DESTINATION ${CMAKE_INSTALL_PREFIX}/lib
)
597

598
install(DIRECTORY ${LightGBM_HEADER_DIR}/LightGBM DESTINATION ${CMAKE_INSTALL_PREFIX}/include)