Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
fail-fast: false
matrix:
os: [ubuntu-22.04, ubuntu-24.04, macos-13]
os: [ubuntu-22.04, ubuntu-24.04, macos-14]
xeus_static_dependencies: [0]
xeus_build_shared_lib: [1]
include:
Expand Down Expand Up @@ -49,12 +49,13 @@ jobs:
-DCMAKE_PREFIX_PATH=$CONDA_PREFIX \
-DCMAKE_INSTALL_PREFIX=$CONDA_PREFIX \
-DXEUS_UV_STATIC_DEPENDENCIES=${{ matrix.xeus_static_dependencies }} \
-DXEUS_UV_BUILD_SHARED_LIBS=${{ matrix.xeus_build_shared_lib }}
-DXEUS_UV_BUILD_SHARED_LIBS=${{ matrix.xeus_build_shared_lib }} \
-DXEUS_UV_BUILD_STATIC_LIBS=$((1 - ${{ matrix.xeus_build_shared_lib }}))
working-directory: build

- name: Build
shell: bash -l {0}
run: make -j 4
run: make -j 2 install
working-directory: build

- name: Test xeus-uv
Expand Down
24 changes: 19 additions & 5 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
############################################################################
# Copyright (c) 2026, Dr. Thorsten Beier #
# Copyright (c) 2024, Isabel Paredes #
# Copyright (c) 2024, QuantStack #
# #
Expand All @@ -19,7 +20,7 @@ set(XEUS_UV_TEST_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test)
# ===========

