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
53 changes: 30 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ set(CMAKE_CXX_EXTENSIONS NO)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED TRUE)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

include(GNUInstallDirs)

set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}")

set(XEUS_CPP_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
Expand All @@ -33,20 +37,6 @@ set(${PROJECT_NAME}_VERSION
${XEUS_CPP_VERSION_MAJOR}.${XEUS_CPP_VERSION_MINOR}.${XEUS_CPP_VERSION_PATCH})
message(STATUS "Building xeus-cpp v${${PROJECT_NAME}_VERSION}")

# Configuration
# =============

include(GNUInstallDirs)

if (NOT DEFINED XEUS_CPP_KERNELSPEC_PATH)
set(XEUS_CPP_KERNELSPEC_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/")
endif ()

configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xcpp/kernel.json.in"
"${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xcpp/kernel.json"
)

# Build options
# =============

Expand Down Expand Up @@ -121,13 +111,29 @@ if(EMSCRIPTEN)
set(EMSCRIPTEN_FEATURES "${EMSCRIPTEN_FEATURES} -s \"EXTRA_EXPORTED_RUNTIME_METHODS=[ENV']\"")
endif()

find_package(Clang REQUIRED)
include(AddLLVM)
include(HandleLLVMOptions)
add_definitions(${LLVM_DEFINITIONS})
find_package(CppInterOp REQUIRED)
if(CppInterOp_FOUND)
message(STATUS "Found CppInterOp: config=${CPPINTEROP_CONFIG} dir=${CPPINTEROP_DIR} (found version=${CPPINTEROP_VERSION} compatible with Clang ${CPPINTEROP_LLVM_VERSION_MAJOR}.x)")
endif()

find_package(argparse REQUIRED)
find_package(pugixml REQUIRED)

# Configuration
# =============

if (NOT DEFINED XEUS_CPP_KERNELSPEC_PATH)
set(XEUS_CPP_KERNELSPEC_PATH "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_BINDIR}/")
endif ()

set(XEUS_CPP_PATH "$ENV{PATH}")
set(XEUS_CPP_LD_LIBRARY_PATH "$ENV{LD_LIBRARY_PATH}")
set(XEUS_CPP_RESOURCE_DIR ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}/clang/${CppInterOp_CLANG_VERSION})
configure_file (
"${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels/xcpp/kernel.json.in"
"${CMAKE_CURRENT_BINARY_DIR}/share/jupyter/kernels/xcpp/kernel.json"
)
Copy link
Collaborator

@SylvainCorlay SylvainCorlay Apr 2, 2024

Choose a reason for hiding this comment

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

What is the benefit of this version compared to the previous one?

(trying to understand better because keeping cmake files of xeus-based kernels similar makes it easier to make changes across all kernels).


# Source files
# ============

Expand Down Expand Up @@ -174,7 +180,8 @@ include(CheckCXXCompilerFlag)

string(TOUPPER "${CMAKE_BUILD_TYPE}" U_CMAKE_BUILD_TYPE)

