Skip to content

Commit d788185

Browse files
supporting cppyy
1 parent 64e0919 commit d788185

File tree

5 files changed

+160
-1
lines changed

5 files changed

+160
-1
lines changed

CMakeLists.txt

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ set(XEUS_CPP_SRC
189189
src/xparser.cpp
190190
src/xutils.cpp
191191
src/xmagics/os.cpp
192+
193+
# magics
194+
src/xmagics/pythonexec.cpp
192195
)
193196

194197
if(NOT EMSCRIPTEN)
@@ -348,6 +351,31 @@ macro(xeus_cpp_create_target target_name linkage output_name)
348351
target_link_libraries(${target_name} PRIVATE ${CMAKE_THREAD_LIBS_INIT})
349352
endif()
350353

354+
# Python Stuff
355+
if(NOT EMSCRIPTEN)
356+
find_package(Python COMPONENTS Interpreter Development)
357+
358+
target_include_directories(${target_name} PRIVATE ${Python_INCLUDE_DIRS})
359+
target_link_libraries(${target_name} PUBLIC ${Python_LIBRARIES})
360+
target_compile_options(${target_name} PRIVATE ${Python_CFLAGS_OTHER})
361+
else()
362+
set(Python_INCLUDE_DIRS
363+
"${CMAKE_PREFIX_PATH}/include/python3.11")
364+
set(Python_LIBRARIES
365+
"python3.11"
366+
"m"
367+
"bz2"
368+
"libz.a"
369+
"sqlite3"
370+
"ffi"
371+
)
372+
set(Python_CFLAGS_OTHER "-sUSE_ZLIB=1" "-sUSE_BZIP2=1")
373+
374+
target_include_directories(${target_name} PRIVATE ${Python_INCLUDE_DIRS})
375+
target_link_libraries(${target_name} PUBLIC ${Python_LIBRARIES})
376+
target_compile_options(${target_name} PRIVATE ${Python_CFLAGS_OTHER})
377+
endif()
378+
351379
endmacro()
352380

353381
# xeus-cpp-headers
@@ -416,6 +444,7 @@ if(EMSCRIPTEN)
416444
endif()
417445
include(WasmBuildOptions)
418446
find_package(xeus-lite ${xeus_lite_REQUIRED_VERSION} REQUIRED)
447+
link_directories(BEFORE "${CMAKE_INSTALL_PREFIX}/lib")
419448
add_executable(xcpp src/main_emscripten_kernel.cpp )
420449
target_link_libraries(xcpp PRIVATE xeus-lite)
421450
xeus_cpp_set_kernel_options(xcpp)
@@ -429,6 +458,14 @@ if(EMSCRIPTEN)
429458
PUBLIC "SHELL: -s USE_SDL=2"
430459
PUBLIC "SHELL: --preload-file ${ESCAPED_SYSROOT_PATH}/include@/include"
431460
PUBLIC "SHELL: --preload-file ${ESCAPED_XEUS_CPP_RESOURCE_DIR}@/${CMAKE_INSTALL_LIBDIR}/clang/${CPPINTEROP_LLVM_VERSION_MAJOR}"
461+
PUBLIC "SHELL: --preload-file ${CPyCppyy_DIR}/include/CPyCppyy@/include/CPyCppyy"
462+
PUBLIC "SHELL: --preload-file ${CPyCppyy_BUILD_DIR}/libcppyy.so@/lib/python3.11/site-packages/libcppyy.so"
463+
PUBLIC "SHELL: --preload-file ${Cppyy_Backend_DIR}/python/cppyy_backend@/lib/python3.11/site-packages/cppyy_backend"
464+
PUBLIC "SHELL: --preload-file ${Cppyy_DIR}/python/cppyy@/lib/python3.11/site-packages/cppyy"
465+
PUBLIC "SHELL: --preload-file ${Cppyy_DIR}/python/cppyy_compat@/lib/python3.11/site-packages/cppyy_compat"
466+
PUBLIC "SHELL: --preload-file ${CMAKE_PREFIX_PATH}/lib/python3.11@/lib/python3.11"
467+
PUBLIC "SHELL: --preload-file ${CMAKE_PREFIX_PATH}/include/clang@/include/clang"
468+
PUBLIC "SHELL: --preload-file ${CMAKE_PREFIX_PATH}/include/clang-c@/include/clang-c"
432469
PUBLIC "SHELL: --post-js ${CMAKE_CURRENT_SOURCE_DIR}/wasm_patches/post.js"
433470
)
434471
endif()

environment-wasm-host.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,8 @@ dependencies:
1010
- cpp-argparse
1111
- pugixml
1212
- doctest
13+
- python=3.12
14+
- bzip2
15+
- zlib
16+
- libffi
17+
- sqlite

src/xinterpreter.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#ifndef EMSCRIPTEN
2323
#include "xmagics/xassist.hpp"
2424
#endif
25+
#include "xmagics/pythonexec.hpp"
2526
#include "xparser.hpp"
2627
#include "xsystem.hpp"
2728

@@ -370,7 +371,7 @@ __get_cxx_version ()
370371
// executable(m_interpreter));
371372
// preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("timeit",
372373
// timeit(&m_interpreter));
373-
// preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("python", pythonexec());
374+
preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("python", pythonexec());
374375
preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("file", writefile());
375376
#ifndef EMSCRIPTEN
376377
preamble_manager["magics"].get_cast<xmagics_manager>().register_magic("xassist", xassist());

src/xmagics/pythonexec.cpp

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/************************************************************************************
2+
* Copyright (c) 2025, xeus-cpp contributors *
3+
* *
4+
* Distributed under the terms of the BSD 3-Clause License. *
5+
* *
6+
* The full license is in the file LICENSE, distributed with this software. *
7+
************************************************************************************/
8+
9+
#include "pythonexec.hpp"
10+
#include "../xparser.hpp"
11+
#include <string>
12+
13+
#include "Python.h"
14+
15+
#include "clang/Interpreter/CppInterOp.h"
16+
17+
namespace xcpp {
18+
bool pythonexec::is_initalized = false;
19+
20+
void pythonexec::operator()([[maybe_unused]] const std::string& line, const std::string& cell) {
21+
22+
if (!is_initalized)
23+
initialize();
24+
if (!is_initalized) {
25+
// initializing failed
26+
std::cout << Cpp::EndStdStreamCapture();
27+
std::cerr << Cpp::EndStdStreamCapture();
28+
29+
std::cerr << "Failed to Initialize Python\n";
30+
return;
31+
}
32+
33+
std::string code = trim(cell);
34+
if (code.empty())
35+
return;
36+
37+
Cpp::BeginStdStreamCapture(Cpp::kStdErr);
38+
Cpp::BeginStdStreamCapture(Cpp::kStdOut);
39+
40+
PyRun_SimpleString(code.c_str());
41+
42+
std::cout << Cpp::EndStdStreamCapture();
43+
std::cerr << Cpp::EndStdStreamCapture();
44+
}
45+
46+
void pythonexec::initialize() {
47+
#ifdef EMSCRIPTEN
48+
PyStatus status;
49+
50+
PyConfig config;
51+
PyConfig_InitPythonConfig(&config);
52+
static const std::wstring prefix(L"/");
53+
config.base_prefix = const_cast<wchar_t*>(prefix.c_str());
54+
config.base_exec_prefix = const_cast<wchar_t*>(prefix.c_str());
55+
config.prefix = const_cast<wchar_t*>(prefix.c_str());
56+
config.exec_prefix = const_cast<wchar_t*>(prefix.c_str());
57+
58+
status = Py_InitializeFromConfig(&config);
59+
if (PyStatus_Exception(status)) {
60+
// TODO: initialization failed, propagate error
61+
PyConfig_Clear(&config);
62+
is_initalized = false;
63+
return;
64+
}
65+
PyConfig_Clear(&config);
66+
#else
67+
Py_Initialize();
68+
#endif
69+
70+
PyRun_SimpleString("import sys\nsys.path.append('')"); // add current directory to PYTHONPATH
71+
72+
// // Import cppyy module
73+
// PyObject* cppyyModule = PyImport_ImportModule("cppyy");
74+
// if (!cppyyModule) {
75+
// PyErr_Print();
76+
// Py_Finalize();
77+
// return; // Handle import error as needed
78+
// }
79+
80+
// PyObject* mainModule = PyImport_AddModule("__main__");
81+
// PyObject_SetAttrString(mainModule, "cppyy", cppyyModule);
82+
// Py_XDECREF(cppyyModule);
83+
84+
is_initalized = true;
85+
}
86+
} // namespace xcpp

src/xmagics/pythonexec.hpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/************************************************************************************
2+
* Copyright (c) 2025, xeus-cpp contributors *
3+
* *
4+
* Distributed under the terms of the BSD 3-Clause License. *
5+
* *
6+
* The full license is in the file LICENSE, distributed with this software. *
7+
************************************************************************************/
8+
9+
#ifndef XEUS_CPP_PYTHONEXEC_MAGIC_HPP
10+
#define XEUS_CPP_PYTHONEXEC_MAGIC_HPP
11+
12+
#include <string>
13+
14+
#include "xeus-cpp/xmagics.hpp"
15+
16+
namespace xcpp
17+
{
18+
class pythonexec : public xmagic_cell
19+
{
20+
public:
21+
XEUS_CPP_API
22+
void operator()(const std::string& line, const std::string& cell) override;
23+
private:
24+
static bool is_initalized;
25+
void initialize();
26+
27+
};
28+
} // namespace xcpp
29+
30+
#endif //XEUS_CPP_PYTHONEXEC_MAGIC_HPP

0 commit comments

Comments
 (0)