Skip to content
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

gtsam: conan v2 support #15351

Merged
merged 2 commits into from
Jan 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 0 additions & 7 deletions recipes/gtsam/all/CMakeLists.txt

This file was deleted.

48 changes: 36 additions & 12 deletions recipes/gtsam/all/conandata.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,41 @@ sources:
sha256: "8770a440f1af98c3f0d9d4dffd568de2d4c21b245e7231e987e26bc236aeb5aa"
patches:
"4.1.1":
- patch_file: "patches/0001-conan-4.1.1.patch"
base_path: "source_subfolder"
- patch_file: "patches/0002-macos-rpath-4.1.1.patch"
base_path: "source_subfolder"
- patch_file: "patches/4.1.1-0001-cmake-boost.patch"
patch_description: "Use boost targets"
patch_type: "conan"
- patch_file: "patches/4.1.1-0002-cmake-eigen.patch"
patch_description: "Use Eigen include variable from CMakeDeps"
patch_type: "conan"
- patch_file: "patches/4.1.1-0003-macos-rpath.patch"
patch_description: "Relocatable shared libs on Apple OS"
patch_type: "conan"
- patch_file: "patches/4.0.2-0003-cmake-project.patch"
patch_description: "CMake: move project() after cmake_minimum_required()"
patch_type: "conan"
"4.0.3":
- patch_file: "patches/0001-conan-4.0.3.patch"
base_path: "source_subfolder"
- patch_file: "patches/0002-macos-rpath-4.0.3.patch"
base_path: "source_subfolder"
- patch_file: "patches/4.0.3-0001-cmake-boost.patch"
patch_description: "Use boost targets"
patch_type: "conan"
- patch_file: "patches/4.0.3-0002-cmake-eigen.patch"
patch_description: "Use Eigen include variable from CMakeDeps"
patch_type: "conan"
- patch_file: "patches/4.0.3-0003-macos-rpath.patch"
patch_description: "Relocatable shared libs on Apple OS"
patch_type: "conan"
- patch_file: "patches/4.0.2-0003-cmake-project.patch"
patch_description: "CMake: move project() after cmake_minimum_required()"
patch_type: "conan"
"4.0.2":
- patch_file: "patches/0001-conan-4.0.2.patch"
base_path: "source_subfolder"
- patch_file: "patches/0002-macos-rpath-4.0.2.patch"
base_path: "source_subfolder"
- patch_file: "patches/4.0.2-0001-cmake-boost.patch"
patch_description: "Use boost targets"
patch_type: "conan"
- patch_file: "patches/4.0.2-0002-cmake-eigen.patch"
patch_description: "Use Eigen include variable from CMakeDeps"
patch_type: "conan"
- patch_file: "patches/4.0.2-0003-macos-rpath.patch"
patch_description: "Relocatable shared libs on Apple OS"
patch_type: "conan"
- patch_file: "patches/4.0.2-0003-cmake-project.patch"
patch_description: "CMake: move project() after cmake_minimum_required()"
patch_type: "conan"
181 changes: 85 additions & 96 deletions recipes/gtsam/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from conan.tools.microsoft import msvc_runtime_flag, is_msvc
from conans import ConanFile, tools, CMake
from conans.errors import ConanInvalidConfiguration
from conan import ConanFile
from conan.errors import ConanInvalidConfiguration
from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout
from conan.tools.files import apply_conandata_patches, copy, export_conandata_patches, get, replace_in_file, rmdir, save
from conan.tools.microsoft import check_min_vs, is_msvc, msvc_runtime_flag
from conan.tools.scm import Version
import os
import textwrap

required_conan_version = ">=1.43.0"
required_conan_version = ">=1.53.0"


class GtsamConan(ConanFile):
Expand All @@ -14,7 +17,7 @@ class GtsamConan(ConanFile):
url = "https://github.com/conan-io/conan-center-index"
description = ("GTSAM is a library of C++ classes that implement\
smoothing and mapping (SAM) in robotics and vision")
topics = ("gtsam", "mapping", "smoothing")
topics = ("mapping", "smoothing")

settings = "os", "arch", "compiler", "build_type"
options = {
Expand Down Expand Up @@ -66,34 +69,24 @@ class GtsamConan(ConanFile):
"install_cppunitlite": True,
}

generators = "cmake", "cmake_find_package"
_cmake = None

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _build_subfolder(self):
return "build_subfolder"

