Проект CMake для Emscripten

Я хочу сделать CMake и Emscripten друзьями. Не нашел более или менее информативной документации на веб-сайте проекта Emscripten, но они предоставляют файл CMake toolchain, поэтому я думаю, что это должно быть возможно. Пока очень простая компиляция без дополнительных параметров работает нормально, но у меня есть проблемы при использовании embind и предварительная загрузка файлов.

  1. Процесс связывания, по-видимому, пропускает "двоичные файлы" Emscripten и выдает предупреждения для всех связанных функций embind, как эта: warning: unresolved symbol: _embind_register_class что приводит к соответствующим ошибкам при загрузке скомпилированного файла JS в rowser.
  2. нет .data файл генерируется во время компиляции.

Я создал минималистичный пример, который включает две цели: одну "обычную" (клиент) и одну ручную (ручной клиент), которая просто запускает emcc так, как я ожидаю, что он будет запущен: https://github.com/xwaffelx/minimal-cmake-emscripten-project/blob/master/README.md

Хотя ручной способ работает, я не думаю, что это правильный способ сделать это...

--- Обновить ---

Как и просили, вот еще более короткий пример:

  1. Файл CMakeLists.txt
    cmake_minimum_required(VERSION 2.8)
    cmake_policy(SET CMP0015 NEW)
    project(emtest)
    set(CMAKE_VERBOSE_MAKEFILE on)
    set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/build.emscripten)
    include_directories("lib/assimp/include")
    link_directories("lib/assimp/lib-js")
    link_libraries("assimp")
    file(GLOB_RECURSE CORE_HDR src/.h)
    file(GLOB_RECURSE CORE_SRC src/.cpp)
    add_definitions("-s DEMANGLE_SUPPORT=1 --preload-file ${CMAKE_SOURCE_DIR}/assets --bind")
    add_executable(client ${CORE_SRC} ${CORE_HDR})
    

Результат должен быть эквивалентен выполнению следующей команды manualy:

emcc 
    -Ilib/assimp/include 
    -s DEMANGLE_SUPPORT=1
    --preload-file assets
    --bind
    Application.cpp 
    lib/assimp/lib-js/libassimp.so 
    -o client.js

Вот приложение.cpp:

#include "Application.h"

#include <iostream>

#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

void Application::Initialize() {
    std::cout << "Initializing application." << std::endl;
    Assimp::Importer importer; // For test purpose
}

void Application::SayHello() {
    std::cout << "Hello!" << std::endl;
}

и Application.h:

#ifndef APPLICATION_H
#define APPLICATION_H

#include <emscripten/html5.h>
#include <emscripten/bind.h>

namespace e = emscripten;

class Application {
public:
    void Initialize();
    void SayHello();
};

EMSCRIPTEN_BINDINGS(EMTest) {
  e::class_<Application>("Application")
    .constructor()
      .function("Initialize", &Application::Initialize)
      .function("SayHello", &Application::SayHello);
}

#endif

Затем я запускаю cmake следующим образом: cmake -DCMAKE_TOOLCHAIN_PATH=path/to/Emscripten.cmake .. && make Тем не менее, такие предупреждения, как warning: unresolved symbol: _embind_register_class создаются во время компоновки и запуска кода и не содержат предварительно загруженных данных в client.data файл создается при компиляции проекта CMake. При этом никаких предупреждений нет и все работает нормально при компиляции вручную.

1 ответ

Решение

Решением было указать все флаги во время связывания, предоставив следующую инструкцию CMake:set_target_properties(client PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file assets --bind")

Спасибо разработчикам emscripten, которые помогли в трекере Github.

Другие вопросы по тегам