Skip to content

Correctly pick up & use Protobuf_PROTOC_EXECUTABLE in cross-compilation #14576

Open
@h-vetinari

Description

@h-vetinari

It seems that when using find_package(Protobuf CONFIG), any eventual setting of Protobuf_PROTOC_EXECUTABLE is ignored.

This makes it hard for us in conda-forge, because find_package(Protobuf CONFIG) is necessary to avoid picking up CMake's own implementation of finding protobuf (and prefer an up-to-date protobuf-config.cmake; which is necessary for correctly linking abseil for example).

On the other hand, we simply must cross-compile on several architectures (e.g. no osx-arm64 runners at scale), and so if Protobuf_PROTOC_EXECUTABLE gets ignored (which carefully points to the build environment that matches the arch or the agent, and not the target environment for the final binary) we run into Bad CPU type in executable when it calls the wrong protoc.

The work-around we have come up with (and keep reinventing) in several places boils down to (courtesy @traversaro):

 find_package(Protobuf CONFIG)
 if(Protobuf_FOUND)
     message(STATUS "Found protobuf via cmake config")
+    if(Protobuf_PROTOC_EXECUTABLE)
+      set_target_properties(protobuf::protoc PROPERTIES
+        IMPORTED_LOCATION_RELEASE "${Protobuf_PROTOC_EXECUTABLE}"
+      )
+    endif()
 else()
     message(WARNING "Falling back to cmake FindProtobuf as Protobuf was not found via CONFIG")
     find_package(Protobuf REQUIRED)
 endif()

However, not everyone encountering this issue might be able to investigate and come up with this solution, so we keep running into it. I don't see why this shouldn't be supported out of the box, hence this issue.

What version of protobuf and what language are you using?
Version: 4.24.3
Language: C++

What operating system (Linux, Windows, ...) and version?

linux/osx

What runtime / compiler are you using (e.g., python version or gcc version)

What did you do?
Cross-compile a package that requires protoc, pass -DProtobuf_PROTOC_EXECUTABLE=... to CMake invocation

What did you expect to see

Correct protoc (corresponding to Protobuf_PROTOC_EXECUTABLE) gets used.

What did you see instead?

Wrong protoc gets picked up.

Anything else we should know about your project / environment

Some examples from conda-forge:

Metadata

Metadata

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions