使用 CMake 时如何在 Emscripten 中导出 C 函数
How to export C function in Emscripten when using CMake
在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"]')
或者做类似的事情?
到目前为止我想通的是,可以通过以下设置实现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;
}
我只是 运行 遇到了完全相同的问题,甚至在 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'])
现在是simplest/cleanest方式:
target_link_options(target PRIVATE
-sEXPORTED_FUNCTIONS=['_main','_foo','_bar'])
如果您有更多 -s 设置(您可能会有),您可以在此函数调用中添加它们,或者您可以多次调用 target_link_options,两者都有效。好像挺贴心的,什么都不用逃避了。
在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"]')
或者做类似的事情?
到目前为止我想通的是,可以通过以下设置实现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;
}
我只是 运行 遇到了完全相同的问题,甚至在 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'])
现在是simplest/cleanest方式:
target_link_options(target PRIVATE
-sEXPORTED_FUNCTIONS=['_main','_foo','_bar'])
如果您有更多 -s 设置(您可能会有),您可以在此函数调用中添加它们,或者您可以多次调用 target_link_options,两者都有效。好像挺贴心的,什么都不用逃避了。