From 170bcb6fdca5942d0484042ad38c09b420554792 Mon Sep 17 00:00:00 2001
From: "Michael Hirsch, Ph.D" <scivision@users.noreply.github.com>
Date: Sat, 17 Nov 2018 21:48:26 -0500
Subject: FindOctave: Add module to find GNU octave

---
 Copyright.txt                        |   2 +
 Help/manual/cmake-modules.7.rst      |   1 +
 Help/module/FindOctave.rst           |   1 +
 Help/release/dev/FindOctave.rst      |   4 +
 Modules/FindOctave.cmake             | 167 +++++++++++++++++++++++++++++++++++
 Tests/CMakeLists.txt                 |   4 +
 Tests/FindOctave/CMakeLists.txt      |  10 +++
 Tests/FindOctave/Test/CMakeLists.txt |  20 +++++
 Tests/FindOctave/Test/main.cpp       |  18 ++++
 Tests/FindOctave/Test/testtrue.m     |   1 +
 10 files changed, 228 insertions(+)
 create mode 100644 Help/module/FindOctave.rst
 create mode 100644 Help/release/dev/FindOctave.rst
 create mode 100644 Modules/FindOctave.cmake
 create mode 100644 Tests/FindOctave/CMakeLists.txt
 create mode 100644 Tests/FindOctave/Test/CMakeLists.txt
 create mode 100644 Tests/FindOctave/Test/main.cpp
 create mode 100644 Tests/FindOctave/Test/testtrue.m

diff --git a/Copyright.txt b/Copyright.txt
index c7a81b1..dc6deb9 100644
--- a/Copyright.txt
+++ b/Copyright.txt
@@ -63,6 +63,7 @@ The following individuals and institutions are among the Contributors:
 * Ilya Lavrenov <ilya.lavrenov@itseez.com>
 * Insight Software Consortium <insightsoftwareconsortium.org>
 * Jan Woetzel
+* Julien Schueller
 * Kelly Thompson <kgt@lanl.gov>
 * Laurent Montel <montel@kde.org>
 * Konstantin Podsvirov <konstantin@podsvirov.pro>
@@ -72,6 +73,7 @@ The following individuals and institutions are among the Contributors:
 * Matthaeus G. Chajdas
 * Matthias Kretz <kretz@kde.org>
 * Matthias Maennich <matthias@maennich.net>
+* Michael Hirsch, Ph.D. <www.scivision.co>
 * Michael Stürmer
 * Miguel A. Figueroa-Villanueva
 * Mike Jackson
diff --git a/Help/manual/cmake-modules.7.rst b/Help/manual/cmake-modules.7.rst
index cd5d1a5..2f08a04 100644
--- a/Help/manual/cmake-modules.7.rst
+++ b/Help/manual/cmake-modules.7.rst
@@ -176,6 +176,7 @@ They are normally called through the :command:`find_package` command.
    /module/FindMPEG2
    /module/FindMPEG
    /module/FindMPI
+   /module/FindOctave
    /module/FindODBC
    /module/FindOpenACC
    /module/FindOpenAL
