CMake fails due to missing protobuf-config.cmake while compiling project using Emscripten

Greetings,

I’m trying to compile to WASM a C++ project that has protobuf as a dependency. To this aim, I downloaded the precompiled library from the protobuf-wasm repo’s releases and modified the project’s CMake configuration so that it will point to the directory containing Protobuf’s WASM version. To do this, I modified the call to find_package() so that it now contains the path to the directory where I have the WASM version:

 find_package(Protobuf REQUIRED PATHS /home/osboxes/protobuf-wasm)

The problem is that when I invoke CMake it fails because it can’t find protobuf-config.cmake:

$ emcmake cmake -G Ninja -DWITH_CASTOR=OFF -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON ..
configure: cmake -G Ninja -DWITH_CASTOR=OFF -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON .. -DCMAKE_TOOLCHAIN_FILE=/home/osboxes/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/home/osboxes/emsdk/node/16.20.0_64bit/bin/node
Using Ninja as default generator on Unix. If you wish to generate Makefiles instead, clear the build directory and use
    cmake -DNO_DEFAULT_GENERATOR=True -G'Unix Makefiles'
Using infra   config files from directory /home/osboxes/core-master/config/local
Using project config files from directory /home/osboxes/core-master/config/projects/gum
SYSTEM NAME:
Emscripten
CMake Error at cpp/ext/protobuf/CMakeLists.txt:72 (find_package):
  Could not find a package configuration file provided by "Protobuf" with any
  of the following names:

    ProtobufConfig.cmake
    protobuf-config.cmake

  Add the installation prefix of "Protobuf" to CMAKE_PREFIX_PATH or set
  "Protobuf_DIR" to a directory containing one of the above files.  If
  "Protobuf" provides a separate development package or SDK, be sure it has
  been installed.


-- Configuring incomplete, errors occurred!
See also "/home/osboxes/core-master/wasm/CMakeFiles/CMakeOutput.log".
emcmake: error: 'cmake -G Ninja -DWITH_CASTOR=OFF -DCMAKE_BUILD_WITH_INSTALL_RPATH=ON .. -DCMAKE_TOOLCHAIN_FILE=/home/osboxes/emsdk/upstream/emscripten/cmake/Modules/Platform/Emscripten.cmake -DCMAKE_CROSSCOMPILING_EMULATOR=/home/osboxes/emsdk/node/16.20.0_64bit/bin/node' failed (returned 1)

If I knew where to find one of those files, I could update CMake’s configuration, but the archive with the precompiled WASM Protobuf doesn’t contain those files. Also, aren’t those files only needed if one is compiling the library from source? How can I fix this issue?

I already tried compiling protobuf from source as explained in the repo’s readme, but unfortunately it didn’t work.

Thank you for yopur help,

GTP

I modified the call to find_package() so that it now contains the path to the directory

That would probably also work, but usually such paths are provided in CMAKE_PREFIX_PATH variable, because that way you won’t need to hardcode them in your project.

aren’t those files only needed if one is compiling the library from source?

No, those files (LibraryNameConfig.cmake and such) are produced after one has built and installed the library (if its project is set up properly). They are used for these find_package(LibraryName CONFIG) statements in other projects which would like to use that library. The Protobuf package that you have downloaded indeed does not have them, as people who built and packed it did not bother with making a CMake package (that’s their right, nothing wrong with it). So you can’t use find_package(LibraryName CONFIG) form, you would use find_package(LibraryName) instead, but that is also unlikely to work, because I suspect there is no pre-made module for finding Protobuf in your environment. Here’s a documentation page about finding packages, just in case.

Having built Protobuf from sources yourself you’d probably get the same result.

So what you can do is (optionally) write your own FindProtobuf.cmake module, in which you would set the required variables, such as library path and name, include directories and so on, or just hardcode those values in your project. And then you’ll need to set those in target_include_directories() and target_link_libraries().