Skip to content

Commit

Permalink
cmake: use object library to avoid duplicate compilation. (#4489)
Browse files Browse the repository at this point in the history
* cmake: use object library to avoid duplicate compilation.

* debug: verbose make log for building r package.

* Include /usr/local/include for AppleClang.

* Revert "debug: verbose make log for building r package."

* update cmake comment and fix indentation

* debug cmake USE_DEBUG.

* Revert "debug cmake USt E_DEBUG."

* Add -fPIC for building shared library.

* Always set -fPIC for non MSVC compiler.

* debug: print exception in setup.py

* debug: print cmake output for vs build.

* debug: set opencl related target_xxx on lightgbm_objs.

* Define compile definitions, link libraries on lightgbm_objs.

* Add PUBLIC to target_link_libraries to expose library dependency.

* Use target_link_libraries on object library.

This should propagate usage requirements.

* Fix CUDA linking.

Linking object library (lightgbm_objs) to object library (histograms)
does not linked objects.

* Use PUBLIC link for lightgbm lib.

* Set cuda related properties on final targets.

* Remove debugging changes.

Revert "debug: print exception in setup.py"
Revert "debug: print cmake output for vs build."
etc.

* Remove -D_lightgbm_EXPORTS.

* Revert to add -fPIC only for NOT USE_DEBUG.

* Enable PIC for shared lib.

* Fix enable PIC.

* Use -fPIC for shared lib.

* testlightgbm depends only on object files.

* tweak build for R.

* Try to remove OpenMP related include dir settings.

* link with openmp for capi object library.

* Use PUBLIC for _lightgbm target_link_libraries.

* Try removing exports definition.

* fix typo

Co-authored-by: Nikita Titov <nekit94-08@mail.ru>

* fix typo

Co-authored-by: Nikita Titov <nekit94-08@mail.ru>

* Add some comments for cmake code.

* Try to fix cmake warnings CUDA.

* revert accidentally commited R-package path change.

* Try to fix cmake CUDA warnings, set for _lightgbm target.

* Try to fix cmake CUDA warnings, set for lightgbm target.

* empty commit to trigger ci

Co-authored-by: Nikita Titov <nekit94-08@mail.ru>
  • Loading branch information
cyfdecyf and StrikerRUS committed Nov 10, 2021
1 parent 7152c49 commit 15a6369
Showing 1 changed file with 58 additions and 42 deletions.
100 changes: 58 additions & 42 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -317,8 +317,11 @@ if(MSVC)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /O2 /Ob2 /Oi /Ot /Oy")
endif()
else()
if(NOT BUILD_STATIC_LIB)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
endif()
if(NOT USE_DEBUG)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC -funroll-loops")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -funroll-loops")
endif()
endif(MSVC)

Expand Down Expand Up @@ -353,20 +356,28 @@ if(USE_CUDA)
endif(USE_CUDA)
)

add_executable(lightgbm src/main.cpp src/application/application.cpp ${SOURCES})
list(APPEND SOURCES "src/c_api.cpp")
add_library(lightgbm_objs OBJECT ${SOURCES})

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

set(API_SOURCES "src/c_api.cpp")
# Only build the R part of the library if building for
# use with the R package
if(__BUILD_FOR_R)
list(APPEND SOURCES "src/lightgbm_R.cpp")
list(APPEND API_SOURCES "src/lightgbm_R.cpp")
endif(__BUILD_FOR_R)

add_library(lightgbm_capi_objs OBJECT ${API_SOURCES})

if(BUILD_STATIC_LIB)
add_library(_lightgbm STATIC ${SOURCES})
add_library(_lightgbm STATIC)
else()
add_library(_lightgbm SHARED ${SOURCES})
add_library(_lightgbm SHARED)
endif(BUILD_STATIC_LIB)
# LightGBM headers include openmp, cuda, R etc. headers,
# thus PUBLIC is required for building _lightgbm_swig target.
target_link_libraries(_lightgbm PUBLIC lightgbm_capi_objs lightgbm_objs)

if(MSVC)
set_target_properties(_lightgbm PROPERTIES OUTPUT_NAME "lib_lightgbm")
Expand Down Expand Up @@ -410,70 +421,75 @@ if(USE_SWIG)
endif(USE_SWIG)

if(USE_MPI)
TARGET_LINK_LIBRARIES(lightgbm ${MPI_CXX_LIBRARIES})
TARGET_LINK_LIBRARIES(_lightgbm ${MPI_CXX_LIBRARIES})
target_link_libraries(lightgbm_objs PUBLIC ${MPI_CXX_LIBRARIES})
endif(USE_MPI)

