-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PCL package #1891
Add PCL package #1891
Changes from 44 commits
78029bd
07d0522
fd43a92
8774793
32fef4e
8b74bde
2c755e9
843cf55
9050c8d
6b6ddb5
3cc5c64
3c21176
13125af
2347012
2f0a1ec
2145466
d636240
2741a6e
c272820
53da8bb
8fd2f64
5646161
d03b370
db4eb9a
9129ede
388be41
5143ee9
605c465
1652b16
9a39937
6aa6ef9
0bf1936
dae7be3
33499eb
00a4b9e
41911a9
eba3a02
1730606
414e203
19cb75d
a71774f
2235aaa
634a2f8
e0d7968
9382f89
c6fef55
8c9555e
d1b16fe
de87a86
ec5056e
d7cc565
a52af55
74580bc
8476322
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
cmake_minimum_required(VERSION 2.8.12) | ||
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) | ||
conan_basic_setup() | ||
|
||
find_package(Qhull REQUIRED) | ||
set(QHULL_INCLUDE_DIRS ${Qhull_INCLUDE_DIRS}) | ||
set(QHULL_LIBRARIES ${Qhull_LIBRARIES}) | ||
set(HAVE_QHULL ON) | ||
set(HAVE_QHULL_2011 TRUE) | ||
set(QHULL_FOUND TRUE) | ||
|
||
add_subdirectory(source_subfolder) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
sources: | ||
"1.11.1": | ||
url: "https://github.com/PointCloudLibrary/pcl/archive/pcl-1.11.1.tar.gz" | ||
sha256: "a61558e53abafbc909e0996f91cfd2d7a400fcadf6b8cfb0ea3172b78422c74e" |
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,255 @@ | ||||||||
import os | ||||||||
from glob import glob | ||||||||
from itertools import chain | ||||||||
|
||||||||
from conans import ConanFile, CMake, tools | ||||||||
from conans.errors import ConanInvalidConfiguration | ||||||||
|
||||||||
|
||||||||
class PclConanRecipe(ConanFile): | ||||||||
name = "pcl" | ||||||||
description = "Point Cloud Library" | ||||||||
license = "BSD-3-Clause" | ||||||||
homepage = "https://pointclouds.org/" | ||||||||
url = "https://github.com/conan-io/conan-center-index" | ||||||||
planetmarshall marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
topics = ("pointcloud", "computer-vision", "point-cloud") | ||||||||
settings = "os", "compiler", "build_type", "arch" | ||||||||
options = { | ||||||||
"shared": [True, False], | ||||||||
"fPIC": [True, False], | ||||||||
"with_cuda": [True, False], | ||||||||
planetmarshall marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
"with_tools": [True, False] | ||||||||
} | ||||||||
default_options = { | ||||||||
"shared": False, | ||||||||
"fPIC": True, | ||||||||
"with_cuda": False, | ||||||||
"with_tools": False, | ||||||||
"qhull:reentrant": False | ||||||||
} | ||||||||
requires = ("boost/1.74.0", | ||||||||
"eigen/3.3.8", | ||||||||
"flann/1.9.1", | ||||||||
"libpng/1.6.37", | ||||||||
"qhull/7.3.2") | ||||||||
generators = ["cmake", "cmake_find_package"] | ||||||||
exports = ["CMakeLists.txt"] | ||||||||
_cmake = None | ||||||||
|
||||||||
@property | ||||||||
def _source_subfolder(self): | ||||||||
return "source_subfolder" | ||||||||
|
||||||||
@property | ||||||||
def _version_suffix(self): | ||||||||
semver = tools.Version(self.version) | ||||||||
return "{}.{}".format(semver.major, semver.minor) | ||||||||
|
||||||||
def source(self): | ||||||||
tools.get(**self.conan_data["sources"][self.version]) | ||||||||
planetmarshall marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
os.rename("pcl-pcl-{}".format(self.version), self._source_subfolder) | ||||||||
cmake_lists = os.path.join(self._source_subfolder, "CMakeLists.txt") | ||||||||
tools.replace_in_file( | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The replace in file should be done in the build method |
||||||||
cmake_lists, | ||||||||
"""set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/" ${CMAKE_MODULE_PATH})""", | ||||||||
"""list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules/")""" | ||||||||
) | ||||||||
tools.replace_in_file( | ||||||||
cmake_lists, | ||||||||
"find_package(FLANN 1.7.0 REQUIRED)", | ||||||||
"find_package(Flann REQUIRED)" | ||||||||
) | ||||||||
# Temporary hack for https://github.com/conan-io/conan/issues/8206 | ||||||||
tools.replace_in_file( | ||||||||
os.path.join(self._source_subfolder, "cmake", "pcl_find_boost.cmake"), | ||||||||
"find_package(Boost 1.55.0 QUIET COMPONENTS serialization mpi)", | ||||||||
"find_package(Boost 1.55.0 QUIET OPTIONAL_COMPONENTS serialization)" | ||||||||
) | ||||||||
for folder in ["search", "kdtree"]: | ||||||||
tools.replace_in_file( | ||||||||
os.path.join(self._source_subfolder, folder, "CMakeLists.txt"), | ||||||||
"FLANN::FLANN", "Flann::Flann" | ||||||||
) | ||||||||
|
||||||||
def config_options(self): | ||||||||
if self.settings.os == "Windows": | ||||||||
del self.options.fPIC | ||||||||
|
||||||||
def _check_msvc(self): | ||||||||
if (tools.msvs_toolset(self) == "v140" or | ||||||||
self.settings.compiler == "Visual Studio" and tools.Version(self.settings.compiler.version) < "15"): | ||||||||
raise ConanInvalidConfiguration("Unsupported Visual Studio Compiler or Toolset") | ||||||||
|
||||||||
def _check_cxx_standard(self): | ||||||||
minimal_cpp_standard = "14" | ||||||||
if self.settings.compiler.cppstd: | ||||||||
tools.check_min_cppstd(self, minimal_cpp_standard) | ||||||||
minimal_version = { | ||||||||
"gcc": "5", | ||||||||
"clang": "3.4", | ||||||||
"apple-clang": "10", | ||||||||
"Visual Studio": "14" | ||||||||
} | ||||||||
compiler = str(self.settings.compiler) | ||||||||
if compiler not in minimal_version: | ||||||||
self.output.warn( | ||||||||
"%s recipe lacks information about the %s compiler standard version support" % (self.name, compiler)) | ||||||||
self.output.warn( | ||||||||
"%s requires a compiler that supports at least C++%s" % (self.name, minimal_cpp_standard)) | ||||||||
return | ||||||||
version = tools.Version(self.settings.compiler.version) | ||||||||
if version < minimal_version[compiler]: | ||||||||
raise ConanInvalidConfiguration("%s requires a compiler that supports at least C++%s" % (self.name, minimal_cpp_standard)) | ||||||||
|
||||||||
def _check_libcxx_compatibility(self): | ||||||||
if self.settings.compiler == "clang" and self.settings.compiler.libcxx == "libc++": | ||||||||
version = tools.Version(self.settings.compiler.version) | ||||||||
minimum_version = 6 | ||||||||
if version < minimum_version: | ||||||||
raise ConanInvalidConfiguration("Clang with libc++ is version %s but must be at least version %s" % | ||||||||
(version, minimum_version)) | ||||||||
|
||||||||
def configure(self): | ||||||||
self._check_msvc() | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I tested on macOS. This line needed to prevent fail.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @sakrist The error on that picture is different, it shows that the package version that you passed to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. True. This is new error I get after fix in first comment. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Successfully compiled 1.12.1 package on MacBook M1 Pro. |
||||||||
self._check_cxx_standard() | ||||||||
self._check_libcxx_compatibility() | ||||||||
if self.options["qhull"].reentrant: | ||||||||
self.output.warn( | ||||||||
"Qhull is set to link the reentrant library. If you experience linking errors, try setting " | ||||||||
"qhull:reentrant=False") | ||||||||
|
||||||||
def _configure_cmake(self): | ||||||||
if self._cmake: | ||||||||
return self._cmake | ||||||||
|
||||||||
cmake_definitions = { | ||||||||
"CONAN_PCL_VERSION": self.version, | ||||||||
"PCL_BUILD_WITH_BOOST_DYNAMIC_LINKING_WIN32": self.options["boost"].shared | ||||||||
} | ||||||||
|
||||||||
pcl_config = { | ||||||||
"BUILD_tools": self.options.with_tools, | ||||||||
"WITH_LIBUSB": False, | ||||||||
"WITH_PNG": True, | ||||||||
"WITH_QHULL": True, | ||||||||
"WITH_CUDA": self.options.with_cuda, | ||||||||
"WITH_VTK": False, | ||||||||
"WITH_PCAP": False, | ||||||||
"WITH_OPENGL": False, | ||||||||
"WITH_OPENNI": False, | ||||||||
"WITH_OPENNI2": False, | ||||||||
"WITH_ENSENSO": False, | ||||||||
"WITH_DAVIDSDK": False, | ||||||||
"WITH_DSSDK": False, | ||||||||
"WITH_RSSDK": False, | ||||||||
"PCL_SHARED_LIBS": self.options.shared, | ||||||||
"FLANN_USE_STATIC": not self.options["flann"].shared, | ||||||||
"QHULL_USE_STATIC": not self.options["qhull"].shared | ||||||||
} | ||||||||
pcl_features = { | ||||||||
"BUILD_kdtree": True, | ||||||||
"BUILD_octree": True, | ||||||||
"BUILD_search": True, | ||||||||
"BUILD_sample_consensus": True, | ||||||||
"BUILD_filters": True, | ||||||||
"BUILD_2d": True, | ||||||||
"BUILD_geometry": True, | ||||||||
"BUILD_io": True, | ||||||||
"BUILD_features": True, | ||||||||
"BUILD_ml": True, | ||||||||
"BUILD_segmentation": True, | ||||||||
"BUILD_surface": True, | ||||||||
"BUILD_module_registration": True, | ||||||||
"BUILD_module_keypoints": True, | ||||||||
"BUILD_module_tracking": True, | ||||||||
"BUILD_recognition": True, | ||||||||
"BUILD_stereo": True, | ||||||||
} | ||||||||
|
||||||||
self._cmake = CMake(self) | ||||||||
self._cmake.definitions.update(cmake_definitions) | ||||||||
self._cmake.definitions.update(pcl_config) | ||||||||
self._cmake.definitions.update(pcl_features) | ||||||||
self._cmake.configure() | ||||||||
return self._cmake | ||||||||
|
||||||||
def build(self): | ||||||||
cmake = self._configure_cmake() | ||||||||
cmake.build() | ||||||||
|
||||||||
def _remove_vs_runtime_files(self): | ||||||||
patterns = [os.path.join(self.package_folder, "bin", pattern) for pattern in ["msvcp*.dll", "vcruntime*.dll", "concrt*.dll"]] | ||||||||
runtime_files = chain.from_iterable(glob(pattern) for pattern in patterns) | ||||||||
for runtime_file in runtime_files: | ||||||||
try: | ||||||||
os.remove(runtime_file) | ||||||||
except Exception as ex: | ||||||||
self.output.warn("Could not remove vs runtime file {}, {}".format(runtime_file, ex)) | ||||||||
|
||||||||
def package(self): | ||||||||
cmake = self._configure_cmake() | ||||||||
cmake.install() | ||||||||
self.copy(pattern="LICENSE.txt", dst="licenses", src=self._source_subfolder) | ||||||||
if self.settings.os == "Windows": | ||||||||
self._remove_vs_runtime_files() | ||||||||
|
||||||||
tools.rmdir(os.path.join(self.package_folder, "cmake")) | ||||||||
tools.rmdir(os.path.join(self.package_folder, "share")) | ||||||||
tools.rmdir(os.path.join(self.package_folder, "lib", "pkgconfig")) | ||||||||
|
||||||||
def _lib_name(self, lib): | ||||||||
if self.settings.compiler == "Visual Studio" and self.settings.build_type == "Debug": | ||||||||
return "pcl_{}d".format(lib) | ||||||||
return "pcl_{}".format(lib) | ||||||||
|
||||||||
def _update_components(self, name, dependencies, header_only=False, extra_libs=None): | ||||||||
if not extra_libs: | ||||||||
extra_libs = [] | ||||||||
if not header_only: | ||||||||
self.cpp_info.components[name].libs = [self._lib_name(lib) for lib in [name] + extra_libs] | ||||||||
self.cpp_info.components[name].includedirs = ["include/pcl-{}".format(self._version_suffix)] | ||||||||
self.cpp_info.components[name].name = "PCL_{}_LIBRARIES".format(name.upper()) | ||||||||
self.cpp_info.components[name].names["pkg_config"] = "pcl_{}-{}".format(name, self._version_suffix) | ||||||||
self.cpp_info.components[name].requires = dependencies | ||||||||
|
||||||||
def package_info(self): | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Here are inter dependencies extracted from #list each component dependencies IN PCL
set(pcl_kdtree_int_dep common )
set(pcl_octree_int_dep common )
set(pcl_search_int_dep common kdtree octree )
set(pcl_sample_consensus_int_dep common search )
set(pcl_filters_int_dep common sample_consensus search kdtree octree )
set(pcl_2d_int_dep common filters )
set(pcl_geometry_int_dep common )
set(pcl_io_int_dep common octree )
set(pcl_features_int_dep common search kdtree octree filters 2d )
set(pcl_ml_int_dep common )
set(pcl_segmentation_int_dep common geometry search sample_consensus kdtree octree features filters ml )
set(pcl_surface_int_dep common search kdtree octree )
set(pcl_registration_int_dep common octree kdtree search sample_consensus features filters )
set(pcl_keypoints_int_dep common search kdtree octree features filters )
set(pcl_tracking_int_dep common search kdtree filters octree )
set(pcl_recognition_int_dep common io search kdtree octree features filters registration sample_consensus ml )
set(pcl_stereo_int_dep common io ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Conan center index packages do not support custom PKG config or cmake files. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, but There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. here is a starter to help you: def package_info(self):
self.cpp_info.names["cmake_find_package"] = "PCL"
self.cpp_info.names["cmake_find_package_multi"] = "PCL"
# common
self.cpp_info.components["common"].names["pkg_config"] = "pcl_common"
self.cpp_info.components["common"].libs = ["common"]
# kdtree
self.cpp_info.components["kdtree"].names["pkg_config"] = "pcl_kdtree"
self.cpp_info.components["kdtree"].libs = ["kdtree"]
self.cpp_info.components["kdtree"].requires = ["common"]
... Maybe some values are wrong, didn't check exact lib names or pkgconfig files. You'll have also to properly define external dependencies of each component (and eventually system libs dependencies if any depending on os). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Components is still marked as an experimental feature. Are there any other conan center index packages doing this? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, it's experimental yet, but it should not break, probably it should be increased. Yes, we have a lot of recipe using it (thanks to @SpaceIm): https://github.com/conan-io/conan-center-index/search?l=Python&q=components&type=Code There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Attempted to get as close as I can to PCL's target names, however it creates targets without namespaces along the lines of I don't see a way in conan/cmake to distinguish between a non-namespaced target called There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Conan cmake generator, primarily, focus on the targets approach since that is considered the best practice now a days. We can not create and variables (yet). I think the components work done is complete for a first PR, feel free to mark this resolved! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have now several recipes which are able to provide non-namespaced targets. Take a look at OpenCV recipe for a complex example with targets. |
||||||||
pcl_common = "common" | ||||||||
pcl_kdtree = "kdtree" | ||||||||
pcl_octree = "octree" | ||||||||
pcl_search = "search" | ||||||||
pcl_sample_consensus = "sample_consensus" | ||||||||
pcl_filters = "filters" | ||||||||
pcl_2d = "2d" | ||||||||
pcl_geometry = "geometry" | ||||||||
pcl_io = "io" | ||||||||
pcl_features = "features" | ||||||||
pcl_ml = "ml" | ||||||||
pcl_segmentation = "segmentation" | ||||||||
pcl_surface = "surface" | ||||||||
pcl_registration = "registration" | ||||||||
pcl_keypoints = "keypoints" | ||||||||
pcl_tracking = "tracking" | ||||||||
pcl_recognition = "recognition" | ||||||||
pcl_stereo = "stereo" | ||||||||
|
||||||||
self.cpp_info.names["cmake_find_package"] = "PCL" | ||||||||
self.cpp_info.names["pkg_config"] = "PCL" | ||||||||
|
||||||||
self._update_components(pcl_common, ["eigen::eigen", "boost::boost"]) | ||||||||
self._update_components(pcl_kdtree, [pcl_common, "flann::flann"]) | ||||||||
self._update_components(pcl_octree, [pcl_common]) | ||||||||
self._update_components(pcl_search, [pcl_common, pcl_kdtree, pcl_octree, "flann::flann"]) | ||||||||
self._update_components(pcl_sample_consensus, [pcl_common, pcl_search]) | ||||||||
self._update_components(pcl_filters, [pcl_common, pcl_sample_consensus, pcl_search, pcl_kdtree, pcl_octree]) | ||||||||
self._update_components(pcl_2d, [pcl_common, pcl_filters], header_only=True) | ||||||||
self._update_components(pcl_geometry, [pcl_common], header_only=True) | ||||||||
self._update_components(pcl_io, [pcl_common, pcl_octree, "libpng::libpng"], extra_libs=["io_ply"]) | ||||||||
self._update_components(pcl_features, [pcl_common,pcl_search, pcl_kdtree, pcl_octree, pcl_filters, pcl_2d]) | ||||||||
self._update_components(pcl_ml, [pcl_common]) | ||||||||
self._update_components(pcl_segmentation, [pcl_common, pcl_geometry, pcl_search, pcl_sample_consensus, pcl_kdtree, pcl_octree, pcl_features, pcl_filters, pcl_ml]) | ||||||||
self._update_components(pcl_surface, [pcl_common, pcl_search, pcl_kdtree, pcl_octree, "qhull::qhull"]) | ||||||||
self._update_components(pcl_registration, [pcl_common, pcl_octree, pcl_kdtree, pcl_search, pcl_sample_consensus, pcl_features, pcl_filters]) | ||||||||
self._update_components(pcl_keypoints, [pcl_common, pcl_search, pcl_kdtree, pcl_octree, pcl_features, pcl_filters]) | ||||||||
self._update_components(pcl_tracking, [pcl_common, pcl_search, pcl_kdtree, pcl_filters, pcl_octree]) | ||||||||
self._update_components(pcl_recognition, [pcl_common, pcl_io, pcl_search, pcl_kdtree, pcl_octree, pcl_features, pcl_filters, pcl_registration, pcl_sample_consensus, pcl_ml]) | ||||||||
self._update_components(pcl_stereo, [pcl_common, pcl_io]) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
cmake_minimum_required(VERSION 3.1.3) | ||
project(PclTestPackage) | ||
|
||
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake) | ||
conan_basic_setup() | ||
|
||
find_package(PCL) | ||
|
||
add_executable(pcl_test_package example.cpp) | ||
target_compile_features(pcl_test_package PUBLIC cxx_std_14) | ||
target_link_libraries(pcl_test_package PRIVATE PCL::PCL_SURFACE_LIBRARIES) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from conans import ConanFile, CMake, tools | ||
import os | ||
|
||
class PclTestConan(ConanFile): | ||
settings = "os", "compiler", "build_type", "arch" | ||
generators = "cmake", "cmake_find_package" | ||
|
||
def build(self): | ||
cmake = CMake(self) | ||
cmake.configure() | ||
cmake.build() | ||
|
||
def test(self): | ||
if not tools.cross_building(self.settings): | ||
bin_path = os.path.join("bin", "pcl_test_package") | ||
self.run(bin_path, run_environment=True) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#include <pcl/point_types.h> | ||
#include <pcl/point_cloud.h> | ||
#include <pcl/surface/convex_hull.h> | ||
|
||
#include <iostream> | ||
|
||
using PointCloud = pcl::PointCloud<pcl::PointXYZ>; | ||
|
||
int main() { | ||
|
||
auto cloud = PointCloud::Ptr(new PointCloud); | ||
cloud->emplace_back(-1, -1, 0); | ||
cloud->emplace_back(1, -1, 0); | ||
cloud->emplace_back(0, 1, 0); | ||
cloud->emplace_back(0, 0, 1); | ||
|
||
std::cout << "Calculating convex hull\n"; | ||
|
||
PointCloud hull_geometry; | ||
|
||
pcl::ConvexHull<pcl::PointXYZ> hull; | ||
hull.setInputCloud(cloud); | ||
hull.setComputeAreaVolume(true); | ||
hull.reconstruct(hull_geometry); | ||
|
||
std::cout << "Convex Hull Volume: " << hull.getTotalVolume() << std::endl; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
versions: | ||
"1.11.1": | ||
folder: all |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just to keep track conan-io/conan#7691