def export_sources(self):
self.copy("CMakeLists.txt")
for patch in self.conan_data.get("patches", {}).get(self.version, []):
self.copy(patch["patch_file"])
export_conandata_patches(self)

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")
if self.options.with_TBB:
self.options["onetbb"].tbbmalloc = True

def layout(self):
cmake_layout(self, src_folder="src")

def requirements(self):
self.requires("boost/1.78.0")
self.requires("boost/1.81.0")
self.requires("eigen/3.4.0")
if self.options.with_TBB:
self.requires("onetbb/2020.3")
Expand All @@ -103,89 +96,86 @@ def _required_boost_components(self):
return ["serialization", "system", "filesystem", "thread", "date_time", "regex", "timer", "chrono"]

def validate(self):
miss_boost_required_comp = any(getattr(self.options["boost"], "without_{}".format(boost_comp), True) for boost_comp in self._required_boost_components)
if self.options["boost"].header_only or miss_boost_required_comp:
miss_boost_required_comp = any(self.dependencies["boost"].options.get_safe(f"without_{boost_comp}", True)
for boost_comp in self._required_boost_components)
if self.dependencies["boost"].options.header_only or miss_boost_required_comp:
raise ConanInvalidConfiguration(
"{0} requires non header-only boost with these components: {1}".format(
self.name, ", ".join(self._required_boost_components)
)
f"{self.ref} requires non header-only boost with these components: "
f"{', '.join(self._required_boost_components)}"
)

if self.options.with_TBB and not self.options["onetbb"].tbbmalloc:
if self.options.with_TBB and not self.dependencies["onetbb"].options.tbbmalloc:
raise ConanInvalidConfiguration("gtsam with tbb requires onetbb:tbbmalloc=True")

if is_msvc(self) and tools.Version(self.settings.compiler.version) < 15:
raise ConanInvalidConfiguration ("GTSAM requires MSVC >= 15")
check_min_vs(self, "191")

if is_msvc(self) and tools.Version(self.version) >= '4.1' \
and self.options.shared:
raise ConanInvalidConfiguration("GTSAM does not support shared builds on MSVC. see https://github.com/borglab/gtsam/issues/1087")
if Version(self.version) >= "4.1.0" and is_msvc(self) and self.options.shared:
raise ConanInvalidConfiguration(
f"{self.ref} does not support shared builds with MSVC. See https://github.com/borglab/gtsam/issues/1087"
)

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.variables["BUILD_SHARED_LIBS"] = self.options.shared
tc.variables["GTSAM_USE_QUATERNIONS"] = self.options.use_quaternions
tc.variables["GTSAM_POSE3_EXPMAP"] = self.options.pose3_expmap
tc.variables["GTSAM_ROT3_EXPMAP"] = self.options.rot3_expmap
tc.variables["GTSAM_ENABLE_CONSISTENCY_CHECKS"] = self.options.enable_consistency_checks
tc.variables["GTSAM_WITH_TBB"] = self.options.with_TBB
tc.variables["GTSAM_WITH_EIGEN_MKL"] = self.options.with_eigen_MKL
tc.variables["GTSAM_WITH_EIGEN_MKL_OPENMP"] = self.options.with_eigen_MKL_OPENMP
tc.variables["GTSAM_THROW_CHEIRALITY_EXCEPTION"] = self.options.throw_cheirality_exception
tc.variables["GTSAM_ALLOW_DEPRECATED_SINCE_V4"] = self.options.allow_deprecated_since_V4
tc.variables["GTSAM_TYPEDEF_POINTS_TO_VECTORS"] = self.options.typedef_points_to_vectors
tc.variables["GTSAM_SUPPORT_NESTED_DISSECTION"] = self.options.support_nested_dissection
tc.variables["GTSAM_TANGENT_PREINTEGRATION"] = self.options.tangent_preintegration
tc.variables["GTSAM_BUILD_WITH_CCACHE"] = False
tc.variables["GTSAM_BUILD_UNSTABLE"] = self.options.build_unstable
tc.variables["GTSAM_DISABLE_NEW_TIMERS"] = self.options.disable_new_timers
tc.variables["GTSAM_BUILD_TYPE_POSTFIXES"] = self.options.build_type_postfixes
tc.variables["GTSAM_BUILD_TESTS"] = False
tc.variables["Boost_USE_STATIC_LIBS"] = not self.dependencies["boost"].options.shared
tc.variables["Boost_NO_SYSTEM_PATHS"] = True
tc.variables["GTSAM_BUILD_DOCS"] = False
tc.variables["GTSAM_BUILD_DOC_HTML"] = False
tc.variables["GTSAM_BUILD_EXAMPLES_ALWAYS"] = False
tc.variables["GTSAM_BUILD_WRAP"] = self.options.build_wrap
tc.variables["GTSAM_BUILD_WITH_MARCH_NATIVE"] = False
tc.variables["GTSAM_WRAP_SERIALIZATION"] = self.options.wrap_serialization
tc.variables["GTSAM_INSTALL_MATLAB_TOOLBOX"] = self.options.install_matlab_toolbox
tc.variables["GTSAM_INSTALL_CYTHON_TOOLBOX"] = self.options.install_cython_toolbox
tc.variables["GTSAM_INSTALL_CPPUNITLITE"] = self.options.install_cppunitlite
tc.variables["GTSAM_INSTALL_GEOGRAPHICLIB"] = False
tc.variables["GTSAM_USE_SYSTEM_EIGEN"] = True
tc.variables["GTSAM_BUILD_TYPE_POSTFIXES"] = False
tc.generate()
deps = CMakeDeps(self)
deps.generate()

