diff --git a/recipes/protobuf/all/conandata.yml b/recipes/protobuf/all/conandata.yml index a8f3b51f97dbe..bdae9c9d92a56 100644 --- a/recipes/protobuf/all/conandata.yml +++ b/recipes/protobuf/all/conandata.yml @@ -1,21 +1,21 @@ sources: - 3.9.1: + "3.9.1": sha256: 98e615d592d237f94db8bf033fba78cd404d979b0b70351a9e5aaff725398357 url: https://github.com/protocolbuffers/protobuf/archive/v3.9.1.tar.gz - 3.11.4: + "3.11.4": sha256: a79d19dcdf9139fa4b81206e318e33d245c4c9da1ffed21c87288ed4380426f9 url: https://github.com/protocolbuffers/protobuf/archive/v3.11.4.tar.gz - 3.12.4: + "3.12.4": sha256: 512e5a674bf31f8b7928a64d8adf73ee67b8fe88339ad29adaa3b84dbaa570d8 url: https://github.com/protocolbuffers/protobuf/archive/v3.12.4.tar.gz - 3.13.0: + "3.13.0": sha256: 9b4ee22c250fe31b16f1a24d61467e40780a3fbb9b91c3b65be2a376ed913a1a url: https://github.com/protocolbuffers/protobuf/archive/v3.13.0.tar.gz - 3.15.5: + "3.15.5": sha256: bc3dbf1f09dba1b2eb3f2f70352ee97b9049066c9040ce0c9b67fb3294e91e4b url: https://github.com/protocolbuffers/protobuf/archive/v3.15.5.tar.gz patches: - 3.12.4: + "3.12.4": - patch_file: "patches/upstream-pr-7761-cmake-regex-fix.patch" base_path: "source_subfolder" - patch_file: "patches/upstream-issue-7567-no-export-template-define.patch" @@ -24,13 +24,13 @@ patches: base_path: "source_subfolder" - patch_file: "patches/upstream-pr-8301-bundle-destination.patch" base_path: "source_subfolder" - 3.13.0: + "3.13.0": - patch_file: "patches/upstream-pr-7761-cmake-regex-fix.patch" base_path: "source_subfolder" - patch_file: "patches/upstream-pr-7288-android-log.patch" base_path: "source_subfolder" - patch_file: "patches/upstream-pr-8301-bundle-destination.patch" base_path: "source_subfolder" - 3.15.5: + "3.15.5": - patch_file: "patches/upstream-pr-8301-bundle-destination.patch" base_path: "source_subfolder" diff --git a/recipes/protobuf/all/conanfile.py b/recipes/protobuf/all/conanfile.py index cb0f93f2eeaa8..4258311d65c56 100644 --- a/recipes/protobuf/all/conanfile.py +++ b/recipes/protobuf/all/conanfile.py @@ -1,7 +1,7 @@ -import os from conans import ConanFile, CMake, tools from conans.errors import ConanInvalidConfiguration -from conans.tools import Version +import os +import textwrap class ProtobufConan(ConanFile): @@ -12,25 +12,27 @@ class ProtobufConan(ConanFile): url = "https://github.com/conan-io/conan-center-index" homepage = "https://github.com/protocolbuffers/protobuf" license = "BSD-3-Clause" - exports_sources = ["CMakeLists.txt", "patches/*"] - generators = "cmake" - short_paths = True + settings = "os", "arch", "compiler", "build_type" options = { - "fPIC": [True, False], - "lite": [True, False], "shared": [True, False], + "fPIC": [True, False], + "with_zlib": [True, False], "with_rtti": [True, False], - "with_zlib": [True, False] + "lite": [True, False], } default_options = { - "fPIC": True, - "lite": False, "shared": False, + "fPIC": True, + "with_zlib": True, "with_rtti": True, - "with_zlib": False + "lite": False, } + short_paths = True + + exports_sources = ["CMakeLists.txt", "patches/*"] + generators = "cmake" _cmake = None @property @@ -49,11 +51,6 @@ def _is_clang_x86(self): def _can_disable_rtti(self): return tools.Version(self.version) >= "3.15.4" - def source(self): - tools.get(**self.conan_data["sources"][self.version]) - extracted_folder = self.name + "-" + self.version - os.rename(extracted_folder, self._source_subfolder) - def config_options(self): if self.settings.os == "Windows": del self.options.fPIC @@ -64,14 +61,11 @@ def configure(self): if self.options.shared: del self.options.fPIC - if self.settings.os == "Windows" and self.settings.compiler in ["Visual Studio", "clang"] and "MT" in self.settings.compiler.runtime: + if str(self.settings.compiler.get_safe("runtime")) in ["MT", "MTd", "static"]: raise ConanInvalidConfiguration("Protobuf can't be built with shared + MT(d) runtimes") - if tools.is_apple_os(self.settings.os): - raise ConanInvalidConfiguration("Protobuf could not be built as shared library for Mac.") - if self.settings.compiler == "Visual Studio": - if Version(self.settings.compiler.version) < "14": + if tools.Version(self.settings.compiler.version) < "14": raise ConanInvalidConfiguration("On Windows Protobuf can only be built with " "Visual Studio 2015 or higher.") @@ -83,6 +77,11 @@ def requirements(self): if self.options.with_zlib: self.requires("zlib/1.2.11") + def source(self): + tools.get(**self.conan_data["sources"][self.version]) + extracted_folder = self.name + "-" + self.version + os.rename(extracted_folder, self._source_subfolder) + @property def _cmake_install_base_path(self): return os.path.join("lib", "cmake", "protobuf") @@ -94,11 +93,12 @@ def _configure_cmake(self): self._cmake.definitions["protobuf_WITH_ZLIB"] = self.options.with_zlib self._cmake.definitions["protobuf_BUILD_TESTS"] = False self._cmake.definitions["protobuf_BUILD_PROTOC_BINARIES"] = True - self._cmake.definitions["protobuf_BUILD_LIBPROTOC"] = True + if tools.Version(self.version) >= "3.14.0": + self._cmake.definitions["protobuf_BUILD_LIBPROTOC"] = True if self._can_disable_rtti: self._cmake.definitions["protobuf_DISABLE_RTTI"] = not self.options.with_rtti - if self.settings.compiler == "Visual Studio": - self._cmake.definitions["protobuf_MSVC_STATIC_RUNTIME"] = "MT" in str(self.settings.compiler.runtime) + if self.settings.compiler.get_safe("runtime"): + self._cmake.definitions["protobuf_MSVC_STATIC_RUNTIME"] = str(self.settings.compiler.runtime) in ["MT", "MTd", "static"] self._cmake.configure(build_folder=self._build_subfolder) return self._cmake @@ -106,57 +106,68 @@ def _patch_sources(self): for patch in self.conan_data.get("patches", {}).get(self.version, []): tools.patch(**patch) - find_protoc = """ - -# Find the protobuf compiler within the paths added by Conan, for use below. -find_program(PROTOC_PROGRAM protoc PATHS ENV PATH NO_DEFAULT_PATH) -if(NOT PROTOC_PROGRAM) - set(PROTOC_PROGRAM "protoc") -endif() -""" + # Provide relocatable protobuf::protoc target and Protobuf_PROTOC_EXECUTABLE cache variable + # TODO: some of the following logic might be disabled when conan will + # allow to create executable imported targets in package_info() + protobuf_config_cmake = os.path.join(self._source_subfolder, "cmake", "protobuf-config.cmake.in") tools.replace_in_file( - os.path.join(self._source_subfolder, "cmake", "protobuf-config.cmake.in"), + protobuf_config_cmake, "@_protobuf_FIND_ZLIB@", - "# CONAN PATCH _protobuf_FIND_ZLIB@" + "# BEGIN CONAN PATCH\n#_protobuf_FIND_ZLIB@\n# END CONAN PATCH" ) + + exe_ext = ".exe" if self.settings.os == "Windows" else "" + protoc_filename = "protoc" + exe_ext + module_folder_depth = len(os.path.normpath(self._cmake_install_base_path).split(os.path.sep)) + protoc_rel_path = "{}bin/{}".format("".join(["../"] * module_folder_depth), protoc_filename) + protoc_target = textwrap.dedent("""\ + if(NOT TARGET protobuf::protoc) + find_program(PROTOC_PROGRAM protoc PATHS ENV PATH NO_DEFAULT_PATH) + if(NOT PROTOC_PROGRAM) + set(PROTOC_PROGRAM \"${{CMAKE_CURRENT_LIST_DIR}}/{protoc_rel_path}\") + endif() + get_filename_component(PROTOC_PROGRAM \"${{PROTOC_PROGRAM}}\" ABSOLUTE) + set(Protobuf_PROTOC_EXECUTABLE ${{PROTOC_PROGRAM}} CACHE FILEPATH \"The protoc compiler\") + add_executable(protobuf::protoc IMPORTED) + set_property(TARGET protobuf::protoc PROPERTY IMPORTED_LOCATION ${{Protobuf_PROTOC_EXECUTABLE}}) + endif() + """.format(protoc_rel_path=protoc_rel_path)) tools.replace_in_file( - os.path.join(self._source_subfolder, "cmake", "protobuf-config.cmake.in"), + protobuf_config_cmake, "include(\"${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake\")", - "# CONAN PATCH include(\"${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake\")" + find_protoc + protoc_target ) - if tools.Version(self.version) < "3.12.0": + # Set DYLD_LIBRARY_PATH in command line to avoid issues with shared protobuf + # (even with virtualrunenv, this fix might be required due to SIP) + # Only works with cmake, cmake_find_package or cmake_find_package_multi generators + if tools.is_apple_os(self.settings.os): tools.replace_in_file( - os.path.join(self._source_subfolder, "cmake", "protobuf-config.cmake.in"), - """COMMAND protobuf::protoc - ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_protobuf_include_path} ${_abs_file} - DEPENDS ${_abs_file} protobuf::protoc""", - """COMMAND "${CMAKE_COMMAND}" - ARGS -E env "DYLD_LIBRARY_PATH=${Protobuf_LIB_DIRS}:${CONAN_LIB_DIRS}:${Protobuf_LIB_DIRS_RELEASE}:${Protobuf_LIB_DIRS_DEBUG}:${Protobuf_LIB_DIRS_RELWITHDEBINFO}:${Protobuf_LIB_DIRS_MINSIZEREL}" ${PROTOC_PROGRAM} --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_protobuf_include_path} ${_abs_file} - DEPENDS ${_abs_file} USES_TERMINAL""" + protobuf_config_cmake, + "add_custom_command(", + ("set(CUSTOM_DYLD_LIBRARY_PATH ${CONAN_LIB_DIRS} ${Protobuf_LIB_DIRS} ${Protobuf_LIB_DIRS_RELEASE} ${Protobuf_LIB_DIRS_DEBUG} ${Protobuf_LIB_DIRS_RELWITHDEBINFO} ${Protobuf_LIB_DIRS_MINSIZEREL})\n" + "string(REPLACE \";\" \":\" CUSTOM_DYLD_LIBRARY_PATH \"${CUSTOM_DYLD_LIBRARY_PATH}\")\n" + "add_custom_command(") ) - else: tools.replace_in_file( - os.path.join(self._source_subfolder, "cmake", "protobuf-config.cmake.in"), - """COMMAND protobuf::protoc - ARGS --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} - DEPENDS ${_abs_file} protobuf::protoc""", - """COMMAND "${CMAKE_COMMAND}" - ARGS -E env "DYLD_LIBRARY_PATH=${Protobuf_LIB_DIRS}:${CONAN_LIB_DIRS}:${Protobuf_LIB_DIRS_RELEASE}:${Protobuf_LIB_DIRS_DEBUG}:${Protobuf_LIB_DIRS_RELWITHDEBINFO}:${Protobuf_LIB_DIRS_MINSIZEREL}" ${PROTOC_PROGRAM} --${protobuf_generate_LANGUAGE}_out ${_dll_export_decl}${protobuf_generate_PROTOC_OUT_DIR} ${_plugin} ${_protobuf_include_path} ${_abs_file} - DEPENDS ${_abs_file} USES_TERMINAL""" + protobuf_config_cmake, + "COMMAND protobuf::protoc", + "COMMAND ${CMAKE_COMMAND} -E env \"DYLD_LIBRARY_PATH=${CUSTOM_DYLD_LIBRARY_PATH}\" $" ) + # Disable a potential warning in protobuf-module.cmake.in + # TODO: remove this patch? Is it really useful? + protobuf_module_cmake = os.path.join(self._source_subfolder, "cmake", "protobuf-module.cmake.in") tools.replace_in_file( - os.path.join(self._source_subfolder, "cmake", "protobuf-module.cmake.in"), - 'if(DEFINED Protobuf_SRC_ROOT_FOLDER)', - """if(0) -if(DEFINED Protobuf_SRC_ROOT_FOLDER)""", + protobuf_module_cmake, + "if(DEFINED Protobuf_SRC_ROOT_FOLDER)", + "if(0)\nif(DEFINED Protobuf_SRC_ROOT_FOLDER)", ) tools.replace_in_file( - os.path.join(self._source_subfolder, "cmake", "protobuf-module.cmake.in"), - '# Define upper case versions of output variables', - 'endif()', + protobuf_module_cmake, + "# Define upper case versions of output variables", + "endif()", ) def build(self): @@ -186,6 +197,7 @@ def package_info(self): self.cpp_info.names["cmake_find_package"] = "protobuf" self.cpp_info.names["cmake_find_package_multi"] = "protobuf" + self.cpp_info.names["pkg_config"] = "protobuf_full_package" # unofficial, but required to avoid side effects (libprotobuf component "steals" the default global pkg_config name) lib_prefix = "lib" if self.settings.compiler == "Visual Studio" else "" lib_suffix = "d" if self.settings.build_type == "Debug" else "" @@ -205,25 +217,17 @@ def package_info(self): if self.settings.os == "Windows": if self.options.shared: self.cpp_info.components["libprotobuf"].defines = ["PROTOBUF_USE_DLLS"] - - self.cpp_info.components["libprotobuf"].builddirs = [ - self._cmake_install_base_path, - ] - - self.cpp_info.components["libprotobuf"].builddirs = [self._cmake_install_base_path] - self.cpp_info.components["libprotobuf"].build_modules.extend([ + self.cpp_info.components["libprotobuf"].builddirs.append(self._cmake_install_base_path) + self.cpp_info.components["libprotobuf"].build_modules = [ os.path.join(self._cmake_install_base_path, "protobuf-generate.cmake"), os.path.join(self._cmake_install_base_path, "protobuf-module.cmake"), os.path.join(self._cmake_install_base_path, "protobuf-options.cmake"), - ]) + ] self.cpp_info.components["libprotoc"].name = "libprotoc" self.cpp_info.components["libprotoc"].libs = [lib_prefix + "protoc" + lib_suffix] self.cpp_info.components["libprotoc"].requires = ["libprotobuf"] - self.cpp_info.components["protoc"].name = "protoc" - self.cpp_info.components["protoc"].requires.extend(["libprotoc", "libprotobuf"]) - bindir = os.path.join(self.package_folder, "bin") self.output.info("Appending PATH environment variable: {}".format(bindir)) self.env_info.PATH.append(bindir) @@ -243,9 +247,9 @@ def package_info(self): if self.settings.os == "Android": self.cpp_info.components["libprotobuf-lite"].system_libs.append("log") - self.cpp_info.components["libprotobuf-lite"].builddirs = [self._cmake_install_base_path] - self.cpp_info.components["libprotobuf-lite"].build_modules.extend([ + self.cpp_info.components["libprotobuf-lite"].builddirs.append(self._cmake_install_base_path) + self.cpp_info.components["libprotobuf-lite"].build_modules = [ os.path.join(self._cmake_install_base_path, "protobuf-generate.cmake"), os.path.join(self._cmake_install_base_path, "protobuf-module.cmake"), os.path.join(self._cmake_install_base_path, "protobuf-options.cmake"), - ]) + ] diff --git a/recipes/protobuf/all/test_package/conanfile.py b/recipes/protobuf/all/test_package/conanfile.py index 65898b23a1bd1..55142345514b7 100644 --- a/recipes/protobuf/all/test_package/conanfile.py +++ b/recipes/protobuf/all/test_package/conanfile.py @@ -1,4 +1,4 @@ -from conans import ConanFile, CMake, RunEnvironment, tools +from conans import ConanFile, CMake, tools import os diff --git a/recipes/protobuf/config.yml b/recipes/protobuf/config.yml index 6f75a293b3fd8..797ab9e4d0664 100644 --- a/recipes/protobuf/config.yml +++ b/recipes/protobuf/config.yml @@ -1,11 +1,11 @@ versions: - 3.9.1: + "3.9.1": folder: all - 3.11.4: + "3.11.4": folder: all - 3.12.4: + "3.12.4": folder: all - 3.13.0: + "3.13.0": folder: all - 3.15.5: + "3.15.5": folder: all