Skip to content

Commit ebf17f8

Browse files
authored
Enable support for multiple kernels for xeus-cpp-lite (#290)
* Enable support for multiple kernels for xeus-cpp-lite * Update constructor for wasm interpreter
1 parent 66510a4 commit ebf17f8

File tree

8 files changed

+70
-36
lines changed

8 files changed

+70
-36
lines changed

CMakeLists.txt

+6-20
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ function(configure_native_kernel kernel)
148148
endfunction()
149149

150150
function(configure_wasm_kernel kernel)
151+
set(XEUS_CPP_RESOURCE_DIR "/lib/clang/${CPPINTEROP_LLVM_VERSION_MAJOR}" PARENT_SCOPE)
151152

152153
configure_file (
153154
"${CMAKE_CURRENT_SOURCE_DIR}${kernel}wasm_kernel.json.in"
@@ -169,17 +170,9 @@ endfunction()
169170

170171
message("Configure kernels: ...")
171172
if(EMSCRIPTEN)
172-
# TODO: Currently jupyterlite-xeus and xeus-lite do not provide
173-
# methods to fetch information from the arguments present in the
174-
# generated emscripten kernel.
175-
# The following needs to be done here :
176-
# 1) We need to configure the kernel properly
177-
# Check issue https://github.com/compiler-research/xeus-cpp/issues/185.
178-
# 2) Once the above is done we need to add support in jupyterlite-xeus & xeus-lite
179-
# to be able to deal with arguments present in kernel.json
180-
# 3) Finally we should fetch the C++ version from the kernel.json file and
181-
# be able to pass it to our wasm interpreter rather than forcing a version.
173+
configure_wasm_kernel("/share/jupyter/kernels/xcpp17/")
182174
configure_wasm_kernel("/share/jupyter/kernels/xcpp20/")
175+
configure_wasm_kernel("/share/jupyter/kernels/xcpp23/")
183176
else()
184177
configure_native_kernel("/share/jupyter/kernels/xcpp17/")
185178
configure_native_kernel("/share/jupyter/kernels/xcpp20/")
@@ -444,20 +437,13 @@ if(EMSCRIPTEN)
444437
xeus_wasm_link_options(xcpp "web,worker")
445438
target_link_options(xcpp
446439
PUBLIC "SHELL: --preload-file ${SYSROOT_PATH}/include@/include"
440+
#PUBLIC "SHELL: --preload-file ${CMAKE_INSTALL_PREFIX}${XEUS_CPP_RESOURCE_DIR}@${XEUS_CPP_RESOURCE_DIR}"
447441
PUBLIC "SHELL: --preload-file ${XEUS_CPP_DATA_DIR}@/share/xeus-cpp"
448442
PUBLIC "SHELL: --preload-file ${XEUS_CPP_CONF_DIR}@/etc/xeus-cpp"
449443
PUBLIC "SHELL: --post-js ${CMAKE_CURRENT_SOURCE_DIR}/wasm_patches/post.js"
450444
)
451-
# TODO: Emscripten supports preloading files just once before it generates
452-
# the xcpp.data file (containing the binary representation of the file(s) we
453-
# want to include in our application).
454-
# Hence although we are adding support for Standard Headers, Libraries etc
455-
# through emscripten's sysroot for now, we need to do the following:
456-
# 1) Enable CppInterOp to provide us with a resource dir.
457-
# 2) If the above cannot be done, we can use the resource dir provided
458-
# by llvm on emscripten-forge but would involve adding a dependency.
459-
# 3) Shift the resource dir and the sysroot to a common location.
460-
# 4) Preload everything required together.
445+
# TODO: Uncomment the above line regarding preloading clang's resource dir
446+
# once has been supported through cppinterop.
461447
endif()
462448
# Tests
463449
# =====

include/xeus-cpp/xinterpreter_wasm.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace xcpp
1919
{
2020
public:
2121

22-
wasm_interpreter();
22+
wasm_interpreter(int argc = 0, char** argv = nullptr);
2323
virtual ~wasm_interpreter() = default;
2424

2525
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"display_name": "C++17",
3+
"argv": [
4+
"@XEUS_CPP_KERNELSPEC_PATH@xcpp",
5+
"-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
6+
"-std=c++17"
7+
],
8+
"language": "cpp",
9+
"metadata": {
10+
"debugger": false,
11+
"shared": {
12+
"libclangCppInterOp.so": "lib/libclangCppInterOp.so"
13+
}
14+
}
15+
}

share/jupyter/kernels/xcpp20/wasm_kernel.json.in

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
"display_name": "C++20",
33
"argv": [
44
"@XEUS_CPP_KERNELSPEC_PATH@xcpp",
5-
"-f",
6-
"{connection_file}",
5+
"-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
76
"-std=c++20"
87
],
98
"language": "cpp",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"display_name": "C++23",
3+
"argv": [
4+
"@XEUS_CPP_KERNELSPEC_PATH@xcpp",
5+
"-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
6+
"-std=c++23"
7+
],
8+
"language": "cpp",
9+
"metadata": {
10+
"debugger": false,
11+
"shared": {
12+
"libclangCppInterOp.so": "lib/libclangCppInterOp.so"
13+
}
14+
}
15+
}

src/main_emscripten_kernel.cpp

+22-1
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,30 @@
1515

1616
#include "xeus-cpp/xinterpreter_wasm.hpp"
1717

18+
template <class interpreter_type>
19+
static interpreter_type* builder_with_args(emscripten::val js_args)
20+
{
21+
// TODO: Refactor interpreter constructor to avoid static args-to-argv conversion.
22+
static std::vector<std::string> args = emscripten::vecFromJSArray<std::string>(js_args);
23+
static std::vector<const char*> argv_vec;
24+
25+
for (const auto& s : args)
26+
{
27+
argv_vec.push_back(s.c_str());
28+
}
29+
30+
int argc = static_cast<int>(argv_vec.size());
31+
char** argv = const_cast<char**>(argv_vec.data());
32+
33+
auto* res = new interpreter_type(argc, argv);
34+
argv_vec.clear();
35+
args.clear();
36+
return res;
37+
}
38+
1839
EMSCRIPTEN_BINDINGS(my_module)
1940
{
2041
xeus::export_core();
2142
using interpreter_type = xcpp::wasm_interpreter;
22-
xeus::export_kernel<interpreter_type>("xkernel");
43+
xeus::export_kernel<interpreter_type, &builder_with_args<interpreter_type>>("xkernel");
2344
}

src/xinterpreter.cpp

+8-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "xinput.hpp"
1919
#include "xinspect.hpp"
2020
#include "xmagics/os.hpp"
21+
#include <iostream>
2122
#ifndef EMSCRIPTEN
2223
#include "xmagics/xassist.hpp"
2324
#endif
@@ -27,25 +28,23 @@
2728
using Args = std::vector<const char*>;
2829

2930
void* createInterpreter(const Args &ExtraArgs = {}) {
30-
Args ClangArgs = {/*"-xc++"*/"-v"}; // ? {"-Xclang", "-emit-llvm-only", "-Xclang", "-diagnostic-log-file", "-Xclang", "-", "-xc++"};
31-
#ifdef EMSCRIPTEN
32-
ClangArgs.push_back("-std=c++20");
33-
#else
31+
Args ClangArgs = {/*"-xc++"*/"-v"};
3432
if (std::find_if(ExtraArgs.begin(), ExtraArgs.end(), [](const std::string& s) {
3533
return s == "-resource-dir";}) == ExtraArgs.end()) {
3634
std::string resource_dir = Cpp::DetectResourceDir();
37-
if (resource_dir.empty())
38-
std::cerr << "Failed to detect the resource-dir\n";
39-
ClangArgs.push_back("-resource-dir");
40-
ClangArgs.push_back(resource_dir.c_str());
35+
if (!resource_dir.empty()) {
36+
ClangArgs.push_back("-resource-dir");
37+
ClangArgs.push_back(resource_dir.c_str());
38+
} else {
39+
std::cerr << "Failed to detect the resource-dir\n";
40+
}
4141
}
4242
std::vector<std::string> CxxSystemIncludes;
4343
Cpp::DetectSystemCompilerIncludePaths(CxxSystemIncludes);
4444
for (const std::string& CxxInclude : CxxSystemIncludes) {
4545
ClangArgs.push_back("-isystem");
4646
ClangArgs.push_back(CxxInclude.c_str());
4747
}
48-
#endif
4948
ClangArgs.insert(ClangArgs.end(), ExtraArgs.begin(), ExtraArgs.end());
5049
// FIXME: We should process the kernel input options and conditionally pass
5150
// the gpu args here.

src/xinterpreter_wasm.cpp

+2-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@
1515

1616
namespace xcpp
1717
{
18-
19-
wasm_interpreter::wasm_interpreter()
20-
: interpreter(0, nullptr)
18+
wasm_interpreter::wasm_interpreter(int argc, char** argv)
19+
: interpreter(argc, argv)
2120
{
2221
}
2322
}

0 commit comments

Comments
 (0)