Skip to content

Commit 23913f6

Browse files
authored
Add Initial Support for xeus-cpp-lite (#199)
1 parent a7649c0 commit 23913f6

File tree

5 files changed

+62
-13
lines changed

5 files changed

+62
-13
lines changed

.github/workflows/deploy-github-page.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,13 +59,15 @@ jobs:
5959
echo "PREFIX=$PREFIX" >> $GITHUB_ENV
6060
export CMAKE_PREFIX_PATH=$PREFIX
6161
export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX
62+
export SYSROOT_PATH=$HOME/emsdk/upstream/emscripten/cache/sysroot
6263
6364
emcmake cmake \
6465
-DCMAKE_BUILD_TYPE=Release \
6566
-DCMAKE_PREFIX_PATH=$PREFIX \
6667
-DCMAKE_INSTALL_PREFIX=$PREFIX \
6768
-DXEUS_CPP_EMSCRIPTEN_WASM_BUILD=ON \
6869
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
70+
-DSYSROOT_PATH=$SYSROOT_PATH \
6971
..
7072
emmake make -j ${{ env.ncpus }} install
7173
@@ -76,6 +78,8 @@ jobs:
7678
micromamba activate xeus-lite-host
7779
python -m pip install jupyterlite-xeus
7880
jupyter lite build --XeusAddon.prefix=${{ env.PREFIX }} --output-dir dist
81+
cp xcpp.data dist/extensions/@jupyterlite/xeus/static
82+
cp $PREFIX/lib/libclangCppInterOp.so dist/extensions/@jupyterlite/xeus/static
7983
mkdir -p dist/files
8084
mv notebooks dist/files
8185
mv README.md dist/files

.github/workflows/main.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,13 +257,15 @@ jobs:
257257
echo "PREFIX=$PREFIX" >> $GITHUB_ENV
258258
export CMAKE_PREFIX_PATH=$PREFIX
259259
export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX
260+
export SYSROOT_PATH=$HOME/emsdk/upstream/emscripten/cache/sysroot
260261
261262
emcmake cmake \
262263
-DCMAKE_BUILD_TYPE=Release \
263264
-DCMAKE_PREFIX_PATH=$PREFIX \
264265
-DCMAKE_INSTALL_PREFIX=$PREFIX \
265266
-DXEUS_CPP_EMSCRIPTEN_WASM_BUILD=ON \
266267
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
268+
-DSYSROOT_PATH=$SYSROOT_PATH \
267269
..
268270
emmake make -j ${{ env.ncpus }} install
269271
@@ -274,6 +276,8 @@ jobs:
274276
micromamba activate xeus-lite-host
275277
python -m pip install jupyterlite-xeus
276278
jupyter lite build --XeusAddon.prefix=${{ env.PREFIX }}
279+
cp xcpp.data _output/extensions/@jupyterlite/xeus/static
280+
cp $PREFIX/lib/libclangCppInterOp.so _output/extensions/@jupyterlite/xeus/static
277281
278282
- name: Setup tmate session
279283
if: ${{ failure() && runner.debug }}

CMakeLists.txt

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ if(EMSCRIPTEN)
8484
set(XEUS_CPP_USE_SHARED_XEUS_CPP OFF)
8585
set(XEUS_CPP_BUILD_TESTS OFF)
8686
# ENV (https://github.com/emscripten-core/emscripten/commit/6d9681ad04f60b41ef6345ab06c29bbc9eeb84e0)
87-
set(EMSCRIPTEN_FEATURES "${EMSCRIPTEN_FEATURES} -s \"EXTRA_EXPORTED_RUNTIME_METHODS=[ENV']\"")
87+
set(EMSCRIPTEN_FEATURES "${EMSCRIPTEN_FEATURES} -s \"EXPORTED_RUNTIME_METHODS=[ENV']\"")
8888
endif()
8989

9090
# Dependencies
@@ -152,8 +152,22 @@ function(configure_kernel kernel)
152152
endfunction()
153153

154154
message("Configure kernels: ...")
155-
configure_kernel("/share/jupyter/kernels/xcpp17/")
156-
configure_kernel("/share/jupyter/kernels/xcpp20/")
155+
if(EMSCRIPTEN)
156+
# TODO: Currently jupyterlite-xeus and xeus-lite do not provide
157+
# methods to fetch information from the arguments present in the
158+
# generated emscripten kernel.
159+
# The following needs to be done here :
160+
# 1) We need to configure the kernel properly
161+
# Check issue https://github.com/compiler-research/xeus-cpp/issues/185.
162+
# 2) Once the above is done we need to add support in jupyterlite-xeus & xeus-lite
163+
# to be able to deal with arguments present in kernel.json
164+
# 3) Finally we should fetch the C++ version from the kernel.json file and
165+
# be able to pass it to our wasm interpreter rather than forcing a version.
166+
configure_kernel("/share/jupyter/kernels/xcpp20/")
167+
else()
168+
configure_kernel("/share/jupyter/kernels/xcpp17/")
169+
configure_kernel("/share/jupyter/kernels/xcpp20/")
170+
endif()
157171

158172
# Source files
159173
# ============
@@ -401,8 +415,24 @@ if(EMSCRIPTEN)
401415
xeus_cpp_set_kernel_options(xcpp)
402416
xeus_wasm_compile_options(xcpp)
403417
xeus_wasm_link_options(xcpp "web,worker")
418+
# TODO: Remove the exported runtime methods
419+
# after the next xeus release.
420+
target_link_options(xcpp PUBLIC
421+
-sEXPORTED_RUNTIME_METHODS=FS,PATH,ERRNO_CODES
422+
# add sysroot location here
423+
--preload-file ${SYSROOT_PATH}/include@/include
424+
)
425+
# TODO: Emscripten supports preloading files just once before it generates
426+
# the xcpp.data file (containing the binary representation of the file(s) we
427+
# want to include in our application).
428+
# Hence although we are adding support for Standard Headers, Libraries etc
429+
# through emscripten's sysroot for now, we need to do the following:
430+
# 1) Enable CppInterOp to provide us with a resource dir.
431+
# 2) If the above cannot be done, we can use the resource dir provided
432+
# by llvm on emscripten-forge but would involve adding a dependency.
433+
# 3) Shift the resource dir and the sysroot to a common location.
434+
# 4) Preload everything required together.
404435
endif()
405-
406436
# Tests
407437
# =====
408438

@@ -492,6 +522,7 @@ if(EMSCRIPTEN)
492522
install(FILES
493523
"$<TARGET_FILE_DIR:xcpp>/xcpp.js"
494524
"$<TARGET_FILE_DIR:xcpp>/xcpp.wasm"
525+
"$<TARGET_FILE_DIR:xcpp>/xcpp.data"
495526
DESTINATION ${CMAKE_INSTALL_BINDIR})
496527
endif ()
497528

README.md

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,15 @@ pushd build
8787
export PREFIX=$MAMBA_ROOT_PREFIX/envs/xeus-cpp-wasm-host
8888
export CMAKE_PREFIX_PATH=$PREFIX
8989
export CMAKE_SYSTEM_PREFIX_PATH=$PREFIX
90+
export SYSROOT_PATH=$HOME/emsdk/upstream/emscripten/cache/sysroot
9091

9192
emcmake cmake \
9293
-DCMAKE_BUILD_TYPE=Release \
9394
-DCMAKE_PREFIX_PATH=$PREFIX \
9495
-DCMAKE_INSTALL_PREFIX=$PREFIX \
9596
-DXEUS_CPP_EMSCRIPTEN_WASM_BUILD=ON \
9697
-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=ON \
98+
-DSYSROOT_PATH=$SYSROOT_PATH \
9799
..
98100
emmake make install
99101
```
@@ -105,12 +107,20 @@ micromamba activate xeus-lite-host
105107
python -m pip install jupyterlite-xeus
106108
jupyter lite build --XeusAddon.prefix=$PREFIX
107109
```
110+
111+
We now need to shift necessary files like `xcpp.data` which contains the binary representation of the file(s)
112+
we want to include in our application. As of now this would contain all important files like Standard Headers,
113+
Libraries etc coming out of emscripten's sysroot. Assuming we are still inside build we should do the following
114+
```bash
115+
cp xcpp.data _output/extensions/@jupyterlite/xeus/static
116+
cp $PREFIX/lib/libclangCppInterOp.so _output/extensions/@jupyterlite/xeus/static
117+
```
118+
108119
Once the Jupyter Lite site has built you can test the website locally by executing
109120
```bash
110121
jupyter lite serve --XeusAddon.prefix=$PREFIX
111122
```
112123

113-
114124
## Trying it online
115125

116126
To try out xeus-cpp interactively in your web browser, just click on the binder link:

src/xinterpreter.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ using Args = std::vector<const char*>;
2828

2929
void* createInterpreter(const Args &ExtraArgs = {}) {
3030
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
3134
if (std::find_if(ExtraArgs.begin(), ExtraArgs.end(), [](const std::string& s) {
3235
return s == "-resource-dir";}) == ExtraArgs.end()) {
3336
std::string resource_dir = Cpp::DetectResourceDir();
@@ -42,6 +45,7 @@ void* createInterpreter(const Args &ExtraArgs = {}) {
4245
ClangArgs.push_back("-isystem");
4346
ClangArgs.push_back(CxxInclude.c_str());
4447
}
48+
#endif
4549
ClangArgs.insert(ClangArgs.end(), ExtraArgs.begin(), ExtraArgs.end());
4650
// FIXME: We should process the kernel input options and conditionally pass
4751
// the gpu args here.
@@ -73,6 +77,7 @@ namespace xcpp
7377
static std::string get_stdopt()
7478
{
7579
// We need to find what's the C++ version the interpreter runs with.
80+
#ifndef EMSCRIPTEN
7681
const char* code = R"(
7782
int __get_cxx_version () {
7883
#if __cplusplus > 202302L
@@ -93,12 +98,13 @@ int __get_cxx_version () {
9398
}
9499
__get_cxx_version ()
95100
)";
96-
97101
auto cxx_version = Cpp::Evaluate(code);
98102
return std::to_string(cxx_version);
103+
#else
104+
return "20";
105+
#endif
99106
}
100107

101-
102108
interpreter::interpreter(int argc, const char* const* argv) :
103109
xmagics()
104110
, p_cout_strbuf(nullptr)
@@ -110,7 +116,6 @@ __get_cxx_version ()
110116
createInterpreter(Args(argv ? argv + 1 : argv, argv + argc));
111117
m_version = get_stdopt();
112118
redirect_output();
113-
init_includes();
114119
init_preamble();
115120
init_magic();
116121
}
@@ -355,11 +360,6 @@ __get_cxx_version ()
355360
publish_stream("stderr", s);
356361
}
357362

358-
void interpreter::init_includes()
359-
{
360-
Cpp::AddIncludePath((xeus::prefix_path() + "/include/").c_str());
361-
}
362-
363363
void interpreter::init_preamble()
364364
{
365365
//NOLINTBEGIN(cppcoreguidelines-owning-memory)

0 commit comments

Comments
 (0)