diff --git a/Help/module/FindOctave.rst b/Help/module/FindOctave.rst
new file mode 100644
index 0000000..2dbcec4
--- /dev/null
+++ b/Help/module/FindOctave.rst
@@ -0,0 +1 @@
+.. cmake-module:: ../../Modules/FindOctave.cmake
diff --git a/Help/release/dev/FindOctave.rst b/Help/release/dev/FindOctave.rst
new file mode 100644
index 0000000..fe3b242
--- /dev/null
+++ b/Help/release/dev/FindOctave.rst
@@ -0,0 +1,4 @@
+FindOctave
+----------
+
+* A :module:`FindOctave` module was added to find GNU octave.
diff --git a/Modules/FindOctave.cmake b/Modules/FindOctave.cmake
new file mode 100644
index 0000000..8ae6a47
--- /dev/null
+++ b/Modules/FindOctave.cmake
@@ -0,0 +1,167 @@
+# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
+# file Copyright.txt or https://cmake.org/licensing for details.
+
+#[=======================================================================[.rst:
+FindOctave
+----------
+
+Finds GNU Octave interpreter, libraries and compilers.
+
+Imported targets
+^^^^^^^^^^^^^^^^
+
+This module defines the following :prop_tgt:`IMPORTED` targets:
+
+``Octave::Interpreter``
+  Octave interpreter (the main program)
+``Octave::Octave``
+  include directories and libraries
+
+If no ``COMPONENTS`` are specified, ``Interpreter`` is assumed.
+
+Result Variables
+^^^^^^^^^^^^^^^^
+
+``Octave_FOUND``
+  Octave interpreter and/or libraries were found
+``Octave_<component>_FOUND``
+  Octave <component> specified was found
+
+``Octave_EXECUTABLE``
+  Octave interpreter
+``Octave_INCLUDE_DIRS``
+  include path for mex.h
+``Octave_LIBRARIES``
+  octinterp, octave libraries
+
+
+Cache variables
+^^^^^^^^^^^^^^^
+
+The following cache variables may also be set:
+
+``Octave_INTERP_LIBRARY``
+  path to the library octinterp
+``Octave_OCTAVE_LIBRARY``
+  path to the liboctave library
+
+#]=======================================================================]
+
+cmake_policy(VERSION 3.3)
+
+unset(Octave_REQUIRED_VARS)
+unset(Octave_Development_FOUND)
+unset(Octave_Interpreter_FOUND)
+set(CMAKE_INSTALL_DEFAULT_COMPONENT_NAME Interpreter)
+
+if(Development IN_LIST Octave_FIND_COMPONENTS)
+  find_program(Octave_CONFIG_EXECUTABLE
+               NAMES octave-config)
+
+  if(Octave_CONFIG_EXECUTABLE)
+
+    execute_process(COMMAND ${Octave_CONFIG_EXECUTABLE} -p BINDIR
+                    OUTPUT_VARIABLE Octave_BINARY_DIR
+                    ERROR_QUIET
+                    OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    execute_process(COMMAND ${Octave_CONFIG_EXECUTABLE} -p OCTINCLUDEDIR
+                    OUTPUT_VARIABLE Octave_INCLUDE_DIR
+                    ERROR_QUIET
+                    OUTPUT_STRIP_TRAILING_WHITESPACE)
+    list(APPEND Octave_REQUIRED_VARS ${Octave_INCLUDE_DIR})
+
+    execute_process(COMMAND ${Octave_CONFIG_EXECUTABLE} -p OCTLIBDIR
+                    OUTPUT_VARIABLE Octave_LIB1
+                    ERROR_QUIET
+                    OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    execute_process(COMMAND ${Octave_CONFIG_EXECUTABLE} -p LIBDIR
+                    OUTPUT_VARIABLE Octave_LIB2
+                    ERROR_QUIET
+                    OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+    find_library(Octave_INTERP_LIBRARY
+               NAMES octinterp
+               PATHS ${Octave_LIB1} ${Octave_LIB2}
+               NO_DEFAULT_PATH
+              )
+    find_library(Octave_OCTAVE_LIBRARY
+                 NAMES octave
+                 PATHS ${Octave_LIB1} ${Octave_LIB2}
+                 NO_DEFAULT_PATH
+                )
+    list(APPEND Octave_REQUIRED_VARS ${Octave_OCTAVE_LIBRARY} ${Octave_INTERP_LIBRARY})
+
+    if(Octave_REQUIRED_VARS)
+      set(Octave_Development_FOUND true)
+    endif()
+  endif(Octave_CONFIG_EXECUTABLE)
+endif()
+
+if(Interpreter IN_LIST Octave_FIND_COMPONENTS)
+
+  find_program(Octave_EXECUTABLE
+               NAMES octave)
+
+  list(APPEND Octave_REQUIRED_VARS ${Octave_EXECUTABLE})
+
+endif()
+
+if(Octave_EXECUTABLE)
+  execute_process(COMMAND ${Octave_EXECUTABLE} -v
+                  OUTPUT_VARIABLE Octave_VERSION
+                  ERROR_QUIET
+                  OUTPUT_STRIP_TRAILING_WHITESPACE)
+
+
+  string(REGEX REPLACE "GNU Octave, version ([0-9]+)\\.[0-9]+\\.[0-9]+.*" "\\1" Octave_VERSION_MAJOR ${Octave_VERSION})
+  string(REGEX REPLACE "GNU Octave, version [0-9]+\\.([0-9]+)\\.[0-9]+.*" "\\1" Octave_VERSION_MINOR ${Octave_VERSION})
+  string(REGEX REPLACE "GNU Octave, version [0-9]+\\.[0-9]+\\.([0-9]+).*" "\\1" Octave_VERSION_PATCH ${Octave_VERSION})
+
+  set(Octave_VERSION ${Octave_VERSION_MAJOR}.${Octave_VERSION_MINOR}.${Octave_VERSION_PATCH})
+
+  set(Octave_Interpreter_FOUND true)
+
+endif(Octave_EXECUTABLE)
+
+include(FindPackageHandleStandardArgs)
+find_package_handle_standard_args(Octave
+  REQUIRED_VARS Octave_REQUIRED_VARS
+  VERSION_VAR Octave_VERSION
+  HANDLE_COMPONENTS)
+
+
+if(Octave_Development_FOUND)
+  set(Octave_LIBRARIES ${Octave_INTERP_LIBRARY} ${Octave_OCTAVE_LIBRARY})
+  set(Octave_INCLUDE_DIRS ${Octave_INCLUDE_DIR})
+
+  if(NOT TARGET Octave::Octave)
+    add_library(Octave::Octave UNKNOWN IMPORTED)
+    set_target_properties(Octave::Octave PROPERTIES
+                          IMPORTED_LOCATION ${Octave_OCTAVE_LIBRARY}
+                          INTERFACE_INCLUDE_DIRECTORIES ${Octave_INCLUDE_DIR}
+                         )
+  endif()
+
+endif()
+
+
+if(Octave_Interpreter_FOUND)
+  if(NOT TARGET Octave::Interpreter)
+    add_executable(Octave::Interpreter IMPORTED)
+    set_target_properties(Octave::Interpreter PROPERTIES
+                          IMPORTED_LOCATION ${Octave_EXECUTABLE}
+                          VERSION ${Octave_VERSION})
+  endif()
+endif()
+
+mark_as_advanced(
+  Octave_CONFIG_EXECUTABLE
+  Octave_INTERP_LIBRARY
+  Octave_OCTAVE_LIBRARY
+  Octave_INCLUDE_DIR
+  Octave_VERSION_MAJOR
+  Octave_VERSION_MINOR
+  Octave_VERSION_PATCH
+)
diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt
index 8b5f2e9..408c941 100644
--- a/Tests/CMakeLists.txt
+++ b/Tests/CMakeLists.txt
@@ -1441,6 +1441,10 @@ ${CMake_BINARY_DIR}/bin/cmake -DDIR=dev -P ${CMake_SOURCE_DIR}/Utilities/Release
     add_subdirectory(FindODBC)
   endif()
 
+  if(CMake_TEST_FindOctave)
+    add_subdirectory(FindOctave)
+  endif()
+
   if(CMake_TEST_FindOpenCL)
     add_subdirectory(FindOpenCL)
   endif()
diff --git a/Tests/FindOctave/CMakeLists.txt b/Tests/FindOctave/CMakeLists.txt
new file mode 100644
index 0000000..1acc966
--- /dev/null
+++ b/Tests/FindOctave/CMakeLists.txt
@@ -0,0 +1,10 @@
+add_test(NAME FindOctave.Test COMMAND
+  ${CMAKE_CTEST_COMMAND} -C $<CONFIGURATION>
+  --build-and-test
+  "${CMake_SOURCE_DIR}/Tests/FindOctave/Test"
+  "${CMake_BINARY_DIR}/Tests/FindOctave/Test"
+  ${build_generator_args}
+  --build-project TestFindOctave
+  --build-options ${build_options}
+  --test-command ${CMAKE_CTEST_COMMAND} -V -C $<CONFIGURATION>
+  )
diff --git a/Tests/FindOctave/Test/CMakeLists.txt b/Tests/FindOctave/Test/CMakeLists.txt
new file mode 100644
index 0000000..ce33fcd
--- /dev/null
+++ b/Tests/FindOctave/Test/CMakeLists.txt
@@ -0,0 +1,20 @@
+cmake_minimum_required(VERSION 3.3)
+project(TestFindOctave CXX)
+enable_testing()
+
+find_package(Octave REQUIRED COMPONENTS Development Interpreter)
+
+add_definitions(-DCMAKE_EXPECTED_Octave_VERSION=${Octave_VERSION})
+
+add_executable(test_tgt main.cpp)
+target_link_libraries(test_tgt Octave::Octave)
+add_test(NAME test_tgt COMMAND test_tgt)
+
+add_test(NAME test_tgt_exe
+         COMMAND Octave::Interpreter -q --eval "runtests('.')"
+         WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
+
+add_executable(test_var main.cpp)
+target_include_directories(test_var PRIVATE ${Octave_INCLUDE_DIRS})
+target_link_libraries(test_var PRIVATE ${Octave_LIBRARIES})
+add_test(NAME test_var COMMAND test_var)
diff --git a/Tests/FindOctave/Test/main.cpp b/Tests/FindOctave/Test/main.cpp
new file mode 100644
index 0000000..68270b1
--- /dev/null
+++ b/Tests/FindOctave/Test/main.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <oct.h>
+
+// http://www.dm.unibo.it/~achilles/calc/octave.html/Standalone-Programs.html
+int main(void)
+{
+  int n = 2;
+  Matrix a_matrix = Matrix(n, n);
+  for (octave_idx_type i = 0; i < n; i++) {
+    for (octave_idx_type j = 0; j < n; j++) {
+      a_matrix(i, j) = (i + 1) * 10 + (j + 1);
+    }
+  }
+
+  std::cout << a_matrix << std::endl;
+
+  return EXIT_SUCCESS;
+}
diff --git a/Tests/FindOctave/Test/testtrue.m b/Tests/FindOctave/Test/testtrue.m
new file mode 100644
index 0000000..0c28a9e
--- /dev/null
+++ b/Tests/FindOctave/Test/testtrue.m
@@ -0,0 +1 @@
+%!assert(true)
-- 
cgit v0.12