def _patch_sources(self):
for patch in self.conan_data.get("patches", {}).get(self.version, []):
tools.patch(**patch)
apply_conandata_patches(self)
# Honor vc runtime
if is_msvc(self):
tools.replace_in_file(os.path.join(self._source_subfolder, "cmake", "GtsamBuildTypes.cmake"),
"/MD ",
"/{} ".format(msvc_runtime_flag(self)))
tools.replace_in_file(os.path.join(self._source_subfolder, "cmake", "GtsamBuildTypes.cmake"),
"/MDd ",
"/{} ".format(msvc_runtime_flag(self)))

def _configure_cmake(self):
if self._cmake:
return self._cmake
self._cmake = CMake(self)
self._cmake.definitions["BUILD_SHARED_LIBS"] = self.options.shared
self._cmake.definitions["GTSAM_USE_QUATERNIONS"] = self.options.use_quaternions
self._cmake.definitions["GTSAM_POSE3_EXPMAP"] = self.options.pose3_expmap
self._cmake.definitions["GTSAM_ROT3_EXPMAP"] = self.options.rot3_expmap
self._cmake.definitions["GTSAM_ENABLE_CONSISTENCY_CHECKS"] = self.options.enable_consistency_checks
self._cmake.definitions["GTSAM_WITH_TBB"] = self.options.with_TBB
self._cmake.definitions["GTSAM_WITH_EIGEN_MKL"] = self.options.with_eigen_MKL
self._cmake.definitions["GTSAM_WITH_EIGEN_MKL_OPENMP"] = self.options.with_eigen_MKL_OPENMP
self._cmake.definitions["GTSAM_THROW_CHEIRALITY_EXCEPTION"] = self.options.throw_cheirality_exception
self._cmake.definitions["GTSAM_ALLOW_DEPRECATED_SINCE_V4"] = self.options.allow_deprecated_since_V4
self._cmake.definitions["GTSAM_TYPEDEF_POINTS_TO_VECTORS"] = self.options.typedef_points_to_vectors
self._cmake.definitions["GTSAM_SUPPORT_NESTED_DISSECTION"] = self.options.support_nested_dissection
self._cmake.definitions["GTSAM_TANGENT_PREINTEGRATION"] = self.options.tangent_preintegration
self._cmake.definitions["GTSAM_BUILD_UNSTABLE"] = self.options.build_unstable
self._cmake.definitions["GTSAM_DISABLE_NEW_TIMERS"] = self.options.disable_new_timers
self._cmake.definitions["GTSAM_BUILD_TYPE_POSTFIXES"] = self.options.build_type_postfixes
self._cmake.definitions["GTSAM_BUILD_TESTS"] = False
self._cmake.definitions["Boost_USE_STATIC_LIBS"] = not self.options["boost"].shared
self._cmake.definitions["Boost_NO_SYSTEM_PATHS"] = True
self._cmake.definitions["GTSAM_BUILD_DOCS"] = False
self._cmake.definitions["GTSAM_BUILD_DOC_HTML"] = False
self._cmake.definitions["GTSAM_BUILD_EXAMPLES_ALWAYS"] = False
self._cmake.definitions["GTSAM_BUILD_WRAP"] = self.options.build_wrap
self._cmake.definitions["GTSAM_BUILD_WITH_MARCH_NATIVE"] = False
self._cmake.definitions["GTSAM_WRAP_SERIALIZATION"] = self.options.wrap_serialization
self._cmake.definitions["GTSAM_INSTALL_MATLAB_TOOLBOX"] = self.options.install_matlab_toolbox
self._cmake.definitions["GTSAM_INSTALL_CYTHON_TOOLBOX"] = self.options.install_cython_toolbox
self._cmake.definitions["GTSAM_INSTALL_CPPUNITLITE"] = self.options.install_cppunitlite
self._cmake.definitions["GTSAM_INSTALL_GEOGRAPHICLIB"] = False
self._cmake.definitions["GTSAM_USE_SYSTEM_EIGEN"] = True #Set to false to use eigen sources contained in GTSAM
self._cmake.definitions["GTSAM_BUILD_TYPE_POSTFIXES"] = False
self._cmake.configure(build_folder=self._build_subfolder)
return self._cmake
gtsam_build_types_cmake = os.path.join(self.source_folder, "cmake", "GtsamBuildTypes.cmake")
replace_in_file(self, gtsam_build_types_cmake, "/MD ", f"/{msvc_runtime_flag(self)} ")
replace_in_file(self, gtsam_build_types_cmake, "/MDd ", f"/{msvc_runtime_flag(self)} ")

