Проект CMake для Emscripten
Я хочу сделать CMake и Emscripten друзьями. Не нашел более или менее информативной документации на веб-сайте проекта Emscripten, но они предоставляют файл CMake toolchain, поэтому я думаю, что это должно быть возможно. Пока очень простая компиляция без дополнительных параметров работает нормально, но у меня есть проблемы при использовании embind
и предварительная загрузка файлов.
- Процесс связывания, по-видимому, пропускает "двоичные файлы" Emscripten и выдает предупреждения для всех связанных функций embind, как эта:
warning: unresolved symbol: _embind_register_class
что приводит к соответствующим ошибкам при загрузке скомпилированного файла JS в rowser. - нет
.data
файл генерируется во время компиляции.
Я создал минималистичный пример, который включает две цели: одну "обычную" (клиент) и одну ручную (ручной клиент), которая просто запускает emcc так, как я ожидаю, что он будет запущен: https://github.com/xwaffelx/minimal-cmake-emscripten-project/blob/master/README.md
Хотя ручной способ работает, я не думаю, что это правильный способ сделать это...
--- Обновить ---
Как и просили, вот еще более короткий пример:
- Файл 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.