Repository: conan-io/conan-center-index

Issue:
[request] pagmo2/2.8 
### Package Details
  * Package Name/Version: **pagmo2/2.8**

The above mentioned version is an older version not yet available as a recipe. 
I need the old version because I am creating a conan recipe for dartsim 6.9.x (which is needed by Gazebo classic version 11.8.1), and pagmo2 is a dependency of dartsim. However the newer version causes problems as dartsim 6.9.x uses the c++14 standard, and the current version 2.17.0 uses c++17, causing dartsim to fail compiling.


Discussion:

Resolving patch:
diff --git a/recipes/pagmo2/pre_2.11/conanfile.py b/recipes/pagmo2/pre_2.11/conanfile.py
new file mode 100644
--- /dev/null
+++ b/recipes/pagmo2/pre_2.11/conanfile.py
@@ -0,0 +1,111 @@
+from conans import ConanFile, CMake, tools
+from conans.errors import ConanInvalidConfiguration
+import os
+
+required_conan_version = ">=1.43.0"
+
+
+class Pagmo2Conan(ConanFile):
+    name = "pagmo2"
+    description = "pagmo is a C++ scientific library for massively parallel optimization."
+    license = ("LGPL-3.0-or-later", "GPL-3.0-or-later")
+    topics = ("pagmo", "optimization", "parallel-computing", "genetic-algorithm", "metaheuristics")
+    homepage = "https://esa.github.io/pagmo2"
+    url = "https://github.com/conan-io/conan-center-index"
+
+    settings = "os", "arch", "compiler", "build_type"
+    options = {
+        "with_eigen": [True, False],
+        "with_nlopt": [True, False],
+        "with_ipopt": [True, False],
+    }
+    default_options = {
+        "with_eigen": False,
+        "with_nlopt": False,
+        "with_ipopt": False,
+    }
+
+    generators = "cmake", "cmake_find_package", "cmake_find_package_multi"
+    _cmake = None
+
+    @property
+    def _source_subfolder(self):
+        return "source_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"])
+
+    def requirements(self):
+        self.requires("boost/1.78.0")
+        self.requires("onetbb/2020.3")
+        if self.options.with_eigen:
+            self.requires("eigen/3.4.0")
+        if self.options.with_nlopt:
+            self.requires("nlopt/2.7.1")
+
+    @property
+    def _required_boost_components(self):
+        return ["serialization"]
+
+    def validate(self):
+        if self.settings.compiler.get_safe("cppstd"):
+            tools.check_min_cppstd(self, 11)
+        # TODO: add ipopt support
+        if self.options.with_ipopt:
+            raise ConanInvalidConfiguration("ipopt recipe not available yet in CCI")
+
+        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:
+            raise ConanInvalidConfiguration("{0} requires non header-only boost with these components: {1}".format(self.name, ", ".join(self._required_boost_components)))
+
+    def package_id(self):
+        self.info.header_only()
+
+    def source(self):
+        tools.get(**self.conan_data["sources"][self.version],
+                  destination=self._source_subfolder, strip_root=True)
+
+    def _configure_cmake(self):
+        if self._cmake:
+            return self._cmake
+        self._cmake = CMake(self)
+        self._cmake.definitions["PAGMO_BUILD_TESTS"] = False
+        self._cmake.definitions["PAGMO_BUILD_TUTORIALS"] = False
+        self._cmake.definitions["PAGMO_WITH_EIGEN3"] = self.options.with_eigen
+        self._cmake.definitions["PAGMO_WITH_NLOPT"] = self.options.with_nlopt
+        self._cmake.definitions["PAGMO_WITH_IPOPT"] = self.options.with_ipopt
+        self._cmake.configure()
+        return self._cmake
+
+    def build(self):
+        for patch in self.conan_data.get("patches", {}).get(self.version, []):
+            tools.patch(**patch)
+
+    def package(self):
+        self.copy(pattern="COPYING.*", dst="licenses", src=self._source_subfolder)
+        cmake = self._configure_cmake()
+        cmake.install()
+        tools.rmdir(os.path.join(self.package_folder, "lib", "cmake"))
+
+    def package_info(self):
+        self.cpp_info.set_property("cmake_file_name", "pagmo")
+        self.cpp_info.set_property("cmake_target_name", "Pagmo::pagmo")
+        # TODO: back to global scope in conan v2 once cmake_find_package_* generators removed
+        self.cpp_info.components["_pagmo"].requires = ["boost::headers", "boost::serialization", "onetbb::onetbb"]
+        if self.options.with_eigen:
+            self.cpp_info.components["_pagmo"].requires.append("eigen::eigen")
+        if self.options.with_nlopt:
+            self.cpp_info.components["_pagmo"].requires.append("nlopt::nlopt")
+        if self.settings.os in ["Linux", "FreeBSD"]:
+            self.cpp_info.components["_pagmo"].system_libs.append("pthread")
+
+        # TODO: to remove in conan v2 once cmake_find_package_* generators removed
+        self.cpp_info.filenames["cmake_find_package"] = "pagmo"
+        self.cpp_info.filenames["cmake_find_package_multi"] = "pagmo"
+        self.cpp_info.names["cmake_find_package"] = "Pagmo"
+        self.cpp_info.names["cmake_find_package_multi"] = "Pagmo"
+        self.cpp_info.components["_pagmo"].names["cmake_find_package"] = "pagmo"
+        self.cpp_info.components["_pagmo"].names["cmake_find_package_multi"] = "pagmo"
+        self.cpp_info.components["_pagmo"].set_property("cmake_target_name", "Pagmo::pagmo")