# Project version
file(STRINGS "${XEUS_UV_INCLUDE_DIR}/xeus-uv/xeus-uv.hpp" xeus_uv_version_defines
file(STRINGS "${XEUS_UV_INCLUDE_DIR}/xeus-uv/xeus_uv.hpp" xeus_uv_version_defines
REGEX "#define XEUS_UV_VERSION_(MAJOR|MINOR|PATCH)")
foreach(ver ${xeus_uv_version_defines})
if(ver MATCHES "#define XEUS_UV_VERSION_(MAJOR|MINOR|PATCH) +([^ ]+)$")
Expand All @@ -33,7 +34,7 @@ message(STATUS "xeus-uv version: v${XEUS_UV_VERSION}")
# Binary version
# See the following URL for explanations about the binary versioning
# https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html#Updating-version-info
file(STRINGS "${XEUS_UV_INCLUDE_DIR}/xeus-uv/xeus-uv.hpp" xeus_uv_version_defines
file(STRINGS "${XEUS_UV_INCLUDE_DIR}/xeus-uv/xeus_uv.hpp" xeus_uv_version_defines
REGEX "#define XEUS_UV_BINARY_(CURRENT|REVISION|AGE)")
foreach(ver ${xeus_uv_version_defines})
if(ver MATCHES "#define XEUS_UV_BINARY_(CURRENT|REVISION|AGE) +([^ ]+)$")
Expand All @@ -49,7 +50,7 @@ message(STATUS "xeus-uv binary version: v${XEUS_UV_BINARY_VERSION}")

# Compilation options
option(XEUS_UV_BUILD_SHARED_LIBS "Build xeus shared library." ON)
option(XEUS_UV_BUILD_STATIC_LIBS "Build xeus static library (default if BUILD_SHARED_LIBS is OFF)." ON)
option(XEUS_UV_BUILD_STATIC_LIBS "Build xeus static library (default if BUILD_SHARED_LIBS is OFF)." OFF)
option(XEUS_UV_STATIC_DEPENDENCIES "link statically with xeus dependencies" OFF)

# Test options
Expand Down Expand Up @@ -87,6 +88,20 @@ endif()

find_package(xeus-zmq ${xeus_zmq_REQUIRED_VERSION} REQUIRED)

if(XEUS_UV_STATIC_DEPENDENCIES)
# for a static build, xeus-zmq-static links to cppzmq (header-only).
# even though we link **privately** to cppzmq, we need to add it here
# since the xeus-zmqTargets.cmake containts `\$<LINK_ONLY:cppzmq>` for xeus-zmq-static:
#
# set_target_properties(xeus-zmq-static PROPERTIES
# ....
# INTERFACE_LINK_LIBRARIES "nlohmann_json::nlohmann_json;xeus;\$<LINK_ONLY:cppzmq>;\$<LINK_ONLY:OpenSSL::Crypto>;-framework CoreFoundation"
# )
# without finding cppzmq here, the linker will believe that cppzmq is a library
# and complains about not finding it.
find_package(cppzmq REQUIRED)
endif()

find_library(UVW_LIBRARY uvw)
find_path(UVW_INCLUDE_DIR uvw.hpp)
message(STATUS "Found UVW_LIBRARY: ${UVW_LIBRARY}")
Expand All @@ -95,7 +110,7 @@ message(STATUS "Found UVW_LIBRARY: ${UVW_LIBRARY}")
# ============

set(XEUS_UV_HEADERS
${XEUS_UV_INCLUDE_DIR}/xeus-uv/xeus-uv.hpp
${XEUS_UV_INCLUDE_DIR}/xeus-uv/xeus_uv.hpp
${XEUS_UV_INCLUDE_DIR}/xeus-uv/xhook_base.hpp
${XEUS_UV_INCLUDE_DIR}/xeus-uv/xserver_uv.hpp
)
Expand All @@ -104,7 +119,6 @@ set(XEUS_UV_SOURCES
${XEUS_UV_SOURCE_DIR}/xhook_base.cpp
${XEUS_UV_SOURCE_DIR}/xserver_uv.cpp
${XEUS_UV_SOURCE_DIR}/xuv_runner.cpp
${XEUS_UV_SOURCE_DIR}/xuv_runner.hpp
)

# Targets and link
Expand Down
6 changes: 6 additions & 0 deletions environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,9 @@ dependencies:
- xeus-zmq>=3.0,<4.0
- libuvw
- nlohmann_json=3.11.3
- zeromq
- zeromq-static
- cppzmq
# Test dependencies
- pytest
- jupyter_kernel_test>=0.6,<0.7
File renamed without changes.
2 changes: 1 addition & 1 deletion include/xeus-uv/xhook_base.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <memory>
#include <uvw.hpp>

#include "xeus-uv.hpp"
#include "xeus_uv.hpp"


namespace xeus
Expand Down
5 changes: 2 additions & 3 deletions include/xeus-uv/xserver_uv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#include <memory>
#include <uvw.hpp>

#include "xeus-uv/xeus-uv.hpp"
#include "xeus-uv/xeus_uv.hpp"
#include "xeus-uv/xhook_base.hpp"

#include "xeus/xserver.hpp"
Expand All @@ -28,8 +28,7 @@ namespace nl = nlohmann;
namespace xeus
{

XEUX_UV_API
std::unique_ptr<xserver>
XEUS_UV_API std::unique_ptr<xserver>
make_xserver_uv(xcontext& context,
const xconfiguration& config,
nl::json::error_handler_t eh,
Expand Down
1 change: 1 addition & 0 deletions src/xserver_uv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "xuv_runner.hpp"

#include "xeus-uv/xhook_base.hpp"
#include "xeus-uv/xserver_uv.hpp"

#include "xeus-zmq/xcontrol_default_runner.hpp"
#include "xeus-zmq/xserver_zmq_split.hpp"
Expand Down
30 changes: 20 additions & 10 deletions src/xuv_runner.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

#include "xuv_runner.hpp"

#include "xeus-uv/xeus-uv.hpp"
#include "xeus-uv/xeus_uv.hpp"
#include "xeus-uv/xhook_base.hpp"


Expand All @@ -31,14 +31,19 @@ namespace xeus
std::cerr << "No loop provided, using default loop." << std::endl;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why removing this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...overenthusiastic cleanup

p_loop = uvw::loop::get_default();
}
create_polls();
}

}

void xuv_runner::run_impl()
{
create_polls(); // create poll used to be called in the constructor
// but that caused get_shell_fd to crash
// likely because zmq sockets were not yet ready???

p_shell_poll->start(uvw::poll_handle::poll_event_flags::READABLE);
p_controller_poll->start(uvw::poll_handle::poll_event_flags::READABLE);



if (p_hook)
{
p_hook->run(p_loop);
Expand All @@ -53,8 +58,12 @@ namespace xeus
{
// Get the file descriptor for the shell and controller sockets
// and create (libuv) poll handles to bind them to the loop
p_shell_poll = p_loop->resource<uvw::poll_handle>(get_shell_fd());
p_controller_poll = p_loop->resource<uvw::poll_handle>(get_shell_controller_fd());

auto fd_shell = get_shell_fd();
auto fd_controller = get_shell_controller_fd();

p_shell_poll = p_loop->resource<uvw::poll_handle>(fd_shell);
p_controller_poll = p_loop->resource<uvw::poll_handle>(fd_controller);

p_shell_poll->on<uvw::poll_event>(
[this](uvw::poll_event&, uvw::poll_handle&)
Expand All @@ -64,12 +73,13 @@ namespace xeus
this->p_hook->pre_hook();
}

int ZMQ_DONTWAIT{ 1 }; // from zmq.h
if (auto msg = read_shell(ZMQ_DONTWAIT))
int ZMQ_DONTWAIT{ 1 }; // from zmq.h
while (auto msg = read_shell(ZMQ_DONTWAIT))
{
notify_shell_listener(std::move(msg.value()));
}


if (this->p_hook)
{
this->p_hook->post_hook();
Expand All @@ -86,7 +96,7 @@ namespace xeus
}

int ZMQ_DONTWAIT{ 1 }; // from zmq.h
if (auto msg = read_controller(ZMQ_DONTWAIT))
while (auto msg = read_controller(ZMQ_DONTWAIT))
{
std::string val{ msg.value() };
if (val == "stop")
Expand Down Expand Up @@ -114,14 +124,14 @@ namespace xeus
std::cerr << e.what() << std::endl;
}
);

p_controller_poll->on<uvw::error_event>(
[](const uvw::error_event& e, uvw::poll_handle&)
{
std::cerr << e.what() << std::endl;
}
);


}

} // namespace xeus
3 changes: 1 addition & 2 deletions src/xuv_runner.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,8 @@
#include <memory>
#include <uvw.hpp>

#include "xeus-uv/xeus-uv.hpp"
#include "xeus-uv/xeus_uv.hpp"
#include "xeus-uv/xhook_base.hpp"

#include "xeus-zmq/xshell_runner.hpp"


Expand Down
59 changes: 49 additions & 10 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
############################################################################
# Copyright (c) 2026, Dr. Thorsten Beier #
# Copyright (c) 2024, Isabel Paredes #
# Copyright (c) 2024, QuantStack #
# #
Expand All @@ -7,18 +8,56 @@
# The full license is in the file LICENSE, distributed with this software. #
############################################################################

# Unit tests
# ==========

cmake_minimum_required(VERSION 3.10)

if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
project(xeus-uv-test)

enable_testing()
# add test executable
add_executable(test_kernel
xmock_interpreter.cpp
main.cpp)

find_package(xeus-uv REQUIRED CONFIG)
find_package(nlohmann_json QUIET CONFIG)

set(XEUS_UV_TEST_DIR ${CMAKE_CURRENT_LIST_DIR})
endif ()

# link to xeus-uv and xeus-zmq
if(XEUS_UV_BUILD_SHARED_LIBS)
target_link_libraries(test_kernel PRIVATE xeus-uv)
else()
target_link_libraries(test_kernel PRIVATE xeus-uv-static xeus-zmq-static)
endif()

target_compile_definitions(test_kernel PUBLIC UVW_AS_LIB)


target_compile_features(test_kernel PRIVATE cxx_std_17)

# include current source dir for xmock_interpreter.hpp
target_include_directories(test_kernel PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/include
${UVW_INCLUDE_DIRS}
)


enable_testing()


find_program(PYTEST
NAMES pytest-3 pytest py.test-3 py.test REQUIRED)


configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/test_kernel/kernel.json.in"
"kernels/test_kernel/kernel.json"
)


configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/test_kernel.py"
"${CMAKE_CURRENT_BINARY_DIR}/"
COPYONLY)

add_test(NAME test_kernel
COMMAND ${PYTEST} test_kernel.py)
set_tests_properties(test_kernel
PROPERTIES
ENVIRONMENT "JUPYTER_PATH=${CMAKE_CURRENT_BINARY_DIR}")
48 changes: 48 additions & 0 deletions test/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/***************************************************************************
* Copyright (c) 2026, Dr. Thorsten Beier *
* Copyright (c) 2016, Johan Mabille and Sylvain Corlay *
* *
* Distributed under the terms of the BSD 3-Clause License. *
* *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#include <iostream>
#include <memory>

#include "xeus/xkernel.hpp"
#include "xeus/xkernel_configuration.hpp"
#include "xeus-zmq/xzmq_context.hpp"
#include "xeus-zmq/xserver_zmq.hpp"
#include "xmock_interpreter.hpp"

#include "xeus-uv/xserver_uv.hpp"
#include "xeus-uv/xhook_base.hpp"

#include <uvw.hpp>

int main(int argc, char* argv[])
{
std::string file_name = (argc == 1) ? "connection.json" : argv[2];
xeus::xconfiguration config = xeus::load_configuration(file_name);

auto context = xeus::make_zmq_context();

auto make_xserver = [&](xeus::xcontext& context,
const xeus::xconfiguration& config,
nl::json::error_handler_t eh) {
return xeus::make_xserver_uv(context, config, eh);
};

using interpreter_ptr = std::unique_ptr<xeus::xmock_interpreter>;
interpreter_ptr interpreter = interpreter_ptr(new xeus::xmock_interpreter());
xeus::xkernel kernel(config,
xeus::get_user_name(),
std::move(context),
std::move(interpreter),
make_xserver);
std::cout << "starting kernel" << std::endl;
kernel.start();

return 0;
}
Loading