Skip to content

Commit

Permalink
Merge pull request #5 from valgur/feature/AddPCL
Browse files Browse the repository at this point in the history
pcl: misc recipe tweaks
  • Loading branch information
EstebanDugueperoux2 authored Aug 9, 2023
2 parents d8a1d15 + 9f53056 commit 6bc2990
Show file tree
Hide file tree
Showing 6 changed files with 151 additions and 325 deletions.
14 changes: 6 additions & 8 deletions recipes/pcl/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,13 @@ sources:
sha256: 8ab98a9db371d822de0859084a375a74bdc7f31c96d674147710cf4101b79621
patches:
"1.13.1":
- patch_file: "patches/0001-cmake_use_requirements_name_from_cmakedeps.patch"
patch_description: "Update pcl CMake files to work with conan"
patch_type: "conan"
- patch_file: "patches/0001-KB-H020_avoid_pkgconfig_files.patch"
patch_description: "Disable pkgconfig files install to follow KB-H020 rule"
patch_type: "conan"
- patch_file: "patches/0001-ReportFixAboutMemoryConsumptionDuringBuild.patch"
patch_description: "Report fix from https://github.com/PointCloudLibrary/pcl/pull/5764"
- patch_file: "patches/0001-cmake_use_conan_targets.patch"
patch_description: "Update PCL CMake files to work with Conan"
patch_type: "conan"
- patch_file: "patches/0001-Add-Eigen3-Eigen-target-in-pcl_common-target.patch"
patch_description: "Add Eigen3::Eigen target to pcl_common target"
patch_type: "conan"
- patch_file: "patches/0001-ReportFixAboutMemoryConsumptionDuringBuild.patch"
patch_description: "MovingLeastSquares: reduce the number of instantiations to reduce compile time"
patch_source: "https://github.com/PointCloudLibrary/pcl/pull/5764"
patch_type: "conan"
182 changes: 94 additions & 88 deletions recipes/pcl/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,18 @@
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.microsoft import check_min_vs, is_msvc
from conan.tools.files import apply_conandata_patches, export_conandata_patches, get, copy, rmdir
from conan.tools.build import check_min_cppstd
from conan.tools.scm import Version
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import apply_conandata_patches, export_conandata_patches, get, copy, rmdir, rm
from conan.tools.scm import Version
from conan.tools.system import package_manager
import os


required_conan_version = ">=1.53.0"


class PclConan(ConanFile):
name = "pcl"
description = "Point Cloud Library"
description = "The Point Cloud Library (PCL) is a standalone, large-scale, open project for 2D/3D image and point cloud processing."
license = "BSD-3-Clause"
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://github.com/PointCloudLibrary/pcl"
Expand Down Expand Up @@ -45,7 +43,7 @@ class PclConan(ConanFile):
"with_vtk": False,
"with_cuda": False,
"with_pcap": False,
"with_opengl": False,
"with_opengl": True,
"with_tools": False,
"with_apps": False,
}
Expand All @@ -56,13 +54,14 @@ class PclConan(ConanFile):
def _min_cppstd(self):
return 17

# in case the project requires C++14/17/20/... the minimum compiler version should be listed
@property
def _compilers_minimum_version(self):
return {
"gcc": "7",
"clang": "7",
"apple-clang": "10",
"msvc": "191",
"Visual Studio": "15",
}

def export_sources(self):
Expand All @@ -81,14 +80,16 @@ def layout(self):

def system_requirements(self):
if self.options.with_vtk:
# TODO: add vtk/system package?
package_manager.Apt(self).install(["libvtk-dev"])
package_manager.Dnf(self).install(["vtk-devel"])
if self.settings.os == "Windows":
self.output.warn("On Windows VTK must be installed manually.")
self.output.warn("VTK must be installed manually on Windows.")

def requirements(self):
self.requires("zlib/1.2.13")
# Transitive headers on boost because pcl/point_struct_traits.h:40:10: references boost/mpl/assert.hpp
# Boost is used in public PCL headers here:
# https://github.com/PointCloudLibrary/pcl/blob/pcl-1.13.1/common/include/pcl/point_struct_traits.h#L40-L46
self.requires("boost/1.82.0", transitive_headers=True)
self.requires("eigen/3.4.0", transitive_headers=True)
self.requires("flann/1.9.2")
Expand All @@ -104,102 +105,83 @@ def requirements(self):
self.requires("libpcap/1.10.4")
if self.options.with_opengl:
self.requires("opengl/system")
self.requires("glew/2.2.0")

