diff --git a/recipes/mavlink/all/conandata.yml b/recipes/mavlink/all/conandata.yml new file mode 100644 index 0000000000000..35aa9850e002b --- /dev/null +++ b/recipes/mavlink/all/conandata.yml @@ -0,0 +1,15 @@ +sources: + "1.0.12.cci.20241205": + mavlink: + url: "https://github.com/mavlink/mavlink/archive/35f70c4a7e0c4aa91edc1eaa5205a1077490442c.tar.gz" + sha256: "be2e9583bc72cc894056b903578879128fe8c68a92fbcbb3268ab92c78c7ddef" + pymavlink: + url: "https://github.com/ArduPilot/pymavlink/archive/refs/tags/v2.4.42.tar.gz" + sha256: "bbe1b78759211597c98214e31b6dfc9cc42b3cb4548c813674463cb664b56a9f" + "1.0.12.cci.20240530": + mavlink: + url: "https://github.com/mavlink/mavlink/archive/f1d42e2774cae767a1c0651b0f95e3286c587257.tar.gz" + sha256: "3eb515843143fd9b1e275141c4c82f5f3cbbb77c12e1eb2b929a6a005f016a51" + pymavlink: + url: "https://github.com/ArduPilot/pymavlink/archive/refs/tags/v2.4.42.tar.gz" + sha256: "bbe1b78759211597c98214e31b6dfc9cc42b3cb4548c813674463cb664b56a9f" diff --git a/recipes/mavlink/all/conanfile.py b/recipes/mavlink/all/conanfile.py new file mode 100644 index 0000000000000..f8fe7352ea624 --- /dev/null +++ b/recipes/mavlink/all/conanfile.py @@ -0,0 +1,97 @@ +import os + +from conan import ConanFile +from conan.tools.cmake import cmake_layout +from conan.tools.env import Environment +from conan.tools.files import copy, get + +required_conan_version = ">=2.4" + + +class MavlinkConan(ConanFile): + name = "mavlink" + description = "Marshalling / communication library for drones." + license = "MIT" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://github.com/mavlink/mavlink" + topics = ("mav", "drones", "marshalling", "communication") + package_type = "header-library" + settings = "os", "arch", "compiler", "build_type" + options = { + # https://mavlink.io/en/messages/README.html + "dialect": [ + "all", + "common", + "standard", + "minimal", + "development", + "ardupilotmega", + "ASLUAV", + "AVSSUAS", + "csAirLink", + "cubepilot", + "icarous", + "loweheiser", + "matrixpilot", + "paparazzi", + "storm32", + "ualberta", + "uAvionix", + ], + # https://github.com/ArduPilot/pymavlink/blob/v2.4.42/tools/mavgen.py#L24 + "wire_protocol": ["0.9", "1.0", "2.0"], + } + default_options = { + "dialect": "common", + "wire_protocol": "2.0", + } + languages = ["C"] + + def layout(self): + cmake_layout(self, src_folder="src") + + def package_id(self): + self.info.settings.clear() + + def build_requirements(self): + self.tool_requires("cpython/[>=3.12 <4]") + + def source(self): + info = self.conan_data["sources"][self.version] + get(self, **info["mavlink"], strip_root=True) + get(self, **info["pymavlink"], strip_root=True, destination="pymavlink") + + def generate(self): + # To install pyelftools + env = Environment() + env.append_path("PYTHONPATH", self._site_packages_dir) + env.append_path("PATH", os.path.join(self._site_packages_dir, "bin")) + env.vars(self).save_script("pythonpath") + + @property + def _site_packages_dir(self): + return os.path.join(self.build_folder, "site-packages") + + def _pip_install(self, packages): + self.run(f"python -m pip install {' '.join(packages)} --no-cache-dir --target={self._site_packages_dir}", + cwd=self.source_folder) + + def build(self): + # Reproduce these CMake steps https://github.com/mavlink/mavlink/blob/5e3a42b8f3f53038f2779f9f69bd64767b913bb8/CMakeLists.txt#L32-L39 + # for a tighter control over the created temporary Python environment. + self._pip_install(["-r", "pymavlink/requirements.txt"]) + self.run("python -m pymavlink.tools.mavgen --lang=C" + f" --wire-protocol={self.options.wire_protocol}" + f" --output {self.build_folder}/include/mavlink/" + f" message_definitions/v1.0/{self.options.dialect}.xml", + cwd=self.source_folder) + + def package(self): + copy(self, "COPYING", self.source_folder, os.path.join(self.package_folder, "licenses")) + copy(self, "*", os.path.join(self.build_folder, "include"), os.path.join(self.package_folder, "include")) + + def package_info(self): + self.cpp_info.set_property("cmake_file_name", "MAVLink") + self.cpp_info.set_property("cmake_target_name", "MAVLink::mavlink") + self.cpp_info.bindirs = [] + self.cpp_info.libdirs = [] diff --git a/recipes/mavlink/all/test_package/CMakeLists.txt b/recipes/mavlink/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..724efce77440b --- /dev/null +++ b/recipes/mavlink/all/test_package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package LANGUAGES C) + +find_package(MAVLink REQUIRED CONFIG) + +add_executable(${PROJECT_NAME} test_package.c) +target_link_libraries(${PROJECT_NAME} PRIVATE MAVLink::mavlink) diff --git a/recipes/mavlink/all/test_package/conanfile.py b/recipes/mavlink/all/test_package/conanfile.py new file mode 100644 index 0000000000000..2e77b4246fa81 --- /dev/null +++ b/recipes/mavlink/all/test_package/conanfile.py @@ -0,0 +1,25 @@ +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake +import os + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "CMakeToolchain" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires(self.tested_reference_str) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindir, "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/mavlink/all/test_package/config.yml b/recipes/mavlink/all/test_package/config.yml new file mode 100644 index 0000000000000..d07c95e596619 --- /dev/null +++ b/recipes/mavlink/all/test_package/config.yml @@ -0,0 +1,5 @@ +versions: + "1.2.0": + folder: all + "1.1.0": + folder: all diff --git a/recipes/mavlink/all/test_package/test_package.c b/recipes/mavlink/all/test_package/test_package.c new file mode 100644 index 0000000000000..5bf857c44d12b --- /dev/null +++ b/recipes/mavlink/all/test_package/test_package.c @@ -0,0 +1,7 @@ +#include + +#include + +int main() { + printf("Payload size for minimal dialect: %d bytes\n", MAVLINK_MAX_DIALECT_PAYLOAD_SIZE); +} diff --git a/recipes/mavlink/config.yml b/recipes/mavlink/config.yml new file mode 100644 index 0000000000000..446284f981c87 --- /dev/null +++ b/recipes/mavlink/config.yml @@ -0,0 +1,5 @@ +versions: + "1.0.12.cci.20241205": + folder: all + "1.0.12.cci.20240530": + folder: all diff --git a/recipes/mavsdk/all/conandata.yml b/recipes/mavsdk/all/conandata.yml new file mode 100644 index 0000000000000..2fef8822c6ddb --- /dev/null +++ b/recipes/mavsdk/all/conandata.yml @@ -0,0 +1,8 @@ +sources: + "2.13.0": + source: + url: "https://github.com/mavlink/MAVSDK/archive/refs/tags/v2.13.0.tar.gz" + sha256: "9af60e71d707b0ca412198dc14ab7e1b632dd7f4558c2f5e7cefc0a0354ce3a6" + proto: + url: "https://github.com/mavlink/MAVSDK-Proto/archive/34bce6d61dba5f72b602bdbd31f04fceff093881.tar.gz" + sha256: "1f441671dddf38fe5ef6a4d0aa73be5634437a4e6bd516348e7f6e344ed05356" diff --git a/recipes/mavsdk/all/conanfile.py b/recipes/mavsdk/all/conanfile.py new file mode 100644 index 0000000000000..ffaaf5d3dade6 --- /dev/null +++ b/recipes/mavsdk/all/conanfile.py @@ -0,0 +1,163 @@ +import os + +from conan import ConanFile +from conan.tools.build import check_min_cppstd +from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain, cmake_layout +from conan.tools.files import copy, get, rm, rmdir, replace_in_file +from conan.tools.microsoft import is_msvc +from conan.tools.scm import Version + +required_conan_version = ">=2.0.9" + + +class MavsdkConan(ConanFile): + name = "mavsdk" + description = "C++ library to interface with MAVLink systems" + license = "BSD-3-Clause" + url = "https://github.com/conan-io/conan-center-index" + homepage = "https://mavsdk.mavlink.io/" + topics = ("mavlink", "drones") + package_type = "library" + settings = "os", "arch", "compiler", "build_type" + options = { + "shared": [True, False], + "fPIC": [True, False], + "regenerate_protobuf": [True, False], + "build_server": [True, False], + "enable_reflection": [True, False], + } + default_options = { + "shared": False, + "fPIC": True, + "regenerate_protobuf": False, + "build_server": False, + "enable_reflection": False, + } + implements = ["auto_shared_fpic"] + + def configure(self): + if self.options.shared: + self.options.rm_rf("fPIC") + if self.options.build_server: + # The .proto files were processed with protobuf v4, which is not compatible with + # the gRPC protobuf version on CCI, so we need to regenerate them. + del self.options.regenerate_protobuf + else: + del self.options.enable_reflection + + def layout(self): + cmake_layout(self, src_folder="src") + + def requirements(self): + self.requires("mavlink/1.0.12.cci.20240530", transitive_headers=True) + self.requires("jsoncpp/1.9.6") + self.requires("tinyxml2/10.0.0") + self.requires("libcurl/[>=7.86 <9]") + self.requires("xz_utils/[>=5.4.5 <6]") + if self.options.build_server: + self.requires("grpc/1.67.1") + + def validate(self): + check_min_cppstd(self, 17) + + def build_requirements(self): + if self.options.get_safe("regenerate_protobuf", True): + if self.options.build_server: + self.tool_requires("grpc/") + self.tool_requires("protobuf/") + else: + self.tool_requires("grpc/1.67.1") + self.tool_requires("protobuf/5.27.0") + if self.settings_build.os == "Windows": + self.win_bash = True + if not self.conf.get("tools.microsoft.bash:path", check_type=str): + self.tool_requires("msys2/cci.latest") + + def source(self): + get(self, **self.conan_data["sources"][self.version]["source"], strip_root=True) + get(self, **self.conan_data["sources"][self.version]["proto"], strip_root=True, destination="proto") + # Let Conan handle the C++ standard + replace_in_file(self, os.path.join(self.source_folder, "src", "CMakeLists.txt"), + "set(CMAKE_CXX_STANDARD 17)", "") + # Fix version string for SOVERSION, since it cannot be derived from a git tag. + replace_in_file(self, os.path.join(self.source_folder, "CMakeLists.txt"), + 'set(VERSION_STR "0.0.0")', + f'set(VERSION_STR "v{self.version}")') + + def generate(self): + tc = CMakeToolchain(self) + if Version(self.version) <= "2.13.0": + tc.cache_variables["BUILD_TESTS"] = False + tc.cache_variables["BUILD_TESTING"] = False + tc.cache_variables["SUPERBUILD"] = False + tc.cache_variables["MAVLINK_DIALECT"] = self.dependencies["mavlink"].options.dialect + tc.cache_variables["BUILD_MAVSDK_SERVER"] = self.options.build_server + tc.cache_variables["BUILD_WITH_PROTO_REFLECTION"] = self.options.get_safe("enable_reflection", False) + # The project uses CMake policy version < 3.12 in several places + tc.cache_variables["CMAKE_POLICY_DEFAULT_CMP0077"] = "NEW" + tc.generate() + + deps = CMakeDeps(self) + deps.generate() + + def build(self): + if self.options.get_safe("regenerate_protobuf", True): + # No need to re-generate Jinja templates + replace_in_file(self, os.path.join(self.source_folder, "tools", "generate_from_protos.sh"), + "python3 ${script_dir}/grpc_server_jinja.py", + "# python3 ${script_dir}/grpc_server_jinja.py") + self.run(f"tools/generate_from_protos.sh -b {self.build_folder}", cwd=self.source_folder) + cmake = CMake(self) + cmake.configure() + cmake.build() + + def package(self): + copy(self, "LICENSE.md", self.source_folder, os.path.join(self.package_folder, "licenses")) + cmake = CMake(self) + cmake.install() + rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig")) + rmdir(self, os.path.join(self.package_folder, "lib", "cmake")) + rm(self, "*.pdb", self.package_folder, recursive=True) + + def package_info(self): + self.cpp_info.set_property("cmake_file_name", "MAVSDK") + + postfix = "" + if is_msvc(self) and self.settings.build_type == "Debug": + postfix = "d" + + mavsdk = self.cpp_info.components["mavsdk"] + mavsdk.set_property("cmake_target_name", "MAVSDK::mavsdk") + mavsdk.set_property("pkg_config_name", "mavsdk") + mavsdk.libs = ["mavsdk" + postfix] + mavsdk.includedirs.append(os.path.join("include", "mavsdk")) + if self.settings.os in ["Linux", "FreeBSD"]: + mavsdk.system_libs = ["m", "pthread", "dl"] + elif self.settings.os == "Windows": + mavsdk.system_libs = ["ws2_32"] + elif self.settings.os == "iOS": + mavsdk.frameworks = ["Foundation", "Security"] + elif self.settings.os == "Android": + mavsdk.system_libs = ["log"] + if str(self.settings.compiler.libcxx) in ["libstdc++", "libstdc++11"] or str(self.settings.arch).startswith("arm"): + mavsdk.system_libs.append("atomic") + mavsdk.requires = [ + "mavlink::mavlink", + "jsoncpp::jsoncpp", + "tinyxml2::tinyxml2", + "libcurl::libcurl", + "xz_utils::xz_utils", + ] + + if self.options.build_server: + mavsdk_server = self.cpp_info.components["mavsdk_server"] + mavsdk_server.set_property("cmake_target_name", "MAVSDK::mavsdk_server") + mavsdk_server.set_property("pkg_config_name", "mavsdk_server") + mavsdk_server.libs = ["mavsdk_server"] + if self.settings.os in ["Linux", "FreeBSD"]: + mavsdk_server.system_libs = ["dl"] + if str(self.settings.compiler.libcxx) in ["libstdc++", "libstdc++11"] or str(self.settings.arch).startswith("arm"): + mavsdk_server.system_libs.append("atomic") + mavsdk_server.requires = ["grpc::grpc++"] + if self.options.enable_reflection: + mavsdk_server.requires.append("grpc::grpc++_reflection") diff --git a/recipes/mavsdk/all/test_package/CMakeLists.txt b/recipes/mavsdk/all/test_package/CMakeLists.txt new file mode 100644 index 0000000000000..0f5a819a85079 --- /dev/null +++ b/recipes/mavsdk/all/test_package/CMakeLists.txt @@ -0,0 +1,7 @@ +cmake_minimum_required(VERSION 3.15) +project(test_package LANGUAGES CXX) + +find_package(MAVSDK REQUIRED CONFIG) + +add_executable(${PROJECT_NAME} test_package.cpp) +target_link_libraries(${PROJECT_NAME} PRIVATE MAVSDK::mavsdk) diff --git a/recipes/mavsdk/all/test_package/conanfile.py b/recipes/mavsdk/all/test_package/conanfile.py new file mode 100644 index 0000000000000..2e77b4246fa81 --- /dev/null +++ b/recipes/mavsdk/all/test_package/conanfile.py @@ -0,0 +1,25 @@ +from conan import ConanFile +from conan.tools.build import can_run +from conan.tools.cmake import cmake_layout, CMake +import os + + +class TestPackageConan(ConanFile): + settings = "os", "arch", "compiler", "build_type" + generators = "CMakeDeps", "CMakeToolchain" + + def layout(self): + cmake_layout(self) + + def requirements(self): + self.requires(self.tested_reference_str) + + def build(self): + cmake = CMake(self) + cmake.configure() + cmake.build() + + def test(self): + if can_run(self): + bin_path = os.path.join(self.cpp.build.bindir, "test_package") + self.run(bin_path, env="conanrun") diff --git a/recipes/mavsdk/all/test_package/config.yml b/recipes/mavsdk/all/test_package/config.yml new file mode 100644 index 0000000000000..d07c95e596619 --- /dev/null +++ b/recipes/mavsdk/all/test_package/config.yml @@ -0,0 +1,5 @@ +versions: + "1.2.0": + folder: all + "1.1.0": + folder: all diff --git a/recipes/mavsdk/all/test_package/test_package.cpp b/recipes/mavsdk/all/test_package/test_package.cpp new file mode 100644 index 0000000000000..af37ad988fbd2 --- /dev/null +++ b/recipes/mavsdk/all/test_package/test_package.cpp @@ -0,0 +1,10 @@ +#include +#include + +using namespace mavsdk; + +int main() +{ + Mavsdk mavsdk{Mavsdk::Configuration{1, 180, false}}; + std::cout << "MAVSDK version: " << mavsdk.version() << std::endl; +} diff --git a/recipes/mavsdk/config.yml b/recipes/mavsdk/config.yml new file mode 100644 index 0000000000000..319f45f887837 --- /dev/null +++ b/recipes/mavsdk/config.yml @@ -0,0 +1,3 @@ +versions: + "2.13.0": + folder: all