def build(self):
self._patch_sources()
cmake = self._configure_cmake()
cmake = CMake(self)
cmake.configure()
cmake.build()

def package(self):
cmake = self._configure_cmake()
copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
copy(self, "LICENSE.BSD", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses"))
cmake = CMake(self)
cmake.install()
self.copy("LICENSE", src=self._source_subfolder, dst="licenses")
self.copy("LICENSE.BSD", src=self._source_subfolder, dst="licenses")
tools.rmdir(os.path.join(self.package_folder, "lib", "cmake"))
tools.rmdir(os.path.join(self.package_folder, "CMake"))
rmdir(self, os.path.join(self.package_folder, "lib", "cmake"))
rmdir(self, os.path.join(self.package_folder, "CMake"))

# TODO: to remove in conan v2 once cmake_find_package* generators removed
self._create_cmake_module_alias_targets(
Expand All @@ -198,41 +188,40 @@ def package(self):
}
)

@staticmethod
def _create_cmake_module_alias_targets(module_file, targets):
def _create_cmake_module_alias_targets(self, module_file, targets):
content = ""
for alias, aliased in targets.items():
content += textwrap.dedent("""\
content += textwrap.dedent(f"""\
if(TARGET {aliased} AND NOT TARGET {alias})
add_library({alias} INTERFACE IMPORTED)
set_property(TARGET {alias} PROPERTY INTERFACE_LINK_LIBRARIES {aliased})
endif()
""".format(alias=alias, aliased=aliased))
tools.save(module_file, content)
""")
save(self, module_file, content)

@property
def _module_file_rel_path(self):
return os.path.join("lib", "cmake", "conan-official-{}-targets.cmake".format(self.name))
return os.path.join("lib", "cmake", f"conan-official-{self.name}-targets.cmake")

def package_info(self):
self.cpp_info.set_property("cmake_file_name", "GTSAM")

prefix = "lib" if is_msvc(self) and not self.options.shared else ""

self.cpp_info.components["libgtsam"].set_property("cmake_target_name", "gtsam")
self.cpp_info.components["libgtsam"].libs = ["{}gtsam".format(prefix)]
self.cpp_info.components["libgtsam"].requires = ["boost::{}".format(component) for component in self._required_boost_components]
self.cpp_info.components["libgtsam"].libs = [f"{prefix}gtsam"]
self.cpp_info.components["libgtsam"].requires = [f"boost::{component}" for component in self._required_boost_components]
self.cpp_info.components["libgtsam"].requires.append("eigen::eigen")
if self.options.with_TBB:
self.cpp_info.components["libgtsam"].requires.append("onetbb::onetbb")
if self.options.support_nested_dissection:
self.cpp_info.components["libgtsam"].requires.append("libmetis-gtsam")
if self.settings.os == "Windows" and tools.Version(self.version) >= "4.0.3":
if self.settings.os == "Windows" and Version(self.version) >= "4.0.3":
self.cpp_info.components["libgtsam"].system_libs = ["dbghelp"]

if self.options.build_unstable:
self.cpp_info.components["libgtsam_unstable"].set_property("cmake_target_name", "gtsam_unstable")
self.cpp_info.components["libgtsam_unstable"].libs = ["{}gtsam_unstable".format(prefix)]
self.cpp_info.components["libgtsam_unstable"].libs = [f"{prefix}gtsam_unstable"]
self.cpp_info.components["libgtsam_unstable"].requires = ["libgtsam"]

if self.options.support_nested_dissection:
Expand Down
Loading