From 850d5c8f16376c446e298378ea08d7687ad15a3a Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Thu, 20 Jul 2023 14:43:42 +0300 Subject: [PATCH 1/9] lightgbm: migrate to Conan v2, add v4.0.0 --- recipes/lightgbm/all/CMakeLists.txt | 7 -- recipes/lightgbm/all/conandata.yml | 18 +-- recipes/lightgbm/all/conanfile.py | 110 ++++++++++++------ .../all/patches/0001-fix-includes.patch | 16 --- .../all/patches/0002-fix-openmp-clang.patch | 13 --- .../all/patches/0003-fix-openmp-clang.patch | 13 --- .../lightgbm/all/test_package/CMakeLists.txt | 9 +- .../lightgbm/all/test_package/conanfile.py | 23 ++-- .../all/test_v1_package/CMakeLists.txt | 8 ++ .../lightgbm/all/test_v1_package/conanfile.py | 17 +++ recipes/lightgbm/config.yml | 4 +- 11 files changed, 124 insertions(+), 114 deletions(-) delete mode 100644 recipes/lightgbm/all/CMakeLists.txt delete mode 100644 recipes/lightgbm/all/patches/0001-fix-includes.patch delete mode 100644 recipes/lightgbm/all/patches/0002-fix-openmp-clang.patch delete mode 100644 recipes/lightgbm/all/patches/0003-fix-openmp-clang.patch create mode 100644 recipes/lightgbm/all/test_v1_package/CMakeLists.txt create mode 100644 recipes/lightgbm/all/test_v1_package/conanfile.py diff --git a/recipes/lightgbm/all/CMakeLists.txt b/recipes/lightgbm/all/CMakeLists.txt deleted file mode 100644 index 61f3d3b039e2b..0000000000000 --- a/recipes/lightgbm/all/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -cmake_minimum_required(VERSION 3.1) -project(cmake_wrapper) - -include(conanbuildinfo.cmake) -conan_basic_setup(KEEP_RPATHS) - -add_subdirectory("source_subfolder") diff --git a/recipes/lightgbm/all/conandata.yml b/recipes/lightgbm/all/conandata.yml index 2fac2e54523aa..4d8509e6d9775 100644 --- a/recipes/lightgbm/all/conandata.yml +++ b/recipes/lightgbm/all/conandata.yml @@ -1,18 +1,10 @@ sources: - "3.3.2": - url: "https://github.com/microsoft/LightGBM/archive/refs/tags/v3.3.2.tar.gz" - sha256: "d7c0f842e94165578d5a0c046ca942838d1574149f98c84400ce511239d17b9f" + "4.0.0": + url: "https://github.com/microsoft/LightGBM/archive/refs/tags/v4.0.0.tar.gz" + sha256: "affb82a5a9d88949ffea634c0c33485ba966d42b1f5f838caa7c068447c99c1e" "3.3.5": url: "https://github.com/microsoft/LightGBM/archive/refs/tags/v3.3.5.tar.gz" sha256: "16fb9e299ced37be5ac69dd510e7323337e623019c9c578628c43b285f764be7" -patches: "3.3.2": - - patch_file: "patches/0001-fix-includes.patch" - base_path: "source_subfolder" - - patch_file: "patches/0002-fix-openmp-clang.patch" - base_path: "source_subfolder" - "3.3.5": - - patch_file: "patches/0001-fix-includes.patch" - base_path: "source_subfolder" - - patch_file: "patches/0003-fix-openmp-clang.patch" - base_path: "source_subfolder" + url: "https://github.com/microsoft/LightGBM/archive/refs/tags/v3.3.2.tar.gz" + sha256: "d7c0f842e94165578d5a0c046ca942838d1574149f98c84400ce511239d17b9f" diff --git a/recipes/lightgbm/all/conanfile.py b/recipes/lightgbm/all/conanfile.py index d00e21c352364..8cd1800f288b5 100644 --- a/recipes/lightgbm/all/conanfile.py +++ b/recipes/lightgbm/all/conanfile.py @@ -1,82 +1,116 @@ -from conans import CMake, ConanFile, tools +import os + +from conan import ConanFile +from conan.tools.apple import is_apple_os +from conan.tools.build import check_min_cppstd +from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout +from conan.tools.files import copy, get, replace_in_file, save from conan.tools.microsoft import is_msvc -import functools +from conan.tools.scm import Version -required_conan_version = ">=1.33.0" +required_conan_version = ">=1.53.0" class LightGBMConan(ConanFile): name = "lightgbm" - description = "A fast, distributed, high performance gradient boosting (GBT, GBDT, GBRT, GBM or MART) framework based on decision tree algorithms, used for ranking, classification and many other machine learning tasks." - topics = ("machine-learning", "boosting") + description = ( + "A fast, distributed, high performance gradient boosting " + "(GBT, GBDT, GBRT, GBM or MART) framework based on decision tree algorithms, " + "used for ranking, classification and many other machine learning tasks." + ) + license = "MIT" url = "https://github.com/conan-io/conan-center-index" homepage = "https://github.com/microsoft/LightGBM" - license = "MIT" + topics = ("machine-learning", "boosting") + package_type = "library" settings = "os", "arch", "compiler", "build_type" - exports_sources = ["CMakeLists.txt", "patches/**"] - generators = "cmake", "cmake_find_package" options = { "shared": [True, False], "fPIC": [True, False], - "with_openmp": [True, False] + "with_openmp": [True, False], } default_options = { "shared": False, "fPIC": True, - "with_openmp": True + "with_openmp": True, } - @property - def _source_subfolder(self): - return "source_subfolder" - def config_options(self): if self.settings.os == "Windows": del self.options.fPIC def configure(self): if self.options.shared: - del self.options.fPIC + self.options.rm_safe("fPIC") + + def layout(self): + cmake_layout(self, src_folder="src") def requirements(self): self.requires("eigen/3.4.0") - self.requires("fast_double_parser/0.6.0") - self.requires("fmt/9.0.0") - if self.options.with_openmp and self.settings.compiler in ("clang", "apple-clang"): - self.requires("llvm-openmp/11.1.0") + self.requires("fast_double_parser/0.7.0", transitive_headers=True) + self.requires("fmt/10.0.0", transitive_headers=True) + # FIXME: enable when llvm-openmp has been migrated to Conan v2 + # if self.options.with_openmp and self.settings.compiler in ("clang", "apple-clang"): + # self.requires("llvm-openmp/12.0.1") def validate(self): if self.settings.compiler.get_safe("cppstd"): - tools.check_min_cppstd(self, 11) + check_min_cppstd(self, 11) def source(self): - tools.get(**self.conan_data["sources"][self.version], - destination=self._source_subfolder, strip_root=True) + get(self, **self.conan_data["sources"][self.version], strip_root=True) + + def generate(self): + tc = CMakeToolchain(self) + tc.cache_variables["BUILD_STATIC_LIB"] = not self.options.shared + tc.cache_variables["USE_DEBUG"] = self.settings.build_type in ["Debug", "RelWithDebInfo"] + tc.cache_variables["USE_OPENMP"] = self.options.with_openmp + tc.cache_variables["BUILD_CLI"] = False + if is_apple_os(self): + tc.cache_variables["APPLE_OUTPUT_DYLIB"] = True + tc.generate() + tc = CMakeDeps(self) + tc.generate() def _patch_sources(self): - for patch in self.conan_data.get("patches", {}).get(self.version, []): - tools.patch(**patch) + cmakelists_path = os.path.join(self.source_folder, "CMakeLists.txt") + # Fix OpenMP detection for Clang + replace_in_file(self, cmakelists_path, "AppleClang", "Clang|AppleClang") + # Fix vendored dependency includes + common_h = os.path.join(self.source_folder, "include", "LightGBM", "utils", "common.h") + for lib in ["fmt", "fast_double_parser"]: + replace_in_file(self, common_h, f"../../../external_libs/{lib}/include/", "") + # Add dependencies + extra_cmake_content = ( + "find_package(fmt REQUIRED CONFIG)\n" + "find_package(Eigen3 REQUIRED CONFIG)\n" + "find_package(fast_double_parser REQUIRED CONFIG)\n" + ) + if Version(self.version).major >= 4: + targets = ["lightgbm_objs", "lightgbm_capi_objs"] + else: + targets = ["lightgbm", "_lightgbm"] + for target in targets: + extra_cmake_content += ( + f"target_link_libraries({target} PRIVATE " + "fmt::fmt Eigen3::Eigen fast_double_parser::fast_double_parser)\n" + ) + save(self, cmakelists_path, extra_cmake_content, append=True) - @functools.lru_cache(1) - def _configure_cmake(self): - cmake = CMake(self) - cmake.definitions["BUILD_STATIC_LIB"] = not self.options.shared - cmake.definitions["USE_DEBUG"] = self.settings.build_type == "Debug" - cmake.definitions["USE_OPENMP"] = self.options.with_openmp - if self.settings.os == "Macos": - cmake.definitions["APPLE_OUTPUT_DYLIB"] = True - cmake.configure() - return cmake def build(self): self._patch_sources() - cmake = self._configure_cmake() + cmake = CMake(self) + cmake.configure() cmake.build() def package(self): - self.copy("LICENSE", dst="licenses", src=self._source_subfolder) - cmake = self._configure_cmake() + copy(self, "LICENSE", + dst=os.path.join(self.package_folder, "licenses"), + src=self.source_folder) + cmake = CMake(self) cmake.install() def package_info(self): @@ -90,7 +124,7 @@ def package_info(self): self.cpp_info.libs = ["lib_lightgbm"] if is_msvc(self) else ["_lightgbm"] if self.settings.os == "Windows": self.cpp_info.system_libs.extend(["ws2_32", "iphlpapi"]) - elif self.settings.os == "Linux": + elif self.settings.os in ["Linux", "FreeBSD"]: self.cpp_info.system_libs.append("pthread") if not self.options.shared and self.options.with_openmp: if is_msvc(self): diff --git a/recipes/lightgbm/all/patches/0001-fix-includes.patch b/recipes/lightgbm/all/patches/0001-fix-includes.patch deleted file mode 100644 index 13fa0fe43a998..0000000000000 --- a/recipes/lightgbm/all/patches/0001-fix-includes.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/include/LightGBM/utils/common.h b/include/LightGBM/utils/common.h -index af981062..097f20d4 100644 ---- a/include/LightGBM/utils/common.h -+++ b/include/LightGBM/utils/common.h -@@ -33,9 +33,9 @@ - - #if (!((defined(sun) || defined(__sun)) && (defined(__SVR4) || defined(__svr4__)))) - #define FMT_HEADER_ONLY --#include "../../../external_libs/fmt/include/fmt/format.h" -+#include - #endif --#include "../../../external_libs/fast_double_parser/include/fast_double_parser.h" -+#include - - #ifdef _MSC_VER - #include diff --git a/recipes/lightgbm/all/patches/0002-fix-openmp-clang.patch b/recipes/lightgbm/all/patches/0002-fix-openmp-clang.patch deleted file mode 100644 index 092e8d05ac946..0000000000000 --- a/recipes/lightgbm/all/patches/0002-fix-openmp-clang.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 109a252d..e5d46bce 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -415,7 +415,7 @@ if(USE_MPI) - endif(USE_MPI) - - if(USE_OPENMP) -- if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") -+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") - TARGET_LINK_LIBRARIES(lightgbm OpenMP::OpenMP_CXX) - TARGET_LINK_LIBRARIES(_lightgbm OpenMP::OpenMP_CXX) - endif() diff --git a/recipes/lightgbm/all/patches/0003-fix-openmp-clang.patch b/recipes/lightgbm/all/patches/0003-fix-openmp-clang.patch deleted file mode 100644 index 0fbe29eced0c4..0000000000000 --- a/recipes/lightgbm/all/patches/0003-fix-openmp-clang.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/CMakeLists.txt b/CMakeLists.txt -index 95610d55..2b48507d 100644 ---- a/CMakeLists.txt -+++ b/CMakeLists.txt -@@ -444,7 +444,7 @@ if(USE_MPI) - endif(USE_MPI) - - if(USE_OPENMP) -- if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") -+ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") - TARGET_LINK_LIBRARIES(lightgbm OpenMP::OpenMP_CXX) - TARGET_LINK_LIBRARIES(_lightgbm OpenMP::OpenMP_CXX) - endif() diff --git a/recipes/lightgbm/all/test_package/CMakeLists.txt b/recipes/lightgbm/all/test_package/CMakeLists.txt index 12b8a397ff5d3..1fc3dbaef1eaa 100644 --- a/recipes/lightgbm/all/test_package/CMakeLists.txt +++ b/recipes/lightgbm/all/test_package/CMakeLists.txt @@ -1,10 +1,7 @@ -cmake_minimum_required(VERSION 3.1) -project(test_package) +cmake_minimum_required(VERSION 3.15) +project(test_package LANGUAGES CXX) -include("${CMAKE_BINARY_DIR}/conanbuildinfo.cmake") -conan_basic_setup(TARGETS) - -find_package(LightGBM CONFIG REQUIRED) +find_package(LightGBM REQUIRED CONFIG) add_executable(${PROJECT_NAME} test_package.cpp) target_link_libraries(${PROJECT_NAME} LightGBM::LightGBM) diff --git a/recipes/lightgbm/all/test_package/conanfile.py b/recipes/lightgbm/all/test_package/conanfile.py index 746d011e4501a..ef5d7042163ec 100644 --- a/recipes/lightgbm/all/test_package/conanfile.py +++ b/recipes/lightgbm/all/test_package/conanfile.py @@ -1,10 +1,19 @@ -from conans import ConanFile, CMake, tools +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake import os -class LightGBMTestConan(ConanFile): - settings = "os", "compiler", "build_type", "arch" - generators = "cmake", "cmake_find_package_multi" +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "CMakeToolchain", "VirtualRunEnv" + test_type = "explicit" + + def requirements(self): + self.requires(self.tested_reference_str) + + def layout(self): + cmake_layout(self) def build(self): cmake = CMake(self) @@ -12,6 +21,6 @@ def build(self): cmake.build() def test(self): - if not tools.cross_building(self): - bin_path = os.path.join("bin", "test_package") - self.run(bin_path, run_environment=True) + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindir, "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/lightgbm/all/test_v1_package/CMakeLists.txt b/recipes/lightgbm/all/test_v1_package/CMakeLists.txt new file mode 100644 index 0000000000000..91630d79f4abb --- /dev/null +++ b/recipes/lightgbm/all/test_v1_package/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package) + +include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) +conan_basic_setup(TARGETS) + +add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/../test_package/ + ${CMAKE_CURRENT_BINARY_DIR}/test_package/) diff --git a/recipes/lightgbm/all/test_v1_package/conanfile.py b/recipes/lightgbm/all/test_v1_package/conanfile.py new file mode 100644 index 0000000000000..746d011e4501a --- /dev/null +++ b/recipes/lightgbm/all/test_v1_package/conanfile.py @@ -0,0 +1,17 @@ +from conans import ConanFile, CMake, tools +import os + + +class LightGBMTestConan(ConanFile): + settings = "os", "compiler", "build_type", "arch" + generators = "cmake", "cmake_find_package_multi" + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if not tools.cross_building(self): + bin_path = os.path.join("bin", "test_package") + self.run(bin_path, run_environment=True) diff --git a/recipes/lightgbm/config.yml b/recipes/lightgbm/config.yml index 185a3ba9f96e0..a21c1caec5866 100644 --- a/recipes/lightgbm/config.yml +++ b/recipes/lightgbm/config.yml @@ -1,5 +1,7 @@ versions: - "3.3.2": + "4.0.0": folder: all "3.3.5": folder: all + "3.3.2": + folder: all From 3e3223188ca7e590af75157d25d5ccf349b4900e Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Thu, 21 Sep 2023 19:33:43 +0300 Subject: [PATCH 2/9] lightgbm: enable llvm-openmp --- recipes/lightgbm/all/conanfile.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/recipes/lightgbm/all/conanfile.py b/recipes/lightgbm/all/conanfile.py index 8cd1800f288b5..e3c9459726b99 100644 --- a/recipes/lightgbm/all/conanfile.py +++ b/recipes/lightgbm/all/conanfile.py @@ -50,10 +50,9 @@ def layout(self): def requirements(self): self.requires("eigen/3.4.0") self.requires("fast_double_parser/0.7.0", transitive_headers=True) - self.requires("fmt/10.0.0", transitive_headers=True) - # FIXME: enable when llvm-openmp has been migrated to Conan v2 - # if self.options.with_openmp and self.settings.compiler in ("clang", "apple-clang"): - # self.requires("llvm-openmp/12.0.1") + self.requires("fmt/10.1.1", transitive_headers=True) + if self.options.with_openmp and self.settings.compiler in ["clang", "apple-clang"]: + self.requires("llvm-openmp/12.0.1") def validate(self): if self.settings.compiler.get_safe("cppstd"): From deea03b0354247263bcc966216b29fbd64a8094b Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Thu, 21 Sep 2023 19:37:33 +0300 Subject: [PATCH 3/9] lightgbm: bump version --- recipes/lightgbm/all/conandata.yml | 6 +++--- recipes/lightgbm/config.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/recipes/lightgbm/all/conandata.yml b/recipes/lightgbm/all/conandata.yml index 4d8509e6d9775..880839ac61786 100644 --- a/recipes/lightgbm/all/conandata.yml +++ b/recipes/lightgbm/all/conandata.yml @@ -1,7 +1,7 @@ sources: - "4.0.0": - url: "https://github.com/microsoft/LightGBM/archive/refs/tags/v4.0.0.tar.gz" - sha256: "affb82a5a9d88949ffea634c0c33485ba966d42b1f5f838caa7c068447c99c1e" + "4.1.0": + url: "https://github.com/microsoft/LightGBM/archive/refs/tags/v4.1.0.tar.gz" + sha256: "eb896dc21c7afec95d10327777f6e77163b5bcd35f6ce5d152e6feefbe3328a5" "3.3.5": url: "https://github.com/microsoft/LightGBM/archive/refs/tags/v3.3.5.tar.gz" sha256: "16fb9e299ced37be5ac69dd510e7323337e623019c9c578628c43b285f764be7" diff --git a/recipes/lightgbm/config.yml b/recipes/lightgbm/config.yml index a21c1caec5866..eba2ef0bbf4fd 100644 --- a/recipes/lightgbm/config.yml +++ b/recipes/lightgbm/config.yml @@ -1,5 +1,5 @@ versions: - "4.0.0": + "4.1.0": folder: all "3.3.5": folder: all From 6134984379eb85fe639fcd4dcae57debd2be907d Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Thu, 21 Sep 2023 19:44:56 +0300 Subject: [PATCH 4/9] lightgbm: unvendor Eigen fully --- recipes/lightgbm/all/conanfile.py | 1 + 1 file changed, 1 insertion(+) diff --git a/recipes/lightgbm/all/conanfile.py b/recipes/lightgbm/all/conanfile.py index e3c9459726b99..83d168523242c 100644 --- a/recipes/lightgbm/all/conanfile.py +++ b/recipes/lightgbm/all/conanfile.py @@ -82,6 +82,7 @@ def _patch_sources(self): for lib in ["fmt", "fast_double_parser"]: replace_in_file(self, common_h, f"../../../external_libs/{lib}/include/", "") # Add dependencies + replace_in_file(self, cmakelists_path, "include_directories(${EIGEN_DIR})", "") extra_cmake_content = ( "find_package(fmt REQUIRED CONFIG)\n" "find_package(Eigen3 REQUIRED CONFIG)\n" From 228a65681df9c9b4b8d4f60539d365bccd1d34f3 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Fri, 17 Nov 2023 22:39:38 +0200 Subject: [PATCH 5/9] lightgbm: bump llvm-openmp, export OpenMP flags correctly --- recipes/lightgbm/all/conanfile.py | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/recipes/lightgbm/all/conanfile.py b/recipes/lightgbm/all/conanfile.py index 83d168523242c..9cf4e25a553b9 100644 --- a/recipes/lightgbm/all/conanfile.py +++ b/recipes/lightgbm/all/conanfile.py @@ -49,10 +49,10 @@ def layout(self): def requirements(self): self.requires("eigen/3.4.0") - self.requires("fast_double_parser/0.7.0", transitive_headers=True) - self.requires("fmt/10.1.1", transitive_headers=True) + self.requires("fast_double_parser/0.7.0", transitive_headers=True, transitive_libs=True) + self.requires("fmt/10.1.1", transitive_headers=True, transitive_libs=True) if self.options.with_openmp and self.settings.compiler in ["clang", "apple-clang"]: - self.requires("llvm-openmp/12.0.1") + self.requires("llvm-openmp/17.0.4", transitive_headers=True, transitive_libs=True) def validate(self): if self.settings.compiler.get_safe("cppstd"): @@ -126,14 +126,16 @@ def package_info(self): self.cpp_info.system_libs.extend(["ws2_32", "iphlpapi"]) elif self.settings.os in ["Linux", "FreeBSD"]: self.cpp_info.system_libs.append("pthread") - if not self.options.shared and self.options.with_openmp: + + # OpenMP preprocessor directives are used in a number of public headers, such as: + # https://github.com/microsoft/LightGBM/blob/master/include/LightGBM/tree.h#L188 + if self.options.with_openmp: + openmp_flags = [] if is_msvc(self): openmp_flags = ["-openmp"] elif self.settings.compiler == "gcc": openmp_flags = ["-fopenmp"] - elif self.settings.compiler in ("clang", "apple-clang"): + elif self.settings.compiler in ["clang", "apple-clang"]: openmp_flags = ["-Xpreprocessor", "-fopenmp"] - else: - openmp_flags = [] - self.cpp_info.exelinkflags.extend(openmp_flags) - self.cpp_info.sharedlinkflags.extend(openmp_flags) + self.cpp_info.cflags.extend(openmp_flags) + self.cpp_info.cxxflags.extend(openmp_flags) From 1e3e7290c8247d6eb1307c38e0cfb7ad28708dee Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Fri, 17 Nov 2023 23:06:27 +0200 Subject: [PATCH 6/9] lightgbm: restore patches for the Clang OpenMP support fix --- recipes/lightgbm/all/conandata.yml | 13 +++++++++++++ recipes/lightgbm/all/conanfile.py | 8 +++++--- .../all/patches/3.3.2-0001-fix-openmp-clang.patch | 13 +++++++++++++ .../all/patches/3.3.5-0001-fix-openmp-clang.patch | 13 +++++++++++++ .../all/patches/4.1.0-0001-fix-openmp-clang.patch | 11 +++++++++++ 5 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 recipes/lightgbm/all/patches/3.3.2-0001-fix-openmp-clang.patch create mode 100644 recipes/lightgbm/all/patches/3.3.5-0001-fix-openmp-clang.patch create mode 100644 recipes/lightgbm/all/patches/4.1.0-0001-fix-openmp-clang.patch diff --git a/recipes/lightgbm/all/conandata.yml b/recipes/lightgbm/all/conandata.yml index 880839ac61786..5c29f9403b5ce 100644 --- a/recipes/lightgbm/all/conandata.yml +++ b/recipes/lightgbm/all/conandata.yml @@ -8,3 +8,16 @@ sources: "3.3.2": url: "https://github.com/microsoft/LightGBM/archive/refs/tags/v3.3.2.tar.gz" sha256: "d7c0f842e94165578d5a0c046ca942838d1574149f98c84400ce511239d17b9f" +patches: + "4.1.0": + - patch_file: "patches/4.1.0-0001-fix-openmp-clang.patch" + patch_type: "portability" + patch_description: "Fix OpenMP support for Clang" + "3.3.5": + - patch_file: "patches/3.3.5-0001-fix-openmp-clang.patch" + patch_type: "portability" + patch_description: "Fix OpenMP support for Clang" + "3.3.2": + - patch_file: "patches/3.3.2-0001-fix-openmp-clang.patch" + patch_type: "portability" + patch_description: "Fix OpenMP support for Clang" diff --git a/recipes/lightgbm/all/conanfile.py b/recipes/lightgbm/all/conanfile.py index 9cf4e25a553b9..4074480e30736 100644 --- a/recipes/lightgbm/all/conanfile.py +++ b/recipes/lightgbm/all/conanfile.py @@ -4,7 +4,7 @@ from conan.tools.apple import is_apple_os from conan.tools.build import check_min_cppstd from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout -from conan.tools.files import copy, get, replace_in_file, save +from conan.tools.files import copy, get, replace_in_file, save, export_conandata_patches, apply_conandata_patches from conan.tools.microsoft import is_msvc from conan.tools.scm import Version @@ -36,6 +36,9 @@ class LightGBMConan(ConanFile): "with_openmp": True, } + def export_sources(self): + export_conandata_patches(self) + def config_options(self): if self.settings.os == "Windows": del self.options.fPIC @@ -74,9 +77,8 @@ def generate(self): tc.generate() def _patch_sources(self): + apply_conandata_patches(self) cmakelists_path = os.path.join(self.source_folder, "CMakeLists.txt") - # Fix OpenMP detection for Clang - replace_in_file(self, cmakelists_path, "AppleClang", "Clang|AppleClang") # Fix vendored dependency includes common_h = os.path.join(self.source_folder, "include", "LightGBM", "utils", "common.h") for lib in ["fmt", "fast_double_parser"]: diff --git a/recipes/lightgbm/all/patches/3.3.2-0001-fix-openmp-clang.patch b/recipes/lightgbm/all/patches/3.3.2-0001-fix-openmp-clang.patch new file mode 100644 index 0000000000000..092e8d05ac946 --- /dev/null +++ b/recipes/lightgbm/all/patches/3.3.2-0001-fix-openmp-clang.patch @@ -0,0 +1,13 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 109a252d..e5d46bce 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -415,7 +415,7 @@ if(USE_MPI) + endif(USE_MPI) + + if(USE_OPENMP) +- if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") ++ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") + TARGET_LINK_LIBRARIES(lightgbm OpenMP::OpenMP_CXX) + TARGET_LINK_LIBRARIES(_lightgbm OpenMP::OpenMP_CXX) + endif() diff --git a/recipes/lightgbm/all/patches/3.3.5-0001-fix-openmp-clang.patch b/recipes/lightgbm/all/patches/3.3.5-0001-fix-openmp-clang.patch new file mode 100644 index 0000000000000..0fbe29eced0c4 --- /dev/null +++ b/recipes/lightgbm/all/patches/3.3.5-0001-fix-openmp-clang.patch @@ -0,0 +1,13 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index 95610d55..2b48507d 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -444,7 +444,7 @@ if(USE_MPI) + endif(USE_MPI) + + if(USE_OPENMP) +- if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") ++ if(CMAKE_CXX_COMPILER_ID MATCHES "Clang|AppleClang") + TARGET_LINK_LIBRARIES(lightgbm OpenMP::OpenMP_CXX) + TARGET_LINK_LIBRARIES(_lightgbm OpenMP::OpenMP_CXX) + endif() diff --git a/recipes/lightgbm/all/patches/4.1.0-0001-fix-openmp-clang.patch b/recipes/lightgbm/all/patches/4.1.0-0001-fix-openmp-clang.patch new file mode 100644 index 0000000000000..4de5b0a2d1c8e --- /dev/null +++ b/recipes/lightgbm/all/patches/4.1.0-0001-fix-openmp-clang.patch @@ -0,0 +1,11 @@ +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -526,7 +526,7 @@ + endif() + + if(USE_OPENMP) +- if(CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") ++ if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang|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. From 96487d119fe724391834a894ddb2f5d86a505769 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Fri, 17 Nov 2023 23:28:41 +0200 Subject: [PATCH 7/9] lightgbm: simplify patching --- recipes/lightgbm/all/CMakeLists.txt | 20 ++++++++++++++++++++ recipes/lightgbm/all/conanfile.py | 29 +++++++---------------------- 2 files changed, 27 insertions(+), 22 deletions(-) create mode 100644 recipes/lightgbm/all/CMakeLists.txt diff --git a/recipes/lightgbm/all/CMakeLists.txt b/recipes/lightgbm/all/CMakeLists.txt new file mode 100644 index 0000000000000..d250cd86d5991 --- /dev/null +++ b/recipes/lightgbm/all/CMakeLists.txt @@ -0,0 +1,20 @@ +cmake_minimum_required(VERSION 3.15) +project(cmake_wrapper LANGUAGES CXX) + +find_package(Eigen3 REQUIRED CONFIG) +find_package(fast_double_parser REQUIRED CONFIG) +find_package(fmt REQUIRED CONFIG) + +add_subdirectory(src) + +if(_MAJOR_VERSION GREATER_EQUAL 4) + set(TARGETS lightgbm_objs lightgbm_capi_objs) + set(VISIBILITY PRIVATE) +else() + set(TARGETS lightgbm _lightgbm) + set(VISIBILITY "") +endif() + +foreach(target ${TARGETS}) + target_link_libraries(${target} ${VISIBILITY} Eigen3::Eigen fast_double_parser::fast_double_parser fmt::fmt) +endforeach() diff --git a/recipes/lightgbm/all/conanfile.py b/recipes/lightgbm/all/conanfile.py index 4074480e30736..31d9022e3d887 100644 --- a/recipes/lightgbm/all/conanfile.py +++ b/recipes/lightgbm/all/conanfile.py @@ -4,7 +4,7 @@ from conan.tools.apple import is_apple_os from conan.tools.build import check_min_cppstd from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout -from conan.tools.files import copy, get, replace_in_file, save, export_conandata_patches, apply_conandata_patches +from conan.tools.files import copy, get, replace_in_file, export_conandata_patches, apply_conandata_patches from conan.tools.microsoft import is_msvc from conan.tools.scm import Version @@ -37,6 +37,7 @@ class LightGBMConan(ConanFile): } def export_sources(self): + copy(self, "CMakeLists.txt", self.recipe_folder, self.export_sources_folder) export_conandata_patches(self) def config_options(self): @@ -72,40 +73,25 @@ def generate(self): tc.cache_variables["BUILD_CLI"] = False if is_apple_os(self): tc.cache_variables["APPLE_OUTPUT_DYLIB"] = True + tc.variables["_MAJOR_VERSION"] = Version(self.version).major tc.generate() tc = CMakeDeps(self) tc.generate() def _patch_sources(self): apply_conandata_patches(self) - cmakelists_path = os.path.join(self.source_folder, "CMakeLists.txt") # Fix vendored dependency includes common_h = os.path.join(self.source_folder, "include", "LightGBM", "utils", "common.h") for lib in ["fmt", "fast_double_parser"]: replace_in_file(self, common_h, f"../../../external_libs/{lib}/include/", "") - # Add dependencies - replace_in_file(self, cmakelists_path, "include_directories(${EIGEN_DIR})", "") - extra_cmake_content = ( - "find_package(fmt REQUIRED CONFIG)\n" - "find_package(Eigen3 REQUIRED CONFIG)\n" - "find_package(fast_double_parser REQUIRED CONFIG)\n" - ) - if Version(self.version).major >= 4: - targets = ["lightgbm_objs", "lightgbm_capi_objs"] - else: - targets = ["lightgbm", "_lightgbm"] - for target in targets: - extra_cmake_content += ( - f"target_link_libraries({target} PRIVATE " - "fmt::fmt Eigen3::Eigen fast_double_parser::fast_double_parser)\n" - ) - save(self, cmakelists_path, extra_cmake_content, append=True) - + # Unvendor Eigen3 + replace_in_file(self, os.path.join(self.source_folder, "CMakeLists.txt"), + "include_directories(${EIGEN_DIR})", "") def build(self): self._patch_sources() cmake = CMake(self) - cmake.configure() + cmake.configure(build_script_folder=self.source_path.parent) cmake.build() def package(self): @@ -139,5 +125,4 @@ def package_info(self): openmp_flags = ["-fopenmp"] elif self.settings.compiler in ["clang", "apple-clang"]: openmp_flags = ["-Xpreprocessor", "-fopenmp"] - self.cpp_info.cflags.extend(openmp_flags) self.cpp_info.cxxflags.extend(openmp_flags) From 28d04ee1833d32a5c274fa9819f0eacc29ac2d20 Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Sat, 18 Nov 2023 08:56:31 +0200 Subject: [PATCH 8/9] lightgbm: add -fopenmp to linker flags --- recipes/lightgbm/all/conanfile.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/recipes/lightgbm/all/conanfile.py b/recipes/lightgbm/all/conanfile.py index 31d9022e3d887..751351cc0cf86 100644 --- a/recipes/lightgbm/all/conanfile.py +++ b/recipes/lightgbm/all/conanfile.py @@ -126,3 +126,5 @@ def package_info(self): elif self.settings.compiler in ["clang", "apple-clang"]: openmp_flags = ["-Xpreprocessor", "-fopenmp"] self.cpp_info.cxxflags.extend(openmp_flags) + self.cpp_info.exelinkflags.extend(openmp_flags) + self.cpp_info.sharedlinkflags.extend(openmp_flags) From 934ec52bcd58b9833bae0917bcc797f26579f54d Mon Sep 17 00:00:00 2001 From: Martin Valgur Date: Sat, 18 Nov 2023 18:27:27 +0200 Subject: [PATCH 9/9] lightgbm: disable openmp on apple-clang for Conan v1 --- recipes/lightgbm/all/conanfile.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/recipes/lightgbm/all/conanfile.py b/recipes/lightgbm/all/conanfile.py index 751351cc0cf86..cae89a9218102 100644 --- a/recipes/lightgbm/all/conanfile.py +++ b/recipes/lightgbm/all/conanfile.py @@ -1,6 +1,6 @@ import os -from conan import ConanFile +from conan import ConanFile, conan_version from conan.tools.apple import is_apple_os from conan.tools.build import check_min_cppstd from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout @@ -43,6 +43,9 @@ def export_sources(self): def config_options(self): if self.settings.os == "Windows": del self.options.fPIC + if conan_version.major == 1 and self.settings.compiler == "apple-clang": + # https://github.com/conan-io/conan-center-index/pull/18759#issuecomment-1817470331 + del self.options.with_openmp def configure(self): if self.options.shared: @@ -55,7 +58,7 @@ def requirements(self): self.requires("eigen/3.4.0") self.requires("fast_double_parser/0.7.0", transitive_headers=True, transitive_libs=True) self.requires("fmt/10.1.1", transitive_headers=True, transitive_libs=True) - if self.options.with_openmp and self.settings.compiler in ["clang", "apple-clang"]: + if self.options.get_safe("with_openmp") and self.settings.compiler in ["clang", "apple-clang"]: self.requires("llvm-openmp/17.0.4", transitive_headers=True, transitive_libs=True) def validate(self): @@ -69,7 +72,7 @@ def generate(self): tc = CMakeToolchain(self) tc.cache_variables["BUILD_STATIC_LIB"] = not self.options.shared tc.cache_variables["USE_DEBUG"] = self.settings.build_type in ["Debug", "RelWithDebInfo"] - tc.cache_variables["USE_OPENMP"] = self.options.with_openmp + tc.cache_variables["USE_OPENMP"] = self.options.get_safe("with_openmp", False) tc.cache_variables["BUILD_CLI"] = False if is_apple_os(self): tc.cache_variables["APPLE_OUTPUT_DYLIB"] = True @@ -117,7 +120,7 @@ def package_info(self): # OpenMP preprocessor directives are used in a number of public headers, such as: # https://github.com/microsoft/LightGBM/blob/master/include/LightGBM/tree.h#L188 - if self.options.with_openmp: + if self.options.get_safe("with_openmp"): openmp_flags = [] if is_msvc(self): openmp_flags = ["-openmp"]