Skip to content
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: improve discovery of protoc executable in build context #20089

Merged
merged 5 commits into from
Dec 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions recipes/protobuf/all/conanfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,20 +124,33 @@ def _patch_sources(self):
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("""\
protoc_target = textwrap.dedent(f"""\
if(NOT TARGET protobuf::protoc)
# Locate protoc executable
## Workaround for legacy "cmake" generator in case of cross-build
if(CMAKE_CROSSCOMPILING)
find_program(PROTOC_PROGRAM protoc PATHS ENV PATH NO_DEFAULT_PATH)
find_program(PROTOC_PROGRAM NAMES protoc PATHS ENV PATH NO_DEFAULT_PATH)
endif()
## And here this will work fine with "CMakeToolchain" (for native & cross-build)
## and legacy "cmake" generator in case of native build
if(NOT PROTOC_PROGRAM)
find_program(PROTOC_PROGRAM NAMES protoc)
endif()
## Last resort: we search in package folder directly
if(NOT PROTOC_PROGRAM)
set(PROTOC_PROGRAM \"${{CMAKE_CURRENT_LIST_DIR}}/{protoc_rel_path}\")
endif()
get_filename_component(PROTOC_PROGRAM \"${{PROTOC_PROGRAM}}\" ABSOLUTE)

# Give opportunity to users to provide an external protoc executable
# (this is a feature of official FindProtobuf.cmake)
set(Protobuf_PROTOC_EXECUTABLE ${{PROTOC_PROGRAM}} CACHE FILEPATH \"The protoc compiler\")

# Create executable imported target protobuf::protoc
add_executable(protobuf::protoc IMPORTED)
set_property(TARGET protobuf::protoc PROPERTY IMPORTED_LOCATION ${{Protobuf_PROTOC_EXECUTABLE}})
endif()
""".format(protoc_rel_path=protoc_rel_path))
""")
replace_in_file(self,
protobuf_config_cmake,
"include(\"${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake\")",
Expand Down
13 changes: 3 additions & 10 deletions recipes/protobuf/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
from conan import ConanFile
from conan.tools.build import can_run, cross_building
from conan.tools.build import can_run
from conan.tools.cmake import cmake_layout, CMake, CMakeToolchain
from conan.tools.env import VirtualBuildEnv, VirtualRunEnv
import os


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

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

def build_requirements(self):
if cross_building(self) and hasattr(self, "settings_build"):
self.tool_requires(self.tested_reference_str)
self.tool_requires(self.tested_reference_str)

def generate(self):
VirtualRunEnv(self).generate()
if cross_building(self) and hasattr(self, "settings_build"):
VirtualBuildEnv(self).generate()
else:
VirtualRunEnv(self).generate(scope="build")
tc = CMakeToolchain(self)
tc.cache_variables["protobuf_LITE"] = self.dependencies[self.tested_reference_str].options.lite
tc.generate()
Expand Down