Skip to content

Commit

Permalink
(conan-io#23084) protobuf : add version 3.22.3
Browse files Browse the repository at this point in the history
  • Loading branch information
sophieeihpos committed Apr 3, 2024
1 parent 976b1cd commit 46a0f55
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 30 deletions.
3 changes: 3 additions & 0 deletions recipes/protobuf/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
sources:
"3.22.3":
url: "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.22.3.tar.gz"
sha256: "91881f49d6a050dd65cad029e23f8140063c70d8a61f549debed2a03b256fb2f"
"3.21.12":
url: "https://github.com/protocolbuffers/protobuf/archive/refs/tags/v3.21.12.tar.gz"
sha256: "930c2c3b5ecc6c9c12615cf5ad93f1cd6e12d0aba862b572e076259970ac3a53"
Expand Down
167 changes: 139 additions & 28 deletions recipes/protobuf/all/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
from conan.tools.files import copy, rename, get, apply_conandata_patches, export_conandata_patches, replace_in_file, rmdir, rm
from conan.tools.microsoft import check_min_vs, msvc_runtime_flag, is_msvc, is_msvc_static_runtime
from conan.tools.scm import Version
from conan.tools.build import check_min_cppstd


import os
import textwrap
Expand Down Expand Up @@ -63,18 +65,35 @@ def layout(self):
cmake_layout(self, src_folder="src")

def requirements(self):
if Version(self.version) >= "3.22.0":
self.requires("abseil/20230125.0", transitive_headers=True)
if self.options.with_zlib:
self.requires("zlib/[>=1.2.11 <2]")

def validate(self):
if self.options.shared and is_msvc_static_runtime(self):
raise ConanInvalidConfiguration("Protobuf can't be built with shared + MT(d) runtimes")

check_min_vs(self, "190")

if self.settings.compiler == "clang":
if Version(self.settings.compiler.version) < "4":
raise ConanInvalidConfiguration(f"{self.ref} doesn't support clang < 4")
if Version(self.version) < "3.22.0":
check_min_vs(self, "190")
if self.settings.compiler == "clang":
if Version(self.settings.compiler.version) < "4":
raise ConanInvalidConfiguration(f"{self.ref} doesn't support clang < 4")
else:
if self.settings.compiler.cppstd:
check_min_cppstd(self, self._min_cppstd)
else:
raise ConanInvalidConfiguration(f"{self.ref} requires C++{self._min_cppstd}, cppstd must be specified.")
minimum_version = self._compilers_minimum_version.get(str(self.settings.compiler), False)
if minimum_version and Version(self.settings.compiler.version) < minimum_version:
raise ConanInvalidConfiguration(
f"{self.ref} requires C++{self._min_cppstd}, which your compiler does not support."
)
if self.options.shared and self.settings.os == "Windows":
# The dependency, shared abseil is not supported on Windows.
# Shared protobuf cannot build with static asbeil on Windows.
raise ConanInvalidConfiguration(
"Windows shared build is not supported yet."
)

def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True)
Expand All @@ -83,11 +102,49 @@ def source(self):
def _cmake_install_base_path(self):
return os.path.join("lib", "cmake", "protobuf")

@property
def _min_cppstd(self):
return "11" if Version(self.dependencies["abseil"].ref.version) < "20230125.0" else "14"

@property
def _compilers_minimum_version(self):
return {
"14": {
"gcc": "6",
"clang": "5",
"apple-clang": "10",
"Visual Studio": "15",
"msvc": "191",
},
}.get(self._min_cppstd, {})

def _get_rpath(self):
dep_dirs = set()
for dependency in self.dependencies.values():
cpp_info = dependency.cpp_info
dep_dirs.update(cpp_info.libdirs)
origin = ""
separator = ""
if is_apple_os(self):
origin = "@loader_path"
separator = ";"
elif self.settings.os == "Linux":
origin = "$ORIGIN"
separator = ":"
lib_dir = os.path.join(self.package_folder, "lib")
rpath = f"{separator}{lib_dir}"
for dep_dir in dep_dirs:
rel_path = os.path.relpath(dep_dir, self.package_folder)
rpath += f"{separator}{origin}/../{rel_path}"
return f'\"{rpath}\"'

def generate(self):
tc = CMakeToolchain(self)
tc.cache_variables["CMAKE_INSTALL_CMAKEDIR"] = self._cmake_install_base_path.replace("\\", "/")
tc.cache_variables["protobuf_WITH_ZLIB"] = self.options.with_zlib
tc.cache_variables["protobuf_BUILD_TESTS"] = False
if Version(self.version) >= "3.22.0":
tc.cache_variables["protobuf_ABSL_PROVIDER"] = "package"
tc.cache_variables["protobuf_BUILD_PROTOC_BINARIES"] = self.settings.os != "tvOS"
if not self.options.debug_suffix:
tc.cache_variables["protobuf_DEBUG_POSTFIX"] = ""
Expand All @@ -98,9 +155,6 @@ def generate(self):
if not runtime:
runtime = self.settings.get_safe("compiler.runtime")
tc.cache_variables["protobuf_MSVC_STATIC_RUNTIME"] = "MT" in runtime
if is_apple_os(self) and self.options.shared:
# Workaround against SIP on macOS for consumers while invoking protoc when protobuf lib is shared
tc.variables["CMAKE_INSTALL_RPATH"] = "@loader_path/../lib"
tc.generate()