if(USE_OPENMP)
if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
TARGET_LINK_LIBRARIES(lightgbm OpenMP::OpenMP_CXX)
TARGET_LINK_LIBRARIES(_lightgbm OpenMP::OpenMP_CXX)
endif()
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()
endif(USE_OPENMP)

if(USE_GPU)
TARGET_LINK_LIBRARIES(lightgbm ${OpenCL_LIBRARY} ${Boost_LIBRARIES})
TARGET_LINK_LIBRARIES(_lightgbm ${OpenCL_LIBRARY} ${Boost_LIBRARIES})
target_link_libraries(lightgbm_objs PUBLIC ${OpenCL_LIBRARY} ${Boost_LIBRARIES})
endif(USE_GPU)

if(__INTEGRATE_OPENCL)
# targets OpenCL and Boost are added in IntegratedOpenCL.cmake
add_dependencies(lightgbm OpenCL Boost)
add_dependencies(_lightgbm OpenCL Boost)
add_dependencies(lightgbm_objs OpenCL Boost)
# variables INTEGRATED_OPENCL_* are set in IntegratedOpenCL.cmake
target_include_directories(lightgbm PRIVATE ${INTEGRATED_OPENCL_INCLUDES})
target_include_directories(_lightgbm PRIVATE ${INTEGRATED_OPENCL_INCLUDES})
target_compile_definitions(lightgbm PRIVATE ${INTEGRATED_OPENCL_DEFINITIONS})
target_compile_definitions(_lightgbm PRIVATE ${INTEGRATED_OPENCL_DEFINITIONS})
target_link_libraries(lightgbm PRIVATE ${INTEGRATED_OPENCL_LIBRARIES})
target_link_libraries(_lightgbm PRIVATE ${INTEGRATED_OPENCL_LIBRARIES})
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})
endif()

if(USE_CUDA)
set_target_properties(lightgbm PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)
# 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)
set_target_properties(lightgbm PROPERTIES CUDA_ARCHITECTURES OFF)
TARGET_LINK_LIBRARIES(
lightgbm
${histograms}
)

# 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)
set_target_properties(_lightgbm PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON)
set_target_properties(_lightgbm PROPERTIES CUDA_ARCHITECTURES OFF)
TARGET_LINK_LIBRARIES(
_lightgbm
${histograms}
)

# 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})
endif(USE_CUDA)

if(USE_HDFS)
TARGET_LINK_LIBRARIES(lightgbm ${HDFS_CXX_LIBRARIES})
TARGET_LINK_LIBRARIES(_lightgbm ${HDFS_CXX_LIBRARIES})
target_link_libraries(lightgbm_objs PUBLIC ${HDFS_CXX_LIBRARIES})
endif(USE_HDFS)

if(WIN32)
if(MINGW OR CYGWIN)
TARGET_LINK_LIBRARIES(lightgbm Ws2_32)
TARGET_LINK_LIBRARIES(_lightgbm Ws2_32)
TARGET_LINK_LIBRARIES(lightgbm IPHLPAPI)
TARGET_LINK_LIBRARIES(_lightgbm IPHLPAPI)
target_link_libraries(lightgbm_objs PUBLIC Ws2_32 IPHLPAPI)
endif(MINGW OR CYGWIN)
endif(WIN32)

if(__BUILD_FOR_R)
# utils/log.h and capi uses R headers, thus both object libraries need to link
# with R lib.
if(MSVC)
TARGET_LINK_LIBRARIES(_lightgbm ${LIBR_MSVC_CORE_LIBRARY})
set(R_LIB ${LIBR_MSVC_CORE_LIBRARY})
else()
TARGET_LINK_LIBRARIES(_lightgbm ${LIBR_CORE_LIBRARY})
set(R_LIB ${LIBR_CORE_LIBRARY})
endif(MSVC)
target_link_libraries(lightgbm_objs PUBLIC ${R_LIB})
target_link_libraries(lightgbm_capi_objs PUBLIC ${R_LIB})
endif(__BUILD_FOR_R)

#-- Google C++ tests
Expand Down Expand Up @@ -505,8 +521,8 @@ if(BUILD_CPP_TEST)
string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}")
endforeach()
endif(MSVC)
add_executable(testlightgbm ${CPP_TEST_SOURCES} ${SOURCES})
target_link_libraries(testlightgbm PRIVATE GTest::GTest)
add_executable(testlightgbm ${CPP_TEST_SOURCES})
target_link_libraries(testlightgbm PRIVATE lightgbm_objs GTest::GTest)
endif()

install(TARGETS lightgbm _lightgbm
Expand Down

0 comments on commit 15a6369

Please sign in to comment.