conanfile.py (326 lines of code) (raw):

# Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. from conan import ConanFile, conan_version from conan.errors import ConanInvalidConfiguration from conan.tools.cmake import CMake, CMakeDeps, CMakeToolchain from conan.tools.scm import Version from conan.tools.files import copy import os required_conan_version = ">=1.32.0" class CelixConan(ConanFile): name = "celix" version = "3.0.0" homepage = "https://celix.apache.org" url = "https://github.com/apache/celix.git" topics = ("conan", "celix", "osgi", "embedded", "linux", "C/C++") exports_sources = ("CMakeLists.txt", "bundles*", "cmake*", "!cmake-build*", "examples*", "libs*", "misc*", "LICENSE", "!examples/conan_test_package*") generators = "CMakeDeps", "VirtualRunEnv" settings = "os", "arch", "compiler", "build_type" license = " Apache-2.0" description = "Apache Celix is an implementation of the OSGi specification adapted to C and C++ (C++14). " \ "It is a framework to develop (dynamic) modular software applications " \ "using component and/or service-oriented programming." _celix_defaults = { "enable_testing": False, "enable_code_coverage": False, "enable_address_sanitizer": False, "enable_undefined_sanitizer": False, "enable_thread_sanitizer": False, "install_find_modules": False, "build_all": False, "build_http_admin": False, "build_log_service": False, "build_log_helper": False, "build_log_service_api": False, "build_syslog_writer": False, "build_cxx_remote_service_admin": False, "build_cxx_rsa_integration": False, "build_remote_service_admin": False, "build_rsa_remote_service_admin_dfi": False, "build_rsa_discovery_common": False, "build_rsa_discovery_configured": False, "build_rsa_discovery_etcd": False, "build_rsa_remote_service_admin_shm_v2": False, "build_rsa_json_rpc": False, "build_rsa_discovery_zeroconf": False, "build_shell": False, "build_shell_api": False, "build_remote_shell": False, "build_shell_tui": False, "build_shell_wui": False, "build_components_ready_check": False, "build_examples": False, "build_celix_etcdlib": False, "build_launcher": False, "build_promises": False, "build_pushstreams": False, "build_experimental": False, "build_celix_dfi": False, "build_framework": False, "build_rcm": False, "build_utils": False, "build_event_admin": False, "build_event_admin_examples": False, "build_event_admin_remote_provider_mqtt": False, "celix_cxx14": True, "celix_cxx17": True, "celix_install_deprecated_api": False, "celix_use_compression_for_bundle_zips": True, "enable_cmake_warning_tests": False, "enable_testing_on_ci": False, "framework_curlinit": True, "enable_ccache": False, "enable_deprecated_warnings": False, } options = { "celix_err_buffer_size": ["ANY"], "celix_utils_max_strlen": ["ANY"], "celix_properties_optimization_string_buffer_size": ["ANY"], "celix_properties_optimization_entries_buffer_size": ["ANY"], } default_options = { "celix_err_buffer_size": "512", "celix_utils_max_strlen": "1073741824", "celix_properties_optimization_string_buffer_size": "128", "celix_properties_optimization_entries_buffer_size": "16", } for comp in _celix_defaults.keys(): options[comp] = [True, False] del comp _cmake = None def validate_config_option_is_positive_number(self, option): try: val = int(self.options.get_safe(option)) if val <= 0: raise ValueError except ValueError: raise ConanInvalidConfiguration("{} must be a positive number".format(option)) def validate(self): if self.settings.os != "Linux" and self.settings.os != "Macos": raise ConanInvalidConfiguration("Celix is only supported for Linux/Macos") if self.options.build_rsa_remote_service_admin_shm_v2 and self.settings.os != "Linux": raise ConanInvalidConfiguration("Celix build_rsa_remote_service_admin_shm_v2 is only supported for Linux") if self.options.build_rsa_discovery_zeroconf and self.settings.os != "Linux": raise ConanInvalidConfiguration("Celix build_rsa_discovery_zeroconf is only supported for Linux") self.validate_config_option_is_positive_number("celix_err_buffer_size") self.validate_config_option_is_positive_number("celix_utils_max_strlen") self.validate_config_option_is_positive_number("celix_properties_optimization_string_buffer_size") self.validate_config_option_is_positive_number("celix_properties_optimization_entries_buffer_size") def package_id(self): del self.info.options.build_all # the followings are not installed del self.info.options.build_cxx_rsa_integration del self.info.options.build_examples del self.info.options.build_event_admin_examples del self.info.options.enable_cmake_warning_tests del self.info.options.enable_testing_on_ci del self.info.options.enable_ccache del self.info.options.enable_deprecated_warnings def build_requirements(self): if self.options.enable_testing: self.test_requires("gtest/1.10.0") if self.options.enable_ccache: self.build_requires("ccache/4.7.4") def configure(self): # copy options to options, fill in defaults if not set options = {} for opt in self._celix_defaults.keys(): options[opt] = self.options.get_safe(opt).value if options[opt] is None: options[opt] = self._celix_defaults[opt] if options["build_all"]: for opt in options.keys(): if opt.startswith('build_'): options[opt] = True if options["build_event_admin_examples"]: options["build_event_admin"] = True options["build_log_service"] = True options["build_shell_tui"] = True options["build_launcher"] = True options["build_event_admin_remote_provider_mqtt"] = True options["build_rsa_discovery_zeroconf"] = True if self.settings.os != "Linux": options["build_rsa_remote_service_admin_shm_v2"] = False options["build_rsa_discovery_zeroconf"] = False if options["enable_code_coverage"]: options["enable_testing"] = True if options["build_examples"]: options["build_shell_tui"] = True options["build_shell_wui"] = True options["build_log_service"] = True options["build_syslog_writer"] = True if options["build_event_admin_remote_provider_mqtt"]: options["build_event_admin"] = True options["build_remote_service_admin"] = True options["build_shell_api"] = True if options["build_cxx_rsa_integration"]: options["build_cxx_remote_service_admin"] = True options["build_pushstreams"] = True options["build_promises"] = True options["build_log_helper"] = True options["build_shell"] = True options["build_shell_tui"] = True options["build_shell_api"] = True if options["build_cxx_remote_service_admin"]: options["build_framework"] = True options["build_log_helper"] = True options["celix_cxx17"] = True if options["build_rsa_discovery_etcd"]: options["build_celix_etcdlib"] = True options["build_rsa_discovery_common"] = True if options["build_rsa_discovery_configured"]: options["build_rsa_discovery_common"] = True if options["build_rsa_discovery_common"] or options["build_rsa_discovery_zeroconf"] \ or options["build_rsa_remote_service_admin_dfi"] or options["build_rsa_json_rpc"] \ or options["build_rsa_remote_service_admin_shm_v2"]: options["build_remote_service_admin"] = True if options["build_remote_service_admin"]: options["build_framework"] = True options["build_log_helper"] = True options["build_celix_dfi"] = True options["celix_install_deprecated_api"] = True if options["build_event_admin"]: options["build_framework"] = True options["build_log_helper"] = True if options["build_remote_shell"]: options["build_shell"] = True if options["build_shell_wui"]: options["build_shell"] = True options["build_http_admin"] = True if options["build_shell_tui"]: options["build_shell"] = True if options["build_shell"]: options["build_shell_api"] = True options["build_log_helper"] = True options["build_framework"] = True if options["build_http_admin"]: options["build_framework"] = True if options["build_syslog_writer"]: options["build_log_service"] = True if options["build_log_service"]: options["build_log_service_api"] = True options["build_shell_api"] = True options["build_framework"] = True options["build_log_helper"] = True if options["build_shell_api"]: options["build_utils"] = True if options["build_log_helper"]: options["build_log_service_api"] = True options["build_framework"] = True if options["build_log_service_api"]: options["build_utils"] = True if options["celix_install_deprecated_api"]: options["build_framework"] = True if options["build_components_ready_check"]: options["build_framework"] = True if options["build_rcm"]: options["build_utils"] = True if options["build_launcher"]: options["build_framework"] = True if options["build_celix_dfi"]: options["build_utils"] = True if options["build_framework"]: options["build_utils"] = True if options["build_pushstreams"]: options["build_promises"] = True if options["build_promises"]: options["celix_cxx17"] = True if options["celix_cxx17"]: options["celix_cxx14"] = True for opt in self._celix_defaults.keys(): setattr(self.options, opt, options[opt]) del options # Conan 2 does not support set dependency option in requirements() # https://github.com/conan-io/conan/issues/14528#issuecomment-1685344080 if self.options.build_utils: self.options['libzip'].shared = True if self.options.build_framework: self.options['util-linux-libuuid'].shared = True if ((self.options.build_framework and self.options.framework_curlinit) or self.options.build_celix_etcdlib or self.options.build_rsa_discovery_common or self.options.build_rsa_remote_service_admin_dfi or self.options.build_launcher): self.options['libcurl'].shared = True self.options['openssl'].shared = True if self.options.enable_testing: self.options['gtest'].shared = True if (self.options.build_rsa_discovery_common or (self.options.build_rsa_remote_service_admin_dfi and self.options.enable_testing)): self.options['libxml2'].shared = True if self.options.build_http_admin or self.options.build_rsa_discovery_common \ or self.options.build_rsa_remote_service_admin_dfi: self.options['civetweb'].shared = True self.options['openssl'].shared = True if self.options.build_celix_dfi: self.options['libffi'].shared = True if self.options.build_utils or self.options.build_celix_dfi or self.options.build_celix_etcdlib or self.options.build_event_admin_remote_provider_mqtt: self.options['jansson'].shared = True if self.options.build_event_admin_remote_provider_mqtt: self.options['mosquitto'].shared = True if self.options.enable_testing: self.options['mosquitto'].broker = True def requirements(self): if self.options.build_utils: self.requires("libzip/[>=1.7.3 <2.0.0]") if self.options.build_framework: self.requires("util-linux-libuuid/[>=2.39 <3.0.0]") if ((self.options.build_framework and self.options.framework_curlinit) or self.options.build_celix_etcdlib or self.options.build_rsa_discovery_common or self.options.build_rsa_remote_service_admin_dfi or self.options.build_launcher): self.requires("libcurl/[>=8.4.0 <9.0.0]") if (self.options.build_rsa_discovery_common or (self.options.build_rsa_remote_service_admin_dfi and self.options.enable_testing)): self.requires("libxml2/[>=2.9.9 <3.0.0]") if self.options.build_cxx_remote_service_admin: self.requires("rapidjson/[>=1.1.0 <2.0.0]") if self.options.build_http_admin or self.options.build_rsa_discovery_common \ or self.options.build_rsa_remote_service_admin_dfi: self.requires("civetweb/1.16") if self.options.build_celix_dfi: self.requires("libffi/[>=3.2.1 <4.0.0]") if self.options.build_utils or self.options.build_celix_dfi or self.options.build_celix_etcdlib or self.options.build_event_admin_remote_provider_mqtt: self.requires("jansson/[>=2.12 <3.0.0]") if self.options.build_rsa_discovery_zeroconf: # TODO: To be replaced with mdnsresponder/1790.80.10, resolve some problems of mdnsresponder # https://github.com/conan-io/conan-center-index/pull/16254 self.requires("mdnsresponder/1310.140.1") # 'libzip/1.10.1' requires 'zlib/1.2.13' while 'libcurl/7.64.1' requires 'zlib/1.2.12' self.requires("openssl/[>=3.2.0]", override=True) self.requires("zlib/1.2.13", override=True) if self.options.build_event_admin_remote_provider_mqtt: self.requires("mosquitto/[>=2.0.3 <3.0.0]") self.validate() def generate(self): tc = CMakeToolchain(self) for opt in self._celix_defaults.keys(): tc.cache_variables[opt.upper()] = self.options.get_safe(opt) if self.options.enable_testing: lst = [x.ref.name for x in self.requires.values()] if "mdnsresponder" in lst: tc.cache_variables["BUILD_ERROR_INJECTOR_MDNSRESPONDER"] = "ON" if "jansson" in lst: tc.cache_variables["BUILD_ERROR_INJECTOR_JANSSON"] = "ON" if "mosquitto" in lst: tc.cache_variables["BUILD_ERROR_INJECTOR_MOSQUITTO"] = "ON" tc.cache_variables["CELIX_ERR_BUFFER_SIZE"] = str(self.options.celix_err_buffer_size) # tc.cache_variables["CMAKE_PROJECT_Celix_INCLUDE"] = os.path.join(self.build_folder, "conan_paths.cmake") # the following is workaround for https://github.com/conan-io/conan/issues/7192 if self.settings.os == "Linux": tc.cache_variables["CMAKE_EXE_LINKER_FLAGS"] = "-Wl,--unresolved-symbols=ignore-in-shared-libs" elif self.settings.os == "Macos": tc.cache_variables["CMAKE_EXE_LINKER_FLAGS"] = "-Wl,-undefined -Wl,dynamic_lookup" v = Version(self.version) tc.cache_variables["CELIX_MAJOR"] = str(v.major.value) tc.cache_variables["CELIX_MINOR"] = str(v.minor.value) tc.cache_variables["CELIX_MICRO"] = str(v.patch.value) tc.generate() def _configure_cmake(self): if self._cmake: return self._cmake self._cmake = CMake(self) self._cmake.configure() return self._cmake def build(self): # self._patch_sources() cmake = self._configure_cmake() cmake.build() def package(self): copy(self, "LICENSE", src=self.source_folder, dst=os.path.join(self.package_folder, "licenses")) cmake = self._configure_cmake() cmake.install() def package_info(self): # enable imports() of conanfile.py to collect bundles from the local cache using @bindirs # check https://docs.conan.io/en/latest/reference/conanfile/methods.html#imports self.cpp_info.bindirs = ["bin", os.path.join("share", self.name, "bundles")] self.cpp_info.build_modules["cmake"].append(os.path.join("lib", "cmake", "Celix", "CelixConfig.cmake")) self.cpp_info.build_modules["cmake_find_package"].append(os.path.join("lib", "cmake", "Celix", "CelixConfig.cmake")) self.cpp_info.set_property("cmake_build_modules", [os.path.join("lib", "cmake", "Celix", "CelixConfig.cmake")])