set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib; ${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib;${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_LIBDIR}")
list(REMOVE_DUPLICATES CMAKE_INSTALL_RPATH)

macro(xeus_cpp_set_common_options target_name)
if (MSVC)
Expand Down Expand Up @@ -228,7 +235,6 @@ macro(xeus_cpp_set_kernel_options target_name)
find_package(Threads)
target_link_libraries(${target_name} PRIVATE ${CMAKE_THREAD_LIBS_INIT})
endif()

endmacro()

# Common macro for shared and static library
Expand Down Expand Up @@ -264,7 +270,8 @@ macro(xeus_cpp_create_target target_name linkage output_name)
set(XEUS_CPP_XEUS_TARGET xeus-static)
endif ()

target_link_libraries(${target_name} PUBLIC ${XEUS_CPP_XEUS_TARGET} clangInterpreter pugixml argparse::argparse xtl)
target_link_libraries(${target_name} PUBLIC ${XEUS_CPP_XEUS_TARGET} clangCppInterOp pugixml argparse::argparse xtl)

if (WIN32 OR CYGWIN)
#
elseif (APPLE)
Expand All @@ -274,7 +281,7 @@ macro(xeus_cpp_create_target target_name linkage output_name)
find_package(Threads) # TODO: add Threads as a dependence of xeus-static?
target_link_libraries(${target_name} PRIVATE ${CMAKE_THREAD_LIBS_INIT})
endif()

endmacro()

# xeus-cpp-headers
Expand Down Expand Up @@ -371,7 +378,7 @@ if(XEUS_CPP_BUILD_EXECUTABLE OR EMSCRIPTEN)
set(XJUPYTER_DATA_DIR "share/jupyter" CACHE STRING "Jupyter data directory")

# Install xcpp Jupyter kernelspec
set(KERNELSPEC_DIR ${CMAKE_CURRENT_SOURCE_DIR}/share/jupyter/kernels)
set(KERNELSPEC_DIR ${CMAKE_CURRENT_BINARY_DIR}/share/jupyter/kernels)
install(DIRECTORY ${KERNELSPEC_DIR}
DESTINATION ${XJUPYTER_DATA_DIR}
PATTERN "*.in" EXCLUDE)
Expand Down
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ source activate "xeus-cpp"
```
We will now install the dependencies needed to compile xeux-cpp from source within this environment by executing the following
```bash
mamba install notebook cmake cxx-compiler xeus-zmq nlohmann_json=3.11.2 cppzmq xtl jupyterlab clangdev=16 cpp-argparse pugixml doctest -c conda-forge
mamba install notebook cmake cxx-compiler xeus-zmq nlohmann_json=3.11.2 cppzmq xtl jupyterlab CppInterOp cpp-argparse<3.1 pugixml doctest -c conda-forge
```
Now you can compile the kernel from the source by executing (replace `$CONDA_PREFIX` with a custom installation prefix if need be)
```bash
Expand Down Expand Up @@ -65,13 +65,13 @@ http://xeus-cpp.readthedocs.io
- [clang](https://github.com/llvm/llvm-project/)
- [argparse](https://github.com/p-ranav/argparse)

| `xeus-cpp` | `xeus-zmq` | `xtl` | `clang` | `pugixml` | `cppzmq` | `cpp-argparse`| `nlohmann_json` | `dirent` (windows only) |
|------------|-----------------|-----------------|-----------|-----------|----------|---------------|-----------------|-------------------------|
| main | >=1.0.0,<2.0.0 | >=0.7.7,<0.8.0 | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |
| 0.3.0 | >=1.0.0,<2.0.0 | >=0.7.7,<0.8.0 | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |
| 0.2.0 | >=1.0.0,<2.0.0 | >=0.7.7,<0.8.0 | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |
| 0.1.0 | >=1.0.0,<2.0.0 | >=0.7.0,<0.8.0 | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |
| 0.0.1 | >=1.0.0,<2.0.0 | >=0.7.0,<0.8.0 | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |
| `xeus-cpp` | `xeus-zmq` | `xtl` | `CppInterOp` | `clang` | `pugixml` | `cppzmq` | `cpp-argparse`| `nlohmann_json` | `dirent` (windows only) |
|------------|-----------------|-----------------|--------------|-----------|-----------|----------|---------------|-----------------|-------------------------|
| main | >=1.0.0,<2.0.0 | >=0.7.7,<0.8.0 | >=1.2.0 | | ~1.8.1 | ~4.3.0 | <3.1 | >=3.11.2,<4.0 | >=2.3.2,<3 |
| 0.3.0 | >=1.0.0,<2.0.0 | >=0.7.7,<0.8.0 | | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |
| 0.2.0 | >=1.0.0,<2.0.0 | >=0.7.7,<0.8.0 | | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |
| 0.1.0 | >=1.0.0,<2.0.0 | >=0.7.0,<0.8.0 | | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |
| 0.0.1 | >=1.0.0,<2.0.0 | >=0.7.0,<0.8.0 | | >=16,<17 | ~1.8.1 | ~4.3.0 | ~2.9 | >=3.6.1,<4.0 | >=2.3.2,<3 |

## Contributing

Expand Down
4 changes: 2 additions & 2 deletions environment-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ dependencies:
- nlohmann_json=3.11.2
- cppzmq
- xtl
- clangdev >=16,<17
- CppInterOp
- pugixml
- cpp-argparse
- cpp-argparse <3.1
- zlib
# Test dependencies
- pytest
Expand Down
4 changes: 2 additions & 2 deletions environment-wasm-host.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ channels:
- https://repo.mamba.pm/conda-forge
dependencies:
- nlohmann_json
- xeus-lite
- xeus-lite <2.0
- xeus >=3.0.5,<4.0
- xtl >=0.7,<0.8
- llvm =16.0.6
- CppInterOp
- cpp-argparse
Copy link
Collaborator

@anutosh491 anutosh491 Mar 26, 2024

Choose a reason for hiding this comment

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

Should we pin this to <3.1 too ?

- pugixml
2 changes: 2 additions & 0 deletions include/xcpp/xdisplay.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#include "xcpp/xmime.hpp"

#include "xeus/xinterpreter.hpp"

namespace nl = nlohmann;

namespace xcpp
Expand Down
6 changes: 1 addition & 5 deletions include/xeus-cpp/xinterpreter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
#include <string>
#include <vector>

#include <clang/Interpreter/Interpreter.h>
#include "clang/Interpreter/CppInterOp.h" // from CppInterOp package
Copy link
Collaborator

Choose a reason for hiding this comment

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

Deos CppInterop place a header in the clang/Interpreter include directory?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah I was thinking about this too !

Copy link
Contributor

@vgvassilev vgvassilev Mar 22, 2024

Choose a reason for hiding this comment

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

Nope, it is not but that's the design of the package - we should change that in the new versions if needed.

EDIT: It does not place a header in the clang/Interpreter. The package has the same include structure and directories. In retrospect that might not have been the best, however, the idea is that most of the content of that library will go in clang under clang/Interpreter.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I am confused. Is the CppInterpop header placed there?

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, wait, are we having a common place for all headers? If everything is under include then it copies it there…

Copy link
Collaborator

Choose a reason for hiding this comment

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

I am still confused by why CppInterOp.h, which is a header from the CppInterOp package is under PREFIX/include/clang.

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, not a good choice. We will fix this in the next release of CppInterOp. Do we want to block progress because of that?

Copy link
Collaborator

Choose a reason for hiding this comment

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

We will fix this in the next release of CppInterOp.

Thanks!


#include <nlohmann/json.hpp>

Expand Down Expand Up @@ -76,10 +76,6 @@ namespace xcpp
void init_preamble();
void init_magic();

std::string get_stdopt(int argc, const char* const* argv);

std::unique_ptr<clang::Interpreter> m_interpreter;

std::string m_version;

xmagics_manager xmagics;
Expand Down
9 changes: 8 additions & 1 deletion share/jupyter/kernels/xcpp/kernel.json.in
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
{
"display_name": "cpp 14 (xcpp)",
"env": {
"PATH":"@XEUS_CPP_PATH@",
"LD_LIBRARY_PATH":"@XEUS_CPP_LD_LIBRARY_PATH@"
Copy link
Collaborator

Choose a reason for hiding this comment

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

I merged, but I wonder why we need to set these up exactly, if it wasn't required before?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Hey @alexander-penev

I actually have a doubt along similar lines. I understand how something like resource dir can contribute and hence it is good to have it introduced in argv as done in the PR !

But I am not sure how PATH (especially LD_LIBRARY_PATH) has a role to play here. As pointed out by Sylvain, xeus-cling never needed these. Can it be removed ?

},
"argv": [
"@XEUS_CPP_KERNELSPEC_PATH@xcpp",
"-f",
"{connection_file}"
"{connection_file}",
"-resource-dir", "@XEUS_CPP_RESOURCE_DIR@",
"-I", "@CMAKE_INSTALL_PREFIX@/include",
"-std=c++14"@XEUS_CPP_OMP@
],
"language": "cpp",
"metadata": {"debugger": false
Expand Down
66 changes: 32 additions & 34 deletions src/xinspect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
#include <fstream>
#include <string>


#include <pugixml.hpp>

#include <xtl/xsystem.hpp>
Expand All @@ -24,6 +23,8 @@
#include "xdemangle.hpp"
#include "xparser.hpp"

#include "clang/Interpreter/CppInterOp.h"

namespace xcpp
{
struct node_predicate
Expand Down Expand Up @@ -79,22 +80,23 @@ namespace xcpp
}
};

std::string find_type(const std::string& expression, clang::Interpreter& interpreter)
{
auto PTU = interpreter.Parse(expression + ";");
if (llvm::Error Err = PTU.takeError()) {
llvm::logAllUnhandledErrors(std::move(Err), llvm::errs(), "error: ");
return "";
}
std::string find_type_slow(const std::string& expression) {
static unsigned long long var_count = 0;

if (auto *type = Cpp::GetType(expression))
return Cpp::GetQualifiedName(type);

clang::Decl *D = *PTU->TUPart->decls_begin();
if (!llvm::isa<clang::TopLevelStmtDecl>(D))
return "";
// Here we might need to deal with integral types such as 3.14.

clang::Expr *E = llvm::cast<clang::Expr>(llvm::cast<clang::TopLevelStmtDecl>(D)->getStmt());
std::string id = "__Xeus_GetType_" + std::to_string(var_count++);
std::string using_clause = "using " + id + " = __typeof__(" + expression + ");\n";

clang::QualType QT = E->getType();
return QT.getAsString();
if (!Cpp::Declare(using_clause.c_str(), /*silent=*/false)) {
Cpp::TCppScope_t lookup = Cpp::GetNamed(id, nullptr);
Cpp::TCppType_t lookup_ty = Cpp::GetTypeFromScope(lookup);
return Cpp::GetQualifiedCompleteName(Cpp::GetCanonicalType(lookup_ty));
}
return "";
}

static nl::json read_tagconfs(const char* path)
Expand All @@ -111,17 +113,16 @@ namespace xcpp
return result;
}

std::pair<bool, std::smatch> is_inspect_request(const std::string code, std::regex re)
std::pair<bool, std::smatch> is_inspect_request(const std::string& code,
const std::regex& re)
{
std::smatch inspect;
if (std::regex_search(code, inspect, re)){
if (std::regex_search(code, inspect, re))
return std::make_pair(true, inspect);
}
return std::make_pair(false, inspect);

}

void inspect(const std::string& code, nl::json& kernel_res, clang::Interpreter& interpreter)
void inspect(const std::string& code, nl::json& kernel_res)
{
std::string tagconf_dir = XCPP_TAGCONFS_DIR;
std::string tagfiles_dir = XCPP_TAGFILES_DIR;
Expand All @@ -144,18 +145,18 @@ namespace xcpp
// Method or variable of class found (xxxx.yyyy)
if (std::regex_search(to_inspect, method, std::regex(R"((.*)\.(\w*)$)")))
{
std::string typename_ = find_type(method[1], interpreter);
std::string type_name = find_type_slow(method[1]);

if (!typename_.empty())
if (!type_name.empty())
{
for (nl::json::const_iterator it = tagconfs.cbegin(); it != tagconfs.cend(); ++it)
{
url = it->at("url");
tagfile = it->at("tagfile");
std::string filename = tagfiles_dir + "/" + tagfile;
pugi::xml_document doc;
doc.load_file(filename.c_str());
class_member_predicate predicate{typename_, "function", method[2]};
pugi::xml_parse_result result = doc.load_file(filename.c_str());
class_member_predicate predicate{type_name, "function", method[2]};
auto node = doc.find_node(predicate);
if (!node.empty())
{
Expand All @@ -178,8 +179,8 @@ namespace xcpp
}
else
{
std::string typename_ = find_type(to_inspect, interpreter);
find_string = (typename_.empty()) ? to_inspect : typename_;
std::string type_name = find_type_slow(to_inspect);
find_string = (type_name.empty()) ? to_inspect : type_name;
}

for (nl::json::const_iterator it = tagconfs.cbegin(); it != tagconfs.cend(); ++it)
Expand All @@ -188,7 +189,7 @@ namespace xcpp
tagfile = it->at("tagfile");
std::string filename = tagfiles_dir + "/" + tagfile;
pugi::xml_document doc;
doc.load_file(filename.c_str());
pugi::xml_parse_result result = doc.load_file(filename.c_str());
for (auto c : check)
{
node_predicate predicate{c, find_string};
Expand Down Expand Up @@ -266,8 +267,7 @@ namespace xcpp
using xpreamble::pattern;
const std::string spattern = R"(^\?)";

xintrospection(clang::Interpreter& p)
: m_interpreter{p}
xintrospection()
{
pattern = spattern;
}
Expand All @@ -277,17 +277,15 @@ namespace xcpp
std::regex re(spattern + R"((.*))");
std::smatch to_inspect;
std::regex_search(code, to_inspect, re);
inspect(to_inspect[1], kernel_res, m_interpreter);
inspect(to_inspect[1], kernel_res);
}

virtual xpreamble* clone() const override
{
return new xintrospection(*this);
}

private:

clang::Interpreter& m_interpreter;
};

}
#endif

#endif // XEUS_CPP_INSPECT_HPP
Loading