def validate(self):
# validate the minimum cpp standard supported. For C++ projects only
if self.settings.compiler.cppstd:
check_min_cppstd(self, self._min_cppstd)
check_min_vs(self, 191)
if not is_msvc(self):
minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
if minimum_version and Version(self.settings.compiler.version) < minimum_version:
raise ConanInvalidConfiguration(
f"{self.ref} requires C++{self._min_cppstd}, which your compiler does not support."
)
minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
if minimum_version and Version(self.settings.compiler.version) < minimum_version:
raise ConanInvalidConfiguration(
f"{self.ref} requires C++{self._min_cppstd}, which your compiler does not support."
)

def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True)

def generate(self):
tc = CMakeToolchain(self)
tc.variables["PCL_SHARED_LIBS"] = self.options.shared
tc.variables["WITH_OPENMP"] = self.options.with_openmp
tc.variables["WITH_LIBUSB"] = self.options.with_libusb
tc.variables["WITH_PNG"] = self.options.with_png
tc.variables["WITH_QHULL"] = self.options.with_qhull
tc.variables["WITH_VTK"] = self.options.with_vtk
tc.variables["WITH_CUDA"] = self.options.with_cuda
tc.variables["WITH_PCAP"] = self.options.with_pcap
tc.variables["WITH_OPENGL"] = self.options.with_opengl
tc.variables["BUILD_tools"] = self.options.with_tools
tc.variables["BUILD_apps"] = self.options.with_apps
tc.variables["BUILD_examples"] = True
tc.cache_variables["PCL_SHARED_LIBS"] = self.options.shared
tc.cache_variables["WITH_OPENMP"] = self.options.with_openmp
tc.cache_variables["WITH_LIBUSB"] = self.options.with_libusb
tc.cache_variables["WITH_PNG"] = self.options.with_png
tc.cache_variables["WITH_QHULL"] = self.options.with_qhull
tc.cache_variables["WITH_VTK"] = self.options.with_vtk
tc.cache_variables["WITH_CUDA"] = self.options.with_cuda
tc.cache_variables["WITH_PCAP"] = self.options.with_pcap
tc.cache_variables["WITH_OPENGL"] = self.options.with_opengl
tc.cache_variables["BUILD_tools"] = self.options.with_tools
tc.cache_variables["BUILD_apps"] = self.options.with_apps
tc.cache_variables["BUILD_examples"] = False
tc.cache_variables["WITH_QT"] = self.options.with_apps
tc.cache_variables["PCL_ONLY_CORE_POINT_TYPES"] = True
tc.generate()

tc = CMakeDeps(self)
tc.set_property("eigen", "cmake_file_name", "EIGEN")
tc.set_property("flann", "cmake_file_name", "FLANN")
tc.set_property("flann", "cmake_target_name", "FLANN::FLANN")
tc.set_property("glew", "cmake_file_name", "GLEW")
if self.options.with_qhull:
tc.set_property("qhull", "cmake_file_name", "QHULL")
tc.generate()

def _patch_sources(self):
apply_conandata_patches(self)
for mod in ["Eigen", "FLANN", "GLEW", "PCap", "Qhull", "libusb"]:
os.remove(os.path.join(self.source_folder, "cmake", "Modules", f"Find{mod}.cmake"))

def build(self):
self._patch_sources()
cmake = CMake(self)
cmake.configure(variables={"PCL_ONLY_CORE_POINT_TYPES": "ON"})
cmake.configure()
cmake.build()

