|
| 1 | +from conan import ConanFile |
| 2 | +from conan.errors import ConanInvalidConfiguration |
| 3 | +from conan.tools.microsoft import check_min_vs, is_msvc |
| 4 | +from conan.tools.files import apply_conandata_patches, export_conandata_patches, get, copy, rmdir |
| 5 | +from conan.tools.build import check_min_cppstd |
| 6 | +from conan.tools.scm import Version |
| 7 | +from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout |
| 8 | +from conan.tools.system import package_manager |
| 9 | +import os |
| 10 | + |
| 11 | + |
| 12 | +required_conan_version = ">=1.53.0" |
| 13 | + |
| 14 | + |
| 15 | +class PclConan(ConanFile): |
| 16 | + name = "pcl" |
| 17 | + description = "Point Cloud Library" |
| 18 | + license = "BSD-3-Clause" |
| 19 | + url = "https://github.com/conan-io/conan-center-index" |
| 20 | + homepage = "https://github.com/PointCloudLibrary/pcl" |
| 21 | + topics = ("computer vision", "point cloud", "pointcloud", "3d", "pcd", "ply", "stl", "ifs", "vtk") |
| 22 | + package_type = "library" |
| 23 | + settings = "os", "arch", "compiler", "build_type" |
| 24 | + options = { |
| 25 | + "shared": [True, False], |
| 26 | + "fPIC": [True, False], |
| 27 | + "with_openmp": [True, False], |
| 28 | + "with_libusb": [True, False], |
| 29 | + "with_png": [True, False], |
| 30 | + "with_qhull": [True, False], |
| 31 | + "with_vtk": [True, False], |
| 32 | + "with_cuda": [True, False], |
| 33 | + "with_pcap": [True, False], |
| 34 | + "with_opengl": [True, False], |
| 35 | + "with_tools": [True, False], |
| 36 | + "with_apps": [True, False], |
| 37 | + } |
| 38 | + default_options = { |
| 39 | + "shared": False, |
| 40 | + "fPIC": True, |
| 41 | + "with_openmp": False, |
| 42 | + "with_libusb": False, |
| 43 | + "with_png": True, |
| 44 | + "with_qhull": True, |
| 45 | + "with_vtk": False, |
| 46 | + "with_cuda": False, |
| 47 | + "with_pcap": False, |
| 48 | + "with_opengl": False, |
| 49 | + "with_tools": False, |
| 50 | + "with_apps": False, |
| 51 | + } |
| 52 | + |
| 53 | + short_paths = True |
| 54 | + |
| 55 | + @property |
| 56 | + def _min_cppstd(self): |
| 57 | + return 17 |
| 58 | + |
| 59 | + # in case the project requires C++14/17/20/... the minimum compiler version should be listed |
| 60 | + @property |
| 61 | + def _compilers_minimum_version(self): |
| 62 | + return { |
| 63 | + "gcc": "7", |
| 64 | + "clang": "7", |
| 65 | + "apple-clang": "10", |
| 66 | + } |
| 67 | + |
| 68 | + def export_sources(self): |
| 69 | + export_conandata_patches(self) |
| 70 | + |
| 71 | + def config_options(self): |
| 72 | + if self.settings.os == "Windows": |
| 73 | + del self.options.fPIC |
| 74 | + |
| 75 | + def configure(self): |
| 76 | + if self.options.shared: |
| 77 | + self.options.rm_safe("fPIC") |
| 78 | + |
| 79 | + def layout(self): |
| 80 | + cmake_layout(self, src_folder="src") |
| 81 | + |
| 82 | + def system_requirements(self): |
| 83 | + if self.options.with_vtk: |
| 84 | + package_manager.Apt(self).install(["libvtk-dev"]) |
| 85 | + package_manager.Dnf(self).install(["vtk-devel"]) |
| 86 | + if self.settings.os == "Windows": |
| 87 | + self.output.warn("On Windows VTK must be installed manually.") |
| 88 | + |
| 89 | + def requirements(self): |
| 90 | + self.requires("zlib/1.2.13") |
| 91 | + # Transitive headers on boost because pcl/point_struct_traits.h:40:10: references boost/mpl/assert.hpp |
| 92 | + self.requires("boost/1.82.0", transitive_headers=True) |
| 93 | + self.requires("eigen/3.4.0", transitive_headers=True) |
| 94 | + self.requires("flann/1.9.2") |
| 95 | + if self.options.with_png: |
| 96 | + self.requires("libpng/1.6.40") |
| 97 | + if self.options.with_qhull: |
| 98 | + self.requires("qhull/8.0.1") |
| 99 | + if self.options.with_apps: |
| 100 | + self.requires("qt/6.5.1") |
| 101 | + if self.options.with_libusb: |
| 102 | + self.requires("libusb/1.0.26") |
| 103 | + if self.options.with_pcap: |
| 104 | + self.requires("libpcap/1.10.4") |
| 105 | + if self.options.with_opengl: |
| 106 | + self.requires("opengl/system") |
| 107 | + |
| 108 | + def validate(self): |
| 109 | + # validate the minimum cpp standard supported. For C++ projects only |
| 110 | + if self.settings.compiler.cppstd: |
| 111 | + check_min_cppstd(self, self._min_cppstd) |
| 112 | + check_min_vs(self, 191) |
| 113 | + if not is_msvc(self): |
| 114 | + minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False) |
| 115 | + if minimum_version and Version(self.settings.compiler.version) < minimum_version: |
| 116 | + raise ConanInvalidConfiguration( |
| 117 | + f"{self.ref} requires C++{self._min_cppstd}, which your compiler does not support." |
| 118 | + ) |
| 119 | + |
| 120 | + def source(self): |
| 121 | + get(self, **self.conan_data["sources"][self.version], strip_root=True) |
| 122 | + |
| 123 | + def generate(self): |
| 124 | + tc = CMakeToolchain(self) |
| 125 | + tc.variables["PCL_SHARED_LIBS"] = self.options.shared |
| 126 | + tc.variables["WITH_OPENMP"] = self.options.with_openmp |
| 127 | + tc.variables["WITH_LIBUSB"] = self.options.with_libusb |
| 128 | + tc.variables["WITH_PNG"] = self.options.with_png |
| 129 | + tc.variables["WITH_QHULL"] = self.options.with_qhull |
| 130 | + tc.variables["WITH_VTK"] = self.options.with_vtk |
| 131 | + tc.variables["WITH_CUDA"] = self.options.with_cuda |
| 132 | + tc.variables["WITH_PCAP"] = self.options.with_pcap |
| 133 | + tc.variables["WITH_OPENGL"] = self.options.with_opengl |
| 134 | + tc.variables["BUILD_tools"] = self.options.with_tools |
| 135 | + tc.variables["BUILD_apps"] = self.options.with_apps |
| 136 | + tc.variables["BUILD_examples"] = True |
| 137 | + tc.cache_variables["WITH_QT"] = self.options.with_apps |
| 138 | + tc.generate() |
| 139 | + |
| 140 | + tc = CMakeDeps(self) |
| 141 | + tc.generate() |
| 142 | + |
| 143 | + def _patch_sources(self): |
| 144 | + apply_conandata_patches(self) |
| 145 | + |
| 146 | + def build(self): |
| 147 | + self._patch_sources() |
| 148 | + cmake = CMake(self) |
| 149 | + cmake.configure(variables={"PCL_ONLY_CORE_POINT_TYPES": "ON"}) |
| 150 | + cmake.build() |
| 151 | + |
| 152 | + def package(self): |
| 153 | + copy(self, pattern="LICENSE.txt", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder) |
| 154 | + cmake = CMake(self) |
| 155 | + cmake.install() |
| 156 | + |
| 157 | + rmdir(self, os.path.join(self.package_folder, "cmake")) |
| 158 | + rmdir(self, os.path.join(self.package_folder, "share")) |
| 159 | + |
| 160 | + @property |
| 161 | + def _pcl_lib_components(self): |
| 162 | + def usb(): |
| 163 | + return ["libusb::libusb"] if self.options.with_libusb else [] |
| 164 | + def png(): |
| 165 | + return ["libpng::libpng"] if self.options.with_png else [] |
| 166 | + def qhull(): |
| 167 | + return ["qhull::qhull"] if self.options.with_qhull else [] |
| 168 | + |
| 169 | + return { |
| 170 | + "common": {"requires": ["eigen::eigen3", "boost::boost"]}, |
| 171 | + "kdtree": {"requires": ["common", "flann::flann"]}, |
| 172 | + "octree": {"requires": ["common"]}, |
| 173 | + "search": {"requires": ["common", "kdtree", "octree", "flann::flann"]}, |
| 174 | + "sample_consensus": {"requires": ["common", "search"]}, |
| 175 | + "filters": {"requires": ["common", "sample_consensus", "search", "kdtree", "octree"]}, |
| 176 | + "2d": {"requires": ["common", "filters"], "header_only": True}, |
| 177 | + "geometry": {"requires": ["common"], "header_only": True}, |
| 178 | + "io": {"requires": ["common", "octree", "zlib::zlib"] + png() + usb(), "extra_libs": ["io_ply"]}, |
| 179 | + "features": {"requires": ["common", "search", "kdtree", "octree", "filters", "2d"]}, |
| 180 | + "ml": {"requires": ["common"]}, |
| 181 | + "segmentation": {"requires": ["common", "geometry", "search", "sample_consensus", "kdtree", "octree", "features", "filters", "ml"]}, |
| 182 | + "surface": {"requires": ["common", "search", "kdtree", "octree"] + qhull()}, |
| 183 | + "registration": {"requires": ["common", "octree", "kdtree", "search", "sample_consensus", "features", "filters"]}, |
| 184 | + "keypoints": {"requires": ["common", "search", "kdtree", "octree", "features", "filters"]}, |
| 185 | + "tracking": {"requires": ["common", "search", "kdtree", "filters", "octree"]}, |
| 186 | + "recognition": {"requires": ["common", "io", "search", "kdtree", "octree", "features", "filters", "registration", "sample_consensus", "ml"]}, |
| 187 | + "stereo": {"requires": ["common", "io"]} |
| 188 | + } |
| 189 | + |
| 190 | + @property |
| 191 | + def _version_suffix(self): |
| 192 | + semver = Version(self.version) |
| 193 | + return "{}.{}".format(semver.major, semver.minor) |
| 194 | + |
| 195 | + def _lib_name(self, lib): |
| 196 | + if self.settings.compiler == "msvc" and self.settings.build_type == "Debug": |
| 197 | + return "pcl_{}d".format(lib) |
| 198 | + return "pcl_{}".format(lib) |
| 199 | + |
| 200 | + def package_info(self): |
| 201 | + self.cpp_info.names["cmake_find_package"] = "PCL" |
| 202 | + self.cpp_info.names["cmake_find_package_multi"] = "PCL" |
| 203 | + |
| 204 | + self.cpp_info.set_property("cmake_file_name", "PCL") |
| 205 | + self.cpp_info.set_property("cmake_module_file_name", "PCL") |
| 206 | + self.cpp_info.set_property("cmake_target_name", "PCL::PCL") |
| 207 | + |
| 208 | + def _update_components(components): |
| 209 | + for comp, values in components.items(): |
| 210 | + self.cpp_info.components[comp].names["cmake_find_package"] = comp |
| 211 | + self.cpp_info.components[comp].names["cmake_find_package_multi"] = comp |
| 212 | + self.cpp_info.components[comp].set_property("cmake_file_name", comp) |
| 213 | + self.cpp_info.components[comp].set_property("cmake_module_file_name", comp) |
| 214 | + self.cpp_info.components[comp].set_property("cmake_target_name", f"PCL::{comp}") |
| 215 | + |
| 216 | + self.cpp_info.components[comp].names["pkg_config"] = "pcl_{}-{}".format(comp, self._version_suffix) |
| 217 | + self.cpp_info.components[comp].set_property("pkg_config_name", "pcl_{}-{}".format(comp, self._version_suffix)) |
| 218 | + |
| 219 | + self.cpp_info.components[comp].includedirs = [os.path.join("include", "pcl-{}".format(self._version_suffix))] |
| 220 | + if not values.get("header_only", False): |
| 221 | + libs = [comp] + values.get("extra_libs", []) |
| 222 | + self.cpp_info.components[comp].libs = [self._lib_name(lib) for lib in libs] |
| 223 | + self.cpp_info.components[comp].requires = values["requires"] |
| 224 | + |
| 225 | + _update_components(self._pcl_lib_components) |
| 226 | + |
| 227 | + if not self.options.shared: |
| 228 | + if self.settings.os in ["Linux", "FreeBSD"]: |
| 229 | + self.cpp_info.components["common"].system_libs.append("pthread") |
| 230 | + if self.options.with_openmp: |
| 231 | + if self.settings.os == "Linux": |
| 232 | + if self.settings.compiler == "gcc": |
| 233 | + self.cpp_info.components["common"].sharedlinkflags.append("-fopenmp") |
| 234 | + self.cpp_info.components["common"].exelinkflags.append("-fopenmp") |
| 235 | + elif self.settings.os == "Windows": |
| 236 | + if self.settings.compiler == "msvc": |
| 237 | + self.cpp_info.components["common"].system_libs.append("delayimp") |
| 238 | + elif self.settings.compiler == "gcc": |
| 239 | + self.cpp_info.components["common"].system_libs.append("gomp") |
| 240 | + |
| 241 | + if self.options.with_apps: |
| 242 | + self.cpp_info.components["apps"].libs = [] |
| 243 | + self.cpp_info.components["apps"].requires = ["qt::qt"] |
0 commit comments