deps = CMakeDeps(self)
Expand Down Expand Up @@ -178,6 +232,16 @@ def _patch_sources(self):
"#elif PROTOBUF_GNUC_MIN(12, 0)",
"#elif PROTOBUF_GNUC_MIN(12, 2)")

# Add $ORIGIN/../{relative_path} in RPATH for running executables.
if (self.settings.os == "Linux" or is_apple_os(self)) and self.options.shared:
old_str = ""
if is_apple_os(self):
old_str = 'PROPERTY INSTALL_RPATH "@loader_path/../lib"'
elif self.settings.os == "Linux":
old_str = 'PROPERTY INSTALL_RPATH "$ORIGIN/../${CMAKE_INSTALL_LIBDIR}"'
new_str = "PROPERTY INSTALL_RPATH " + self._get_rpath()
replace_in_file(self, os.path.join(self.source_folder, "cmake", "install.cmake"), old_str, new_str)

def build(self):
self._patch_sources()
cmake = CMake(self)
Expand All @@ -190,11 +254,17 @@ def package(self):
cmake = CMake(self)
cmake.install()
rmdir(self, os.path.join(self.package_folder, "lib", "pkgconfig"))
os.unlink(os.path.join(self.package_folder, self._cmake_install_base_path, "protobuf-config-version.cmake"))
os.unlink(os.path.join(self.package_folder, self._cmake_install_base_path, "protobuf-targets.cmake"))
os.unlink(os.path.join(self.package_folder, self._cmake_install_base_path, "protobuf-targets-{}.cmake".format(str(self.settings.build_type).lower())))
rename(self, os.path.join(self.package_folder, self._cmake_install_base_path, "protobuf-config.cmake"),
os.path.join(self.package_folder, self._cmake_install_base_path, "protobuf-generate.cmake"))
install_dir = os.path.join(self.package_folder, self._cmake_install_base_path)
os.unlink(os.path.join(install_dir, "protobuf-config-version.cmake"))
os.unlink(os.path.join(install_dir, "protobuf-targets.cmake"))
os.unlink(os.path.join(install_dir, "protobuf-targets-{}.cmake".format(str(self.settings.build_type).lower())))

config_path = os.path.join(install_dir, "protobuf-config.cmake")
if Version(self.version) < "3.22.0":
rename(self, config_path, os.path.join(install_dir, "protobuf-generate.cmake"))
else:
os.unlink(config_path)
rmdir(self, os.path.join(install_dir, "../utf8_range"))

if not self.options.lite:
rm(self, "libprotobuf-lite*", os.path.join(self.package_folder, "lib"))
Expand All @@ -205,33 +275,71 @@ def package_info(self):
self.cpp_info.set_property("cmake_module_file_name", "Protobuf")
self.cpp_info.set_property("cmake_file_name", "protobuf")
self.cpp_info.set_property("pkg_config_name", "protobuf_full_package") # unofficial, but required to avoid side effects (libprotobuf component "steals" the default global pkg_config name)

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"),
]
build_modules = [ os.path.join(self._cmake_install_base_path, path) for path in os.listdir(os.path.join(self._cmake_install_base_path)) if path.endswith(".cmake")]
self.cpp_info.set_property("cmake_build_modules", build_modules)

lib_prefix = "lib" if (is_msvc(self) or self._is_clang_cl) else ""
lib_suffix = "d" if self.settings.build_type == "Debug" and self.options.debug_suffix else ""

# utf8_validity
if Version(self.version) >= "3.22.0":
self.cpp_info.components["utf8_validity"].libs = ["utf8_validity"]
self.cpp_info.components["utf8_validity"].requires = ["abseil::absl_strings"]

# libprotobuf
self.cpp_info.components["libprotobuf"].set_property("cmake_target_name", "protobuf::libprotobuf")
self.cpp_info.components["libprotobuf"].set_property("pkg_config_name", "protobuf")
self.cpp_info.components["libprotobuf"].builddirs.append(self._cmake_install_base_path)
self.cpp_info.components["libprotobuf"].libs = [lib_prefix + "protobuf" + lib_suffix]
required_abseil = [] if Version(self.version) < "3.22.0" else [
"abseil::absl_check",
"abseil::absl_log",
"abseil::absl_algorithm",
"abseil::absl_base",
"abseil::absl_bind_front",
"abseil::absl_bits",
"abseil::absl_btree",
"abseil::absl_cleanup",
"abseil::absl_cord",
"abseil::absl_core_headers",
"abseil::absl_debugging",
"abseil::absl_die_if_null",
"abseil::absl_dynamic_annotations",
"abseil::absl_flags",
"abseil::absl_flat_hash_map",
"abseil::absl_flat_hash_set",
"abseil::absl_function_ref",
"abseil::absl_hash",
"abseil::absl_layout",
"abseil::absl_log_initialize",
"abseil::absl_log_severity",
"abseil::absl_memory",
"abseil::absl_node_hash_map",
"abseil::absl_node_hash_set",
"abseil::absl_optional",
"abseil::absl_span",
"abseil::absl_status",
"abseil::absl_statusor",
"abseil::absl_strings",
"abseil::absl_synchronization",
"abseil::absl_time",
"abseil::absl_type_traits",
"abseil::absl_utility",
"abseil::absl_variant"
]
self.cpp_info.components["libprotobuf"].requires = required_abseil
if Version(self.version) >= "3.22.0":
self.cpp_info.components["libprotobuf"].requires.append("utf8_validity")
if self.options.with_zlib:
self.cpp_info.components["libprotobuf"].requires = ["zlib::zlib"]
self.cpp_info.components["libprotobuf"].requires.append("zlib::zlib")
if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.components["libprotobuf"].system_libs.extend(["m", "pthread"])
if self._is_clang_x86 or "arm" in str(self.settings.arch):
self.cpp_info.components["libprotobuf"].system_libs.append("atomic")
if self.settings.os == "Android":
self.cpp_info.components["libprotobuf"].system_libs.append("log")
if self.settings.os == "Windows":
if self.options.shared:
self.cpp_info.components["libprotobuf"].defines = ["PROTOBUF_USE_DLLS"]
if self.options.shared:
self.cpp_info.components["libprotobuf"].defines = ["PROTOBUF_USE_DLLS"]

# libprotoc
if self.settings.os != "tvOS":
Expand All @@ -241,6 +349,8 @@ def package_info(self):

# libprotobuf-lite
if self.options.lite:
if Version(self.version) >= "3.22.0":
self.cpp_info.components["libprotobuf-lite"].requires = ["utf8_validity"]
self.cpp_info.components["libprotobuf-lite"].set_property("cmake_target_name", "protobuf::libprotobuf-lite")
self.cpp_info.components["libprotobuf-lite"].set_property("pkg_config_name", "protobuf-lite")
self.cpp_info.components["libprotobuf-lite"].builddirs.append(self._cmake_install_base_path)
Expand All @@ -249,9 +359,8 @@ def package_info(self):
self.cpp_info.components["libprotobuf-lite"].system_libs.extend(["m", "pthread"])
if self._is_clang_x86 or "arm" in str(self.settings.arch):
self.cpp_info.components["libprotobuf-lite"].system_libs.append("atomic")
if self.settings.os == "Windows":
if self.options.shared:
self.cpp_info.components["libprotobuf-lite"].defines = ["PROTOBUF_USE_DLLS"]
if self.options.shared:
self.cpp_info.components["libprotobuf-lite"].defines = ["PROTOBUF_USE_DLLS"]
if self.settings.os == "Android":
self.cpp_info.components["libprotobuf-lite"].system_libs.append("log")

Expand All @@ -264,4 +373,6 @@ def package_info(self):
if self.options.lite:
for generator in ["cmake_find_package", "cmake_find_package_multi"]:
self.cpp_info.components["libprotobuf-lite"].build_modules[generator] = build_modules
self.env_info.PATH.append(os.path.join(self.package_folder, "bin"))
bin = os.path.join(self.package_folder, "bin")
self.env_info.PATH.append(bin)
self.buildenv_info.append_path("PATH", bin)
3 changes: 3 additions & 0 deletions recipes/protobuf/all/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,8 @@ if(TARGET protobuf::libprotoc)
target_link_libraries(${PROJECT_NAME} PRIVATE protobuf::libprotoc)
endif()

if (NOT (rotobuf_VERSION LESS 3.22.0))
find_program(protobuf_PROTOC_EXE NAMES protoc PATHS ENV PATH NO_DEFAULT_PATH)
endif()
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS TARGET ${PROJECT_NAME})
protobuf_generate(LANGUAGE cpp TARGET ${PROJECT_NAME} PROTOS addressbook.proto)
6 changes: 4 additions & 2 deletions recipes/protobuf/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "CMakeDeps", "VirtualBuildEnv", "VirtualRunEnv"
generators = "CMakeDeps"
test_type = "explicit"

def layout(self):
Expand All @@ -16,7 +16,9 @@ def requirements(self):
self.requires(self.tested_reference_str)

def build_requirements(self):
self.tool_requires(self.tested_reference_str)
# The protoc executable is not supported on windows with shared library, use static linked executable.
if self.settings.os == "Windows":
self.tool_requires(self.tested_reference_str)

def generate(self):
tc = CMakeToolchain(self)
Expand Down
2 changes: 2 additions & 0 deletions recipes/protobuf/config.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
versions:
"3.22.3":
folder: all
"3.21.12":
folder: all
"3.21.9":
Expand Down

0 comments on commit 46a0f55

Please sign in to comment.