def package(self):
copy(self, pattern="LICENSE.txt", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
copy(self, "LICENSE.txt",
dst=os.path.join(self.package_folder, "licenses"),
src=self.source_folder)

cmake = CMake(self)
cmake.install()

rmdir(self, os.path.join(self.package_folder, "cmake"))
rmdir(self, os.path.join(self.package_folder, "share"))
# For the legal reasons, and in order to reduce the size of packages, it's not allowed to package Microsoft Visual Studio runtime libraries, such as msvcr80.dll, msvcp80.dll, vcruntime140.dll and so on.
# See https://github.com/conan-io/conan-center-index/blob/master/docs/error_knowledge_base.md#kb-h021-ms-runtime-files
rmdir(self, os.path.join(self.package_folder, "bin"))

@property
def _pcl_lib_components(self):
def usb():
return ["libusb::libusb"] if self.options.with_libusb else []
def png():
return ["libpng::libpng"] if self.options.with_png else []
def qhull():
return ["qhull::qhull"] if self.options.with_qhull else []

return {
"common": {"requires": ["eigen::eigen3", "boost::boost"]},
"kdtree": {"requires": ["common", "flann::flann"]},
"octree": {"requires": ["common"]},
"search": {"requires": ["common", "kdtree", "octree", "flann::flann"]},
"sample_consensus": {"requires": ["common", "search"]},
"filters": {"requires": ["common", "sample_consensus", "search", "kdtree", "octree"]},
"2d": {"requires": ["common", "filters"], "header_only": True},
"geometry": {"requires": ["common"], "header_only": True},
"io": {"requires": ["common", "octree", "zlib::zlib"] + png() + usb(), "extra_libs": ["io_ply"]},
"features": {"requires": ["common", "search", "kdtree", "octree", "filters", "2d"]},
"ml": {"requires": ["common"]},
"segmentation": {"requires": ["common", "geometry", "search", "sample_consensus", "kdtree", "octree", "features", "filters", "ml"]},
"surface": {"requires": ["common", "search", "kdtree", "octree"] + qhull()},
"registration": {"requires": ["common", "octree", "kdtree", "search", "sample_consensus", "features", "filters"]},
"keypoints": {"requires": ["common", "search", "kdtree", "octree", "features", "filters"]},
"tracking": {"requires": ["common", "search", "kdtree", "filters", "octree"]},
"recognition": {"requires": ["common", "io", "search", "kdtree", "octree", "features", "filters", "registration", "sample_consensus", "ml"]},
"stereo": {"requires": ["common", "io"]}
}
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
# Remove MSVC runtime libraries
for dll_pattern_to_remove in ["concrt*.dll", "msvcp*.dll", "vcruntime*.dll"]:
rm(self, dll_pattern_to_remove, os.path.join(self.package_folder, "bin"))

@property
def _version_suffix(self):
semver = Version(self.version)
return "{}.{}".format(semver.major, semver.minor)
return f"{semver.major}.{semver.minor}"

def _lib_name(self, lib):
if self.settings.compiler == "msvc" and self.settings.build_type == "Debug":
return "pcl_{}d".format(lib)
return "pcl_{}".format(lib)
return f"pcl_{lib}d"
return f"pcl_{lib}"

def package_info(self):
self.cpp_info.names["cmake_find_package"] = "PCL"
self.cpp_info.names["cmake_find_package_multi"] = "PCL"
Expand All @@ -208,38 +190,62 @@ def package_info(self):
self.cpp_info.set_property("cmake_module_file_name", "PCL")
self.cpp_info.set_property("cmake_target_name", "PCL::PCL")

def _update_components(components):
for comp, values in components.items():
self.cpp_info.components[comp].names["cmake_find_package"] = comp
self.cpp_info.components[comp].names["cmake_find_package_multi"] = comp
self.cpp_info.components[comp].set_property("cmake_file_name", comp)
self.cpp_info.components[comp].set_property("cmake_module_file_name", comp)
self.cpp_info.components[comp].set_property("cmake_target_name", f"PCL::{comp}")
def _add_component(comp, requires, *, extra_libs=(), header_only=False):
self.cpp_info.components[comp].names["cmake_find_package"] = comp
self.cpp_info.components[comp].names["cmake_find_package_multi"] = comp
self.cpp_info.components[comp].set_property("cmake_file_name", comp)
self.cpp_info.components[comp].set_property("cmake_module_file_name", comp)
self.cpp_info.components[comp].set_property("cmake_target_name", f"PCL::{comp}")
self.cpp_info.components[comp].set_property("pkg_config_name", f"pcl_{comp}-{self._version_suffix}")
self.cpp_info.components[comp].includedirs = [os.path.join("include", f"pcl-{self._version_suffix}")]
if not header_only:
libs = [comp] + extra_libs
if comp != "common":
libs.append("common")
self.cpp_info.components[comp].libs = [self._lib_name(lib) for lib in libs]
self.cpp_info.components[comp].requires = requires

self.cpp_info.components[comp].names["pkg_config"] = "pcl_{}-{}".format(comp, self._version_suffix)
self.cpp_info.components[comp].set_property("pkg_config_name", "pcl_{}-{}".format(comp, self._version_suffix))
def usb():
return ["libusb::libusb"] if self.options.with_libusb else []
def png():
return ["libpng::libpng"] if self.options.with_png else []
def qhull():
return ["qhull::qhull"] if self.options.with_qhull else []

self.cpp_info.components[comp].includedirs = [os.path.join("include", "pcl-{}".format(self._version_suffix))]
if not values.get("header_only", False):
libs = [comp] + values.get("extra_libs", [])
self.cpp_info.components[comp].libs = [self._lib_name(lib) for lib in libs]
self.cpp_info.components[comp].requires = values["requires"]
_add_component("common", ["eigen::eigen3", "boost::boost"])
_add_component("kdtree", ["flann::flann"])
_add_component("octree", [])
_add_component("search", ["kdtree", "octree", "flann::flann"])
_add_component("sample_consensus", ["search"])
_add_component("filters", ["sample_consensus", "search", "kdtree", "octree"])
_add_component("2d", ["filters"], header_only=True)
_add_component("geometry", [], header_only=True)
_add_component("io", ["octree", "zlib::zlib"] + png() + usb(), extra_libs=["io_ply"])
_add_component("features", ["search", "kdtree", "octree", "filters", "2d"])
_add_component("ml", [])
_add_component("segmentation", ["geometry", "search", "sample_consensus", "kdtree", "octree", "features", "filters", "ml"])
_add_component("surface", ["search", "kdtree", "octree"] + qhull())
_add_component("registration", ["octree", "kdtree", "search", "sample_consensus", "features", "filters"])
_add_component("keypoints", ["search", "kdtree", "octree", "features", "filters"])
_add_component("tracking", ["search", "kdtree", "filters", "octree"])
_add_component("recognition", ["io", "search", "kdtree", "octree", "features", "filters", "registration", "sample_consensus", "ml"])
_add_component("stereo", ["io"])

_update_components(self._pcl_lib_components)

if not self.options.shared:
common = self.cpp_info.components["common"]
if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.components["common"].system_libs.append("pthread")
common.system_libs.append("pthread")
if self.options.with_openmp:
if self.settings.os == "Linux":
if self.settings.compiler == "gcc":
self.cpp_info.components["common"].sharedlinkflags.append("-fopenmp")
self.cpp_info.components["common"].exelinkflags.append("-fopenmp")
common.sharedlinkflags.append("-fopenmp")
common.exelinkflags.append("-fopenmp")
elif self.settings.os == "Windows":
if self.settings.compiler == "msvc":
self.cpp_info.components["common"].system_libs.append("delayimp")
common.system_libs.append("delayimp")
elif self.settings.compiler == "gcc":
self.cpp_info.components["common"].system_libs.append("gomp")
common.system_libs.append("gomp")

if self.options.with_apps:
self.cpp_info.components["apps"].libs = []
Expand Down
12 changes: 0 additions & 12 deletions recipes/pcl/all/patches/0001-KB-H020_avoid_pkgconfig_files.patch

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
From 0bc2f2cc369f7d013ee5c29075188c4e26ea6f87 Mon Sep 17 00:00:00 2001
From: Markus Vieth <mvieth@techfak.uni-bielefeld.de>
Date: Sat, 15 Jul 2023 15:49:25 +0200
Subject: [PATCH] MovingLeastSquares: reduce the number of instantiations to
reduce compile time PCL_XYZ_POINT_TYPES currently contains 18 types, so
previously, MLS was instantiated for 18*18=324 different type combinations.
However, among those were instantiations which are likely used by nobody
(like `pcl::MovingLeastSquares<pcl::PointWithRange, pcl::PointDEM>`). With
these changes, MLS is only instantiated 6*6+(18-6)=48 times. The most common
type combinations should be covered, but if someone uses an uncommon
combinations, they have to add `#define PCL_NO_PRECOMPILE` before including
`pcl/surface/mls.h` to avoid linker errors.

---
surface/src/mls.cpp | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/surface/src/mls.cpp b/surface/src/mls.cpp
index ba2fd655300..c948f4d19e1 100644
--- a/surface/src/mls.cpp
+++ b/surface/src/mls.cpp
@@ -80,6 +80,15 @@ pcl::MLSResult::calculatePrincipalCurvatures (const double u, const double v) co
Expand Down
32 changes: 32 additions & 0 deletions recipes/pcl/all/patches/0001-cmake_use_conan_targets.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -319,6 +319,6 @@ endif()
find_package(Threads REQUIRED)

# Eigen (required)
-find_package(Eigen 3.3 REQUIRED)
+find_package(EIGEN REQUIRED)
include_directories(SYSTEM ${EIGEN_INCLUDE_DIRS})

--- a/common/CMakeLists.txt
+++ b/common/CMakeLists.txt
@@ -4,7 +4,7 @@ set(SUBSYS_DEPS)

set(build TRUE)
PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON)
-PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} EXT_DEPS eigen boost)
+PCL_SUBSYS_DEPEND(build NAME ${SUBSYS_NAME} DEPS ${SUBSYS_DEPS} EXT_DEPS EIGEN Boost)

PCL_ADD_DOC("${SUBSYS_NAME}")

--- a/io/CMakeLists.txt
+++ b/io/CMakeLists.txt
@@ -1,7 +1,7 @@
set(SUBSYS_NAME io)
set(SUBSYS_DESC "Point cloud IO library")
set(SUBSYS_DEPS common octree)
-set(SUBSYS_EXT_DEPS boost eigen)
+set(SUBSYS_EXT_DEPS Boost EIGEN)

set(build TRUE)
PCL_SUBSYS_OPTION(build "${SUBSYS_NAME}" "${SUBSYS_DESC}" ON)
Loading

0 comments on commit 6bc2990

Please sign in to comment.