Skip to content

How to cross-compile using protobuf's protoc #9307

@star-hengxing

Description

@star-hengxing

Xmake Version

3.0.7

Operating System Version and Architecture

Windows

Describe Bug

C++ libraries that depend on protobuf require protoc for code generation. When cross-compiling, it is necessary to build a host protoc and a target protobuf library.

CMake's find_package (Config mode) typically finds the target protobuf, but it also mandates finding protoc. If the found protoc is the target version (which cannot run on the host), it leads to build errors in dependent libraries. Consequently, some CMake libraries allow setting a separate foo_protoc_exe variable to resolve this issue.

Currently, the protobuf-cpp package deletes the target version of protoc during cross-compilation:

os.tryrm(package:installdir("bin/*.exe"))

This is done so that the xmake protoc rule can successfully locate the host version of protoc (although we could set this via target:data("protobuf.protoc"), it is not very convenient):
https://github.com/xmake-io/xmake/blob/5670477e415e24962c57eac21194c63946ee5e1e/xmake/rules/protobuf/proto.lua#L29-L53

However, if protoc is deleted, CMake throws an error when using find_package with protobuf in Config mode because it cannot locate the executable:

CMake Error at C:/Users/star/AppData/Local/.xmake/packages/p/protobuf-cpp/33.2/70d6e80d573f45a9b5d8167b4d36331d/lib/cmake/protobuf/protobuf-targets.cmake:135 (message):
  The imported target "protobuf::protoc" references the file

     "C:/Users/star/AppData/Local/.xmake/packages/p/protobuf-cpp/33.2/70d6e80d573f45a9b5d8167b4d36331d/bin/protoc.exe"

  but this file does not exist.  Possible reasons include:

  * The file was deleted, renamed, or moved to another location.

  * An install or uninstall procedure did not complete successfully.

  * The installation package was faulty and contained

     "C:/Users/star/AppData/Local/.xmake/packages/p/protobuf-cpp/33.2/70d6e80d573f45a9b5d8167b4d36331d/lib/cmake/protobuf/protobuf-targets.cmake"

  but not all the files it references.

Call Stack (most recent call first):
  C:/Users/star/AppData/Local/.xmake/packages/p/protobuf-cpp/33.2/70d6e80d573f45a9b5d8167b4d36331d/lib/cmake/protobuf/protobuf-config.cmake:16 (include)
  cmake/system_deps.cmake:38 (find_package)
  CMakeLists.txt:437 (include)

Using FindProtobuf.cmake (Module mode) can avoid the mandatory protoc lookup. However, this script has a drawback: it does not set up abseil dependencies or certain compilation flags (such as the PROTOBUF_USE_DLLS macro), which also leads to compilation errors.

Expected Behavior

I currently believe that deleting the target protoc is unnecessary. The lookup failure should be resolved within the xmake protoc rule by excluding the bin directory of the target protobuf-cpp.

When packaging in xmake-repo, we should use find_package in Config mode and, depending on the specific situation, patch the CMakeLists.txt code that invokes protoc.

or try this way: microsoft/vcpkg#41195 (comment)

Project Configuration

N/A

Additional Information and Error Logs

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions