New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
protobuf: allow shared on Macos + add protobuf::protoc imported target #4776
Changes from 6 commits
f320810
f13d5b7
d636224
c4037a2
5df0f08
0913f5f
725d9d4
d879ac2
c2c6033
ab34548
0408def
f5a965d
a7d6760
10ac43a
abb921f
dc170c4
610126d
d877dc5
af51bdb
55a8007
72f94bf
427035b
b3d5a0c
3a56544
69d7baa
4de7716
cd6f6a6
a46fe2d
a0f4c76
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,12 +34,6 @@ def _build_subfolder(self): | |
def _is_clang_x86(self): | ||
return self.settings.compiler == "clang" and self.settings.arch == "x86" | ||
|
||
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 | ||
|
@@ -48,20 +42,23 @@ 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 self.settings.compiler.get_safe("runtime") in ["MT", "MTd"]: | ||
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": | ||
raise ConanInvalidConfiguration("On Windows Protobuf can only be built with " | ||
"Visual Studio 2015 or higher.") | ||
|
||
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") | ||
|
@@ -83,57 +80,62 @@ 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) | ||
if(NOT PROTOC_PROGRAM) | ||
set(PROTOC_PROGRAM "protoc") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not clear to me how this is not conflicting with: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's removed. This PR adds There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have pasted some commands below with one way you can test it. Command: conan create . 3.15.5@foo/testing \
--profile:host android-ndk-r22-api-21-arm64-v8a-clang-c++_static.txt \
--profile:build default \
--build=protobuf android-ndk-r22-api-21-arm64-v8a-clang-c++_static.txt:
Result:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ok so maybe we could keep this There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, could work. I'm happy to try if you push something later :) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you test with a0f4c76 please? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seems to work just fine. I'm happy with it :) |
||
endif() | ||
""" | ||
# Inject relocatable protobuf::protoc target in protobuf-config.cmake.in | ||
# 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) | ||
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 | ||
("if(NOT TARGET protobuf::protoc)\n" | ||
" add_executable(protobuf::protoc IMPORTED)\n" | ||
" get_filename_component(PROTOC_FULL_PATH \"${{CMAKE_CURRENT_LIST_DIR}}/{protoc_rel_path}\" ABSOLUTE)\n" | ||
" set_property(TARGET protobuf::protoc PROPERTY IMPORTED_LOCATION ${{PROTOC_FULL_PATH}})\n" | ||
"endif()" | ||
).format(protoc_rel_path=protoc_rel_path) | ||
) | ||
|
||
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 export DYLD_LIBRARY_PATH=${CUSTOM_DYLD_LIBRARY_PATH}\n" | ||
"COMMAND protobuf::protoc") | ||
) | ||
|
||
# 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): | ||
|
@@ -180,25 +182,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) | ||
|
@@ -216,9 +210,9 @@ def package_info(self): | |
if self.options.shared: | ||
self.cpp_info.components["libprotobuf-lite"].defines = ["PROTOBUF_USE_DLLS"] | ||
|
||
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"), | ||
]) | ||
] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure if we already care about this, but this seems not to be future proof with the settings for the new MSVC compiler
https://github.com/conan-io/conan/blob/03b3d71890c537df1154b3d04cc35ed2654a5894/conans/client/conf/__init__.py#L87
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not a regression in any case, as the old code did not support the MSVC compiler settings either
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can add
"static"
. A new method in tools would be welcome to avoid fragile verifications (something liketools.is_static_runtime(self.settings.compiler)
. There are many recipes like that.