【问题标题】:How to export C function in Emscripten when using CMake使用 CMake 时如何在 Emscripten 中导出 C 函数
【发布时间】:2020-06-25 12:48:02
【问题描述】:

this tutorial 中显示了以下用于导出 C 函数的示例

./emcc tests/hello_function.cpp -o function.html -s EXPORTED_FUNCTIONS='["_int_sqrt"]' -s EXPORTED_RUNTIME_METHODS='["ccall", "cwrap"]'

我也想做同样的事情,只是我像这样使用 CMake

cd bin
emcmake cmake ../src
emmake make

在emmake中指定-s的规范方式是什么?我应该将它添加到CMakeLists.txt 之类的

set(EXPORTED_FUNCTIONS '["_int_sqrt"]')

或者做类似的事情?

【问题讨论】:

    标签: c cmake emscripten emmake


    【解决方案1】:

    到目前为止,我发现可以通过以下设置实现CMake

    # Here you can add -s flag during compiling object files
    add_definitions("-s EXPORTED_RUNTIME_METHODS='[\"ccall\",\"cwrap\"]'")
    add_definitions("-s EXTRA_EXPORTED_RUNTIME_METHODS='[\"ccall\",\"cwrap\"]'")
    add_definitions("-s EXPORTED_FUNCTIONS='[\"_testInt\"]'")
    # Here you can add -s flag during linking
    set_target_properties(web_mealy_compiler PROPERTIES LINK_FLAGS "-s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap']")
    # Set this if you want to to generate sample html file
    set(CMAKE_EXECUTABLE_SUFFIX ".html")
    

    那么你应该可以从 javascript 中调用 C 函数,如下所示:

    <script type="text/javascript">
         
        Module['onRuntimeInitialized'] = function() {
         
            console.log("wasm loaded ");
            
            console.log(Module.ccall); // make sure it's not undefined
            console.log(Module._testInt); // make sure it's not undefined
            console.log(Module._testInt()); // this should work
            console.log( Module.ccall('testInt', // name of C function
                'number', // return type
                 [], // argument types
                 []) // argument values
            );
        }
    </script>
    

    这是我对 C 函数的定义:

    #include <emscripten.h>
    EMSCRIPTEN_KEEPALIVE
    int testInt(){
        return 69420;
    }
    

    【讨论】:

    • 嗨。现代CMake不鼓励使用add_definitions,因为它会影响所有目标,上面建议的target_compile_flags更可取。另外,根据Emscripten QAEMSCRIPTEN_KEEPALIVE also exports the function, as if it were on EXPORTED_FUNCTIONS.
    【解决方案2】:

    这是现在最简单/最干净的方法:

    target_link_options(target PRIVATE
            -sEXPORTED_FUNCTIONS=['_main','_foo','_bar'])
    

    如果你有更多的 -s 设置(你可能会),你可以在这个函数调用中添加它们,或者你可以多次调用 target_link_options,两者都可以。看起来很随和,我不需要逃避任何事情。

    【讨论】:

      【解决方案3】:

      我刚刚遇到了完全相同的问题,甚至在 Emscripten github 页面上启动了一个(请参阅here)。

      对我有用的是将所有 Emscripten 特定标志放入一个长字符串中,然后我添加了 target_compile_options 和 target_link_options。

        set(EMS
            "SHELL:-s EXPORTED_FUNCTIONS=['_main','_malloc','_int_sqrt'] -s EXTRA_EXPORTED_RUNTIME_METHODS=['ccall','cwrap']"
        )
        target_compile_options(EmscriptenExample PRIVATE ${EMS})
        target_link_options(EmscriptenExample PRIVATE ${EMS})
      

      重要从函数列表中删除双引号和空格,否则它将不起作用。至少 CMake 3.17.3 转义双引号对我不起作用。

      /编辑 为了完整起见:Emscripten 现在允许删除 -s 前缀和实际标志之间的空格。这使得实际使用 CMake 自己的 target_*_options 函数成为可能,例如:

      target_link_options(target PRIVATE -sEXPORTED_FUNCTIONS=['_main','_foo','_bar'])
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-18
        • 1970-01-01
        • 1970-01-01
        • 2017-12-28
        • 2018-04-02
        • 1970-01-01
        • 1970-01-01
        • 2021-05-17
        相关资源
        最近更新 更多