LINUX.ORG.RU

CMake + vcpkg + EMSDK

 , , vcpkg


0

1

Допустим, есть простенький C++ проект:

CMakeLists.txt

cmake_minimum_required(VERSION 3.14)

include(FetchContent)
FetchContent_Declare(vcpkg GIT_REPOSITORY https://github.com/microsoft/vcpkg/ GIT_TAG 2022.09.27)
FetchContent_MakeAvailable(vcpkg)
set(CMAKE_TOOLCHAIN_FILE "${vcpkg_SOURCE_DIR}/scripts/buildsystems/vcpkg.cmake" CACHE FILEPATH "")

project(MyProject)

set(CMAKE_CXX_STANDARD 20)

find_package(spdlog CONFIG REQUIRED)

add_executable(${CMAKE_PROJECT_NAME} main.cpp)
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE spdlog::spdlog)

vcpkg.json

{
        "name": "main",
        "version-string": "latest",
        "dependencies": [
                "spdlog"
        ]
}

main.cpp

#include <spdlog/spdlog.h>

int main() {
        spdlog::info("Hello world!");
        return 0;
}

Пытаемся его собирать нативно:

$ cmake .. && make && ./MyProject
...
[100%] Built target MyProject
[2022-10-23 14:41:07.376] [info] Hello world!

Всё работает.

Теперь, допустим, мы его хотим собрать под WASM:

$ source "/home/kiv/emsdk/emsdk_env.sh"
...
$ cmake .. -DVCPKG_TARGET_TRIPLET=wasm32-emscripten && make
-- Running vcpkg install
-- Running vcpkg install - done
CMake Error at build-wasm/_deps/vcpkg-src/scripts/buildsystems/vcpkg.cmake:829 (_find_package):
  Could not find a configuration file for package "spdlog" that is compatible
  with requested version "".

  The following configuration files were considered but not accepted:

    /home/kiv/my_project/build-wasm/vcpkg_installed/wasm32-emscripten/share/spdlog/spdlogConfig.cmake, version: 1.10.0 (32bit)

Call Stack (most recent call first):
  CMakeLists.txt:12 (find_package)


-- Configuring incomplete, errors occurred!
See also "/home/kiv/my_project/build-wasm/CMakeFiles/CMakeOutput.log".

Беглый поиск по ошибке даёт наводку, что такое может быть, когда CMake находит несовместимую библиотеку. Например, пытается использовать системную при кросскомпиляции. Что ж, похоже на наш случай.

$ mkdir tmp && cd tmp
$ ar x ../vcpkg_installed/wasm32-emscripten/lib/libspdlog.a
$ file spdlog.cpp.o
spdlog.cpp.o: WebAssembly (wasm) binary module version 0x1 (MVP)

Нет, не наш случай - библиотека скомпилирована под WASM и её должно быть возможно использовать.

Возникает вопрос, как заставить CMake всё же использовать найденную библиотеку.

Пробуем указывать точную версию find_package(spdlog «1.10.0 (32bit)» CONFIG REQUIRED) - получаем ошибку недопустимого аргумента (вероятно, из-за пробела в версии). Если указывать же просто 1.10.0, то получаем старую ошибку и ничего не меняется.

Возникает вопрос, как find_package определяет совместимость библиотеки и как изменить его мнение в данной ситуации.

★★★★★

Я нашёл, где происходит проверка:

vcpkg_installed/wasm32-emscripten/share/spdlog/spdlogConfigVersion.cmake:

...
# if the installed or the using project don't have CMAKE_SIZEOF_VOID_P set, ignore it:
if("${CMAKE_SIZEOF_VOID_P}" STREQUAL "" OR "4" STREQUAL "")
  return()
endif()

# check that the installed version has the same 32/64bit-ness as the one which is currently searching:
if(NOT CMAKE_SIZEOF_VOID_P STREQUAL "4")
  math(EXPR installedBits "4 * 8")
  set(PACKAGE_VERSION "${PACKAGE_VERSION} (${installedBits}bit)")
  set(PACKAGE_VERSION_UNSUITABLE TRUE)
endif()

Я добавил message(«${CMAKE_SIZEOF_VOID_P}») перед find_package и теперь на этапе конфигурации перед ошибкой CMake выводит «8».

Получается, по какой-то причине CMake использует CMAKE_SIZEOF_VOID_P от хостового тулчейна.

KivApple ★★★★★
() автор топика
Последнее исправление: KivApple (всего исправлений: 1)