使用CMake构建Emscripten项目

15

我希望让CMake和Emscripten变成好朋友。在Emscripten项目网站上没有找到更多或更少有用的文档,但他们提供了CMake工具链文件,所以我认为应该是可能的。 到目前为止,仅使用基本编译而不使用高级参数可以正常工作,但是在使用embind和预加载文件时遇到问题。

  1. 链接过程似乎缺少Emscripten“二进制文件”,并对所有与embind相关的函数产生警告,例如: warning: unresolved symbol: _embind_register_class,这导致在浏览器中加载已编译的JS文件时出现相应的错误。
  2. 在编译过程中未生成.data文件。

我创建了一个包含两个目标的最小示例:一个“普通”的(client)和一个手动的(manual-client),后者只是按照我期望的方式运行emcc:https://github.com/xwaffelx/minimal-cmake-emscripten-project/blob/master/README.md

虽然手动方式可行,但我认为这不是正确的方法...

--- 更新 ---

根据要求,这里是更短的例子:

  1. CMakeLists.txt文件
  2. 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/<em>.h)
    file(GLOB_RECURSE CORE_SRC src/</em>.cpp)
    add_definitions("-s DEMANGLE_SUPPORT=1 --preload-file ${CMAKE_SOURCE_DIR}/assets --bind")
    add_executable(client ${CORE_SRC} ${CORE_HDR})
    

Result should be equivalent to running the following command manualy:

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

Here is the 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个回答

19
解决方案是通过提供以下CMake指令来在链接时指定所有标志: set_target_properties(client PROPERTIES LINK_FLAGS "-s DEMANGLE_SUPPORT=1 --preload-file assets --bind") 感谢emscripten的开发人员在GitHub问题跟踪器中提供的帮助。

抱歉,您修改了哪个文件? Makefile 文件吗? - Alex Polymath
3
不需要 CMakeLists.txt 文件,只需使用 set_target_properties 条目指定链接器参数即可。 - Alexander

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接