Emscripten的CMake项目

时间:2016-06-10 11:32:46

标签: c++ cmake emscripten

我想制作CMake和Emscripten的朋友。没有在Emscripten项目网站上找到或多或少信息丰富的文档,但它们提供了CMake工具链文件,所以我认为它应该是可能的。 到目前为止,没有高级参数的基本编译工作正常,但我在使用embind和预加载文件时遇到了问题。

  1. 链接过程似乎错过了Emscripten"二进制文件"并为所有与embind相关的函数生成警告,例如:warning: unresolved symbol: _embind_register_class,这会在将已编译的JS文件加载到rowser中时导致相应的错误。
  2. 编译期间未生成.data文件。
  3. 我创建了一个简约的例子,其中包括两个目标:一个"普通" (客户端)和一个手动(手动客户端),它只是运行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})
      
    2. 结果应该等同于手动运行以下命令:

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

      这是Application.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之类的警告,并且在编译CMake项目时不会在client.data文件中创建预加载的数据。同时,在手动编译时,没有任何警告和一切正常运行。

1 个答案:

答案 0 :(得分:7)

解决方案是通过提供以下CMake指令来指定链接期间的所有标志: set_target_properties(client PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file assets --bind")

感谢emscripten的开发人员帮助了github问题跟踪器。