Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用CMake时如何在Emscripten中导出C函数_C_Cmake_Emscripten_Emmake - Fatal编程技术网

使用CMake时如何在Emscripten中导出C函数

使用CMake时如何在Emscripten中导出C函数,c,cmake,emscripten,emmake,C,Cmake,Emscripten,Emmake,其中显示了以下导出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 在e

其中显示了以下导出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"]')

或者做类似的事情?

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

# 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>

模块['onRuntimeInitialized']=函数(){
日志(“wasm加载”);
console.log(Module.ccall);//确保它不是未定义的
console.log(Module.\u testInt);//确保它不是未定义的
console.log(Module.\u testInt());//这应该可以工作
log(Module.ccall('testInt',//C函数的名称
'number',//返回类型
[],//参数类型
[])//参数值
);
}
这是我对C函数的定义:

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

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

对我来说,有效的方法是将所有特定于Emscripten的标志放入一个长字符串中,然后添加target_compile_选项和target_link_选项

  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_link_options(target PRIVATE -sEXPORTED_FUNCTIONS=['_main','_foo','_bar'])

这是目前最简单/最干净的方法:

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

如果你有更多的-s设置(你可能会),你可以在这个函数调用中添加它们,或者你可以多次调用target\u link\u选项,这两种方法都可以。这似乎很方便,我不需要逃避任何事情。

嗨。现代CMake ot不鼓励使用
add\u definitions
,因为它会影响所有目标,因此建议使用上述
target\u compile\u标志。此外,根据:
EMSCRIPTEN\u KEEPALIVE还导出函数,就像导出函数一样。