From 0a3db55acee71b4f9b50d2d6dd55094ac75e3acb Mon Sep 17 00:00:00 2001
From: Marco Matthies <71844+marcom@users.noreply.github.com>
Date: Mon, 8 Jul 2024 10:54:48 +0200
Subject: [PATCH] Initial interface to Julia with the jluna library

---
 c++/CMakeLists.txt | 38 ++++++++++++++++++++++++++++++++++----
 c++/README.md      | 12 +++++++++++-
 c++/main.cpp       | 10 ++++++++++
 3 files changed, 55 insertions(+), 5 deletions(-)

diff --git a/c++/CMakeLists.txt b/c++/CMakeLists.txt
index 692cc05..308d59e 100644
--- a/c++/CMakeLists.txt
+++ b/c++/CMakeLists.txt
@@ -1,17 +1,38 @@
 cmake_minimum_required(VERSION 3.16)
 project(PersefoneGUI LANGUAGES CXX)
 
-set(CMAKE_CXX_STANDARD 17)
+set(CMAKE_CXX_STANDARD 20)
 set(CMAKE_CXX_STANDARD_REQUIRED True)
 set(CMAKE_CXX_EXTENSIONS OFF)
-set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++20")
+
+# julia
+# TODO: use JULIA_BINDIR
+#       with
+#       ${JULIA_BINDIR}/../lib
+#       ${JULIA_BINDIR}/../include/
+set(JULIA_DIR "" CACHE PATH "Base directory where julia lib/ and include/ directories are located")
+find_library(JULIA_LIB NAMES julia HINTS ${JULIA_DIR}/lib)
+if(NOT JULIA_LIB)
+    message(FATAL_ERROR "julia library not found. Please set JULIA_DIR to the base directory containing the lib/ and include/ directories.")
+else()
+    message(STATUS "Found julia library: ${JULIA_LIB}")
+endif()
+
+# jluna
+set(JLUNA_DIR "" CACHE PATH "Directory where jluna library is located")
+find_library(JLUNA_LIB NAMES jluna HINTS ${JLUNA_DIR})
+if(NOT JLUNA_LIB)
+    message(FATAL_ERROR "jluna library not found. Please set JLUNA_DIR to the directory containing the library.")
+else()
+    message(STATUS "Found jluna library: ${JLUNA_LIB}")
+endif()
 
 #set(CMAKE_PREFIX_PATH "/usr/lib/x86_64-linux-gnu/cmake/Qt6" CACHE STRING "Qt6 installation prefix")
 #set(HOME_DIR $ENV{HOME})
 #set(CMAKE_PREFIX_PATH "${HOME_DIR}/app/qt6/6.7.2/gcc_64/lib/cmake/Qt6" CACHE STRING "Qt6 installation prefix")
 
 set(CMAKE_AUTOMOC ON)
-
 find_package(Qt6 REQUIRED COMPONENTS Core Gui Quick)
 
 qt_add_executable(PersefoneGUI
@@ -27,9 +48,18 @@ target_link_libraries(PersefoneGUI PRIVATE
     Qt6::Core
     Qt6::Gui
     Qt6::Quick
+    "${JULIA_LIB}"
+    "${JLUNA_LIB}"
 )
 
-# Resources:
+target_include_directories(PersefoneGUI PRIVATE
+    "${JULIA_DIR}/include/julia"
+    "${JLUNA_DIR}/include/jluna"
+)
+
+target_compile_features(PersefoneGUI PRIVATE cxx_std_20)
+
+# QML Resources
 set(qml_resource_files
     "main.qml"
 )
diff --git a/c++/README.md b/c++/README.md
index 786f962..bd4bc78 100644
--- a/c++/README.md
+++ b/c++/README.md
@@ -5,7 +5,10 @@
 ```sh
 mkdir build
 cd build
-cmake ..
+cmake \
+    -DJULIA_DIR=/path/to/where/julia/is/installed \
+    -DJLUNA_DIR=/path/to/where/jluna/is/installed \
+    ..
 make
 ./PersefoneGUI
 ```
@@ -16,6 +19,9 @@ packages could be missing, and some might not be necessary, sorry):
 
 ### Prerequisites for building from source
 
+You need a C++ compiler, cmake, make, and Qt6 installed.
+
+On Ubuntu the following should work:
 ```sh
 sudo apt install build-essential cmake
 sudo apt install qt6-base-dev qt6-declarative-dev
@@ -30,3 +36,7 @@ sudo apt install \
     qml6-module-qtquick-window \
     qt6-image-formats-plugins
 ```
+
+You also need the jluna library installed:
+https://github.com/Clemapfel/jluna
+
diff --git a/c++/main.cpp b/c++/main.cpp
index 64b2361..7202547 100644
--- a/c++/main.cpp
+++ b/c++/main.cpp
@@ -7,6 +7,8 @@
 #include <QDir>
 #include <QUrl>
 
+#include <jluna.hpp>
+
 QString getFileUrlRelativeToExecutable(const QString &relativeFilePath) {
     // Get the directory path of the executable
     QString basePath = QCoreApplication::applicationDirPath();
@@ -21,6 +23,14 @@ QString getFileUrlRelativeToExecutable(const QString &relativeFilePath) {
 
 int main(int argc, char *argv[])
 {
+    jluna::initialize();
+    jluna::Base["println"]("julia: hello from julia");
+    jluna::Main.safe_eval("import Pkg; Pkg.activate(\"..\")");
+    jluna::Main.safe_eval("println(\"julia: LD_LIBRARY_PATH = \", get(ENV, \"LD_LIBRARY_PATH\", \"\"))");
+    jluna::Base["println"]("before import Persefone");
+    jluna::Main.safe_eval("import Persefone");
+    //jluna::Main.safe_eval("import Pkg; Pkg.activate(\"..\"); using Persefone");
+
     QGuiApplication gui_app(argc, argv);
     QQmlApplicationEngine engine;
 
-- 
GitLab