Test patch:
diff --git a/recipes/pagmo2/pre_2.11/test_package/CMakeLists.txt b/recipes/pagmo2/pre_2.11/test_package/CMakeLists.txt
new file mode 100644
--- /dev/null
+++ b/recipes/pagmo2/pre_2.11/test_package/CMakeLists.txt
@@ -0,0 +1,11 @@
+cmake_minimum_required(VERSION 3.8)
+project(test_package)
+
+include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
+conan_basic_setup(TARGETS)
+
+find_package(pagmo REQUIRED CONFIG)
+
+add_executable(${PROJECT_NAME} test_package.cpp)
+target_link_libraries(${PROJECT_NAME} Pagmo::pagmo)
+target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_11)
diff --git a/recipes/pagmo2/pre_2.11/test_package/conanfile.py b/recipes/pagmo2/pre_2.11/test_package/conanfile.py
new file mode 100644
--- /dev/null
+++ b/recipes/pagmo2/pre_2.11/test_package/conanfile.py
@@ -0,0 +1,17 @@
+from conans import ConanFile, CMake, tools
+import os
+
+
+class TestPackageConan(ConanFile):
+    settings = "os", "arch", "compiler", "build_type"
+    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/pagmo2/pre_2.11/test_package/test_package.cpp b/recipes/pagmo2/pre_2.11/test_package/test_package.cpp
new file mode 100644
--- /dev/null
+++ b/recipes/pagmo2/pre_2.11/test_package/test_package.cpp
@@ -0,0 +1,42 @@
+// From first_udp_ver0.cpp in tutorials of pagmo2
+
+#include <pagmo/problem.hpp>
+#include <pagmo/types.hpp>
+
+#include <cmath>
+#include <initializer_list>
+#include <iostream>
+#include <utility>
+
+// Our simple example problem, version 0.
+struct problem_v0 {
+    // Implementation of the objective function.
+    pagmo::vector_double fitness(const pagmo::vector_double &dv) const
+    {
+        return {dv[0] * dv[3] * (dv[0] + dv[1] + dv[2]) + dv[2]};
+    }
+    // Implementation of the box bounds.
+    std::pair<pagmo::vector_double, pagmo::vector_double> get_bounds() const
+    {
+        return {{1., 1., 1., 1.}, {5., 5., 5., 5.}};
+    }
+};
+
+int main()
+{
+    // Construct a pagmo::problem from our example problem.
+    pagmo::problem p{problem_v0{}};
+
+    // Getting its dimensions
+    std::cout << "Calling the dimension getter: " << p.get_nx() << '\n';
+    std::cout << "Calling the fitness dimension getter: " << p.get_nobj() << '\n';
+
+    // Compute the value of the objective function
+    // in the point (1, 2, 3, 4).
+    std::cout << "Value of the objfun in (1, 2, 3, 4): " << p.fitness({1, 2, 3, 4})[0] << '\n';
+
+    // Print p to screen.
+    std::cout << p << "\n";
+
+    return 0;
+}