From ccedd3d59f3fa23de8a4e2a0337ba0c61c7a81bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20M=C3=A4rkl?= Date: Fri, 2 Mar 2018 14:15:53 +0100 Subject: [PATCH] Make Jupyter optional for CMake --- src/CMakeLists.txt | 33 ++++++++++++++++++++++++++++----- src/MainWindow.cpp | 6 ++++++ src/MainWindow.h | 4 ++++ src/cutter.pro | 4 ++++ src/meson.build | 4 ++++ src/utils/JupyterConnection.cpp | 3 +++ src/utils/JupyterConnection.h | 3 +++ src/utils/NestedIPyKernel.cpp | 6 +++++- src/utils/NestedIPyKernel.h | 5 ++++- src/utils/PythonAPI.cpp | 3 +++ src/utils/PythonAPI.h | 4 ++++ src/widgets/JupyterWidget.cpp | 17 ++++++++++++++++- src/widgets/JupyterWidget.h | 12 +++++++++++- 13 files changed, 95 insertions(+), 9 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e3cff26e..205d7f8a 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,13 +6,24 @@ include(DisallowInSource) project(cutter VERSION 1.2) +option(CUTTER_ENABLE_JUPYTER "Enable Jupyter integration. Requires Python >= 3.3." ON) +option(CUTTER_ENABLE_QTWEBENGINE "Use QtWebEngine for in-app Jupyter Browser. Unused if CUTTER_ENABLE_JUPYTER=OFF." ON) + + set(CMAKE_CXX_STANDARD 11) set(CMAKE_INCLUDE_CURRENT_DIR ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTOUIC ON) set(CMAKE_AUTORCC ON) -find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Svg WebEngineWidgets) +find_package(Qt5 REQUIRED COMPONENTS Core Widgets Gui Svg) +if(CUTTER_ENABLE_JUPYTER AND CUTTER_ENABLE_QTWEBENGINE) + find_package(Qt5 COMPONENTS WebEngineWidgets) + if(NOT Qt5_FOUND) + message(FATAL_ERROR "QtWebEngine could not be found which is required for the in-app Jupyter Browser. +If you do not want to enable this in-app Browser, re-run CMake with -DCUTTER_ENABLE_QTWEBENGINE=OFF.") + endif() +endif() if(WIN32) @@ -34,9 +45,16 @@ find_package(Radare2 REQUIRED) include_directories(${RADARE2_INCLUDE_DIRS}) link_directories(${RADARE2_LIBRARY_DIRS}) +if(CUTTER_ENABLE_JUPYTER) + find_package(PythonLibs 3.3) + if(NOT PythonLibs_FOUND) + message(FATAL_ERROR "Python >= 3.3 could not be found which is required for Jupyter integration. +If you do not want to enable Jupyter, re-run CMake with -DCUTTER_ENABLE_JUPYTER=OFF.") + endif() -find_package(PythonLibs 3.3 REQUIRED) -include_directories(${PYTHON_INCLUDE_DIRS}) + include_directories(${PYTHON_INCLUDE_DIRS}) + add_definitions(-DCUTTER_ENABLE_JUPYTER) +endif() if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" @@ -69,7 +87,12 @@ add_definitions("-DAPP_VERSION=\"${CUTTER_VERSION_FULL}\"") add_executable(cutter ${UI_FILES} ${QRC_FILES} ${SOURCE_FILES} ${HEADER_FILES}) -qt5_use_modules(cutter Core Widgets Gui Svg WebEngineWidgets) +qt5_use_modules(cutter Core Widgets Gui Svg) target_link_libraries(cutter ${RADARE2_LIBRARIES}) -target_link_libraries(cutter ${PYTHON_LIBRARIES}) +if(CUTTER_ENABLE_JUPYTER) + target_link_libraries(cutter ${PYTHON_LIBRARIES}) + if(CUTTER_ENABLE_QTWEBENGINE) + qt5_use_modules(cutter WebEngineWidgets) + endif() +endif() diff --git a/src/MainWindow.cpp b/src/MainWindow.cpp index 701bcc68..ae6d2366 100644 --- a/src/MainWindow.cpp +++ b/src/MainWindow.cpp @@ -220,7 +220,9 @@ void MainWindow::initUI() ADD_DOCK(CommentsWidget, commentsDock, ui->actionComments); ADD_DOCK(StringsWidget, stringsDock, ui->actionStrings); ADD_DOCK(FlagsWidget, flagsDock, ui->actionFlags); +#ifdef CUTTER_ENABLE_JUPYTER ADD_DOCK(JupyterWidget, jupyterDock, ui->actionJupyter); +#endif ADD_DOCK(Dashboard, dashboardDock, ui->actionDashboard); ADD_DOCK(SdbDock, sdbDock, ui->actionSDBBrowser); ADD_DOCK(ClassesWidget, classesDock, ui->actionClasses); @@ -538,7 +540,9 @@ void MainWindow::restoreDocks() tabifyDockWidget(dashboardDock, classesDock); tabifyDockWidget(dashboardDock, resourcesDock); tabifyDockWidget(dashboardDock, vTablesDock); +#ifdef CUTTER_ENABLE_JUPYTER tabifyDockWidget(dashboardDock, jupyterDock); +#endif updateDockActionsChecked(); } @@ -578,7 +582,9 @@ void MainWindow::showDefaultDocks() hexdumpDock, pseudocodeDock, dashboardDock, +#ifdef CUTTER_ENABLE_JUPYTER jupyterDock +#endif }; for (auto w : dockWidgets) diff --git a/src/MainWindow.h b/src/MainWindow.h index 34ce62d1..2f7756a0 100644 --- a/src/MainWindow.h +++ b/src/MainWindow.h @@ -39,7 +39,9 @@ class DisassemblerGraphView; class ClassesWidget; class ResourcesWidget; class VTablesWidget; +#ifdef CUTTER_ENABLE_JUPYTER class JupyterWidget; +#endif class QDockWidget; namespace Ui @@ -190,7 +192,9 @@ private: QDockWidget *asmDock = nullptr; QDockWidget *calcDock = nullptr; NewFileDialog *newFileDialog = nullptr; +#ifdef CUTTER_ENABLE_JUPYTER JupyterWidget *jupyterDock = nullptr; +#endif void toggleDockWidget(QDockWidget *dock_widget, bool show); diff --git a/src/cutter.pro b/src/cutter.pro index 67c20cb6..cdf42167 100644 --- a/src/cutter.pro +++ b/src/cutter.pro @@ -14,6 +14,10 @@ CONFIG += c++11 # Define the preprocessor macro to get the application version in our application. DEFINES += APP_VERSION=\\\"$$VERSION\\\" +# TODO: make optional +DEFINES += CUTTER_ENABLE_JUPYTER +DEFINES += CUTTER_ENABLE_QTWEBENGINE + INCLUDEPATH *= . win32 { diff --git a/src/meson.build b/src/meson.build index 0cbc4674..02d0e853 100644 --- a/src/meson.build +++ b/src/meson.build @@ -4,6 +4,10 @@ project('cutter', 'cpp', default_options: 'cpp_std=c++11') #TODO: add console option console = false +#TODO: make optional +add_project_arguments('-DCUTTER_ENABLE_JUPYTER', language: 'cpp') +add_project_arguments('-DCUTTER_ENABLE_QTWEBENGINE', language: 'cpp') + qt5_mod = import('qt5') version = get_option('version') diff --git a/src/utils/JupyterConnection.cpp b/src/utils/JupyterConnection.cpp index 173c4b79..1f7f1fcf 100644 --- a/src/utils/JupyterConnection.cpp +++ b/src/utils/JupyterConnection.cpp @@ -1,3 +1,4 @@ +#ifdef CUTTER_ENABLE_JUPYTER #include @@ -184,3 +185,5 @@ QVariant JupyterConnection::pollNestedIPyKernel(long id) return v; } + +#endif diff --git a/src/utils/JupyterConnection.h b/src/utils/JupyterConnection.h index 70cc49a4..ad775acc 100644 --- a/src/utils/JupyterConnection.h +++ b/src/utils/JupyterConnection.h @@ -1,6 +1,8 @@ #ifndef JUPYTERCONNECTION_H #define JUPYTERCONNECTION_H +#ifdef CUTTER_ENABLE_JUPYTER + #include #include @@ -49,5 +51,6 @@ private: #define Jupyter() (JupyterConnection::getInstance()) +#endif #endif //JUPYTERCONNECTION_H diff --git a/src/utils/NestedIPyKernel.cpp b/src/utils/NestedIPyKernel.cpp index b7e05eff..a7288863 100644 --- a/src/utils/NestedIPyKernel.cpp +++ b/src/utils/NestedIPyKernel.cpp @@ -1,4 +1,6 @@ +#ifdef CUTTER_ENABLE_JUPYTER + #include #include @@ -100,4 +102,6 @@ QVariant NestedIPyKernel::poll() } PyThreadState_Swap(parentThreadState); return ret; -} \ No newline at end of file +} + +#endif diff --git a/src/utils/NestedIPyKernel.h b/src/utils/NestedIPyKernel.h index dce41ac2..0c51c86c 100644 --- a/src/utils/NestedIPyKernel.h +++ b/src/utils/NestedIPyKernel.h @@ -1,8 +1,9 @@ - #ifndef NESTEDIPYKERNEL_H #define NESTEDIPYKERNEL_H +#ifdef CUTTER_ENABLE_JUPYTER + #include struct _object; @@ -29,4 +30,6 @@ private: PyObject *kernel; }; +#endif + #endif //NESTEDIPYKERNEL_H diff --git a/src/utils/PythonAPI.cpp b/src/utils/PythonAPI.cpp index 436a4d7a..0d437b4f 100644 --- a/src/utils/PythonAPI.cpp +++ b/src/utils/PythonAPI.cpp @@ -1,4 +1,6 @@ +#ifdef CUTTER_ENABLE_JUPYTER + #include "PythonAPI.h" #include "cutter.h" #include "JupyterConnection.h" @@ -181,3 +183,4 @@ PyObject *PyInit_api_internal() return PyModule_Create(&CutterInternalModule); } +#endif diff --git a/src/utils/PythonAPI.h b/src/utils/PythonAPI.h index 0c66a527..664c86ac 100644 --- a/src/utils/PythonAPI.h +++ b/src/utils/PythonAPI.h @@ -1,9 +1,13 @@ #ifndef PYTHONAPI_H #define PYTHONAPI_H +#ifdef CUTTER_ENABLE_JUPYTER + #include PyObject *PyInit_api(); PyObject *PyInit_api_internal(); +#endif + #endif // PYTHONAPI_H diff --git a/src/widgets/JupyterWidget.cpp b/src/widgets/JupyterWidget.cpp index 0ef421a5..d05558fb 100644 --- a/src/widgets/JupyterWidget.cpp +++ b/src/widgets/JupyterWidget.cpp @@ -1,13 +1,18 @@ +#ifdef CUTTER_ENABLE_JUPYTER + #include "ui_JupyterWidget.h" #include "JupyterWidget.h" -#include #include #include #include +#ifdef CUTTER_ENABLE_QTWEBENGINE +#include +#endif + JupyterWidget::JupyterWidget(QWidget *parent, Qt::WindowFlags flags) : QDockWidget(parent, flags), ui(new Ui::JupyterWidget) @@ -23,16 +28,22 @@ JupyterWidget::~JupyterWidget() { } +#ifdef CUTTER_ENABLE_QTWEBENGINE JupyterWebView *JupyterWidget::createNewTab() { auto webView = new JupyterWebView(this); ui->tabWidget->addTab(webView, "Tab"); return webView; } +#endif void JupyterWidget::urlReceived(const QString &url) { +#ifdef CUTTER_ENABLE_QTWEBENGINE createNewTab()->load(QUrl(url)); +#else + // TODO: make a tab with the url, so the user can use another browser +#endif } void JupyterWidget::creationFailed() @@ -48,6 +59,7 @@ void JupyterWidget::creationFailed() } +#ifdef CUTTER_ENABLE_QTWEBENGINE JupyterWebView::JupyterWebView(JupyterWidget *mainWidget, QWidget *parent) : QWebEngineView(parent) { this->mainWidget = mainWidget; @@ -63,3 +75,6 @@ QWebEngineView *JupyterWebView::createWindow(QWebEnginePage::WebWindowType type) return nullptr; } } +#endif + +#endif diff --git a/src/widgets/JupyterWidget.h b/src/widgets/JupyterWidget.h index 39ce4c64..5b81627f 100644 --- a/src/widgets/JupyterWidget.h +++ b/src/widgets/JupyterWidget.h @@ -2,10 +2,11 @@ #ifndef JUPYTERWIDGET_H #define JUPYTERWIDGET_H +#ifdef CUTTER_ENABLE_JUPYTER + #include #include -#include #include "utils/JupyterConnection.h" @@ -24,7 +25,9 @@ public: JupyterWidget(QWidget *parent = nullptr, Qt::WindowFlags flags = Qt::WindowFlags()); ~JupyterWidget(); +#ifdef CUTTER_ENABLE_QTWEBENGINE JupyterWebView *createNewTab(); +#endif private slots: void urlReceived(const QString &url); @@ -34,6 +37,9 @@ private: std::unique_ptr ui; }; +#ifdef CUTTER_ENABLE_QTWEBENGINE + +#include class JupyterWebView : public QWebEngineView { @@ -49,4 +55,8 @@ private: JupyterWidget *mainWidget; }; +#endif + +#endif + #endif //JUPYTERWIDGET_H