R interface to Octave / undefined symbol _ZTI18handle_cdef_object

L.S.

We are trying to revive RcppOctave, an R / Octave interface at GitHub - openanalytics/RcppOctave: Seamless Interface to Octave -- and Matlab code

We overcame a number of obstacles, but are currently a bit in the dark regarding the following error which occurs when we try to load the resulting library:

error: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/PKG_ADD: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__init_gnuplot__.oct: failed to load: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__init_gnuplot__.oct: undefined symbol: _ZTI18handle_cdef_object

Sanity check:

$ pwd
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu
$ nm -D __init_gnuplot__.oct | grep handle_cdef_object
                 U _ZTI18handle_cdef_object
$ c++filt _ZTI18handle_cdef_object
typeinfo for handle_cdef_object

This is Octave 5.2.0 installed from Ubuntu repos (Ubuntu 20.04 LTS).

Doest this error ring a bell to anyone? Can I provide any further information?

Many thanks in advance for any pointers!

Kind regards,
Tobias

The PKG_ADD files are executed when the respective path is added to Octave’s search path. One of those files initializes the gnuplot graphics toolkit by calling __init_gnuplot__. If I understand the message in the line you showed correctly, running this function failed because of a missing symbol.
handle_cdef_object is an object exported by the shared library liboctave.
How did you initialize Octave from your code? Can that library be found when __init_gnuplot__.oct tries to run?

Hi @mmuetzel,

Many thanks for your reaction and explanation of the process.

The Makefile that is being generated in the process of building the R package (including compilation of the c++ code) is a Makevars file and looks as follows:

# PATH specification 
# none needed

# To avoid warnings with Octave C99 syntax
CXX_STD = CXX11

# set by configure
OCT_LDFLAGS=  -L/usr/lib/x86_64-linux-gnu -loctinterp -loctave 
OCT_CPPFLAGS=-Wdate-time -D_FORTIFY_SOURCE=2 -I/usr/include/octave-5.2.0/octave/.. -I/usr/include/octave-5.2.0/octave -DOCT_POST_3_4_0=1
OCT_MODULES_PATH=/home/tverbeke/.architect/workspace/RcppOctave.Rcheck/00LOCK-RcppOctave/00new/RcppOctave/modules
OCT_MODULES_DEST="$(OCT_MODULES_PATH)$(R_ARCH)"
OCTAVE_CUSTOMED=FALSE
RSCRIPT_ARG=
RSCRIPT_BIN="$(R_HOME)/bin$(R_ARCH_BIN)/Rscript$(RSCRIPT_ARG)"

# Octave module target
OCT_TARGET=all

# System-specific statments (e.g., overrides)
# none needed

## Use the R_HOME indirection to support installations of multiple R version
PKG_LIBS = `$(RSCRIPT_BIN) -e "Rcpp:::LdFlags()"` $(OCT_LDFLAGS)
PKG_CPPFLAGS = `$(RSCRIPT_BIN) -e "Rcpp:::CxxFlags()"` $(OCT_CPPFLAGS) $(PKG_CPPFLAGS_XTRA)

.PHONY: all OctaveModule

all: OctaveModule $(SHLIB)
$(SHLIB): OctaveModule
 
OctaveModule:
	@echo "# Making Octave module [r_arch: $(OCT_TARGET)]"
	@cd modules && \
	$(MAKE) CC="$(CC)" CXX="$(CXX)" AR="$(AR)" RANLIB="$(RANLIB)" $(OCT_TARGET) && \
	echo "# Copying Octave modules to directory '$(OCT_MODULES_DEST)'" && \
	mkdir -p "$(OCT_MODULES_DEST)" && \
	cp -f PKG_ADD *.oct "$(OCT_MODULES_DEST)"

clean:
	rm *.o;
	cd modules && $(MAKE) clean;

clean-all: clean
	rm $(SHLIB);
	cd modules && $(MAKE) clean-all;

I guess the

OCT_LDFLAGS=  -L/usr/lib/x86_64-linux-gnu -loctinterp -loctave 

is the one we should get right, no?

Regarding the way Octave is being embedded, the c++ code is in the octave_session function at RcppOctave/rcpp_octave.cpp at master · openanalytics/RcppOctave · GitHub

which uses

int status;
static octave::interpreter intrprtr;
status = intrprtr.execute ();

Let me know if I can provide more information or if there is any public examples I can follow.

Thanks again!

Kind regards,
Tobias

Did you install the Octave libraries in that location? I’d assume they should be found automatically there. If they are installed in another location, you could maybe try adding that path to LD_PRELOAD before you run your executable.
Edit: It looks like a make install instruction is missing in your Makefile.

That looks correct to me.
You could try the example in embedded.cc if you haven’t yet:
examples/code/embedded.cc (gnu.org)

(There might be an error in that example. I’m not sure if interpreter->shutdown (); is correct syntax if interpreter is not a pointer.)

Thank you @mmuetzel! Regarding installation of libraries, I currently use the off-the-shelf Ubuntu 20.04 version (5.2.0) which ships it in the following way:

$ dpkg -L octave
/.
/usr
/usr/bin
/usr/bin/octave
/usr/bin/octave-cli
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/octave
/usr/lib/x86_64-linux-gnu/octave/5.2.0
/usr/lib/x86_64-linux-gnu/octave/5.2.0/liboctgui.so.5.0.1
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/PKG_ADD
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__delaunayn__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__eigs__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__fltk_uigetfile__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__glpk__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__init_fltk__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__init_gnuplot__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__init_qt__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__ode15__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__voronoi__.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/amd.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/audiodevinfo.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/audioread.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/ccolamd.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/chol.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/colamd.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/convhulln.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/dmperm.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/fftw.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/gzip.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/qr.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/symbfact.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/symrcm.oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/site
/usr/lib/x86_64-linux-gnu/octave/5.2.0/site/oct
/usr/lib/x86_64-linux-gnu/octave/5.2.0/site/oct/x86_64-pc-linux-gnu
/usr/lib/x86_64-linux-gnu/octave/packages
/usr/lib/x86_64-linux-gnu/octave/site
/usr/lib/x86_64-linux-gnu/octave/site/oct
/usr/lib/x86_64-linux-gnu/octave/site/oct/api-v53
/usr/lib/x86_64-linux-gnu/octave/site/oct/api-v53/x86_64-pc-linux-gnu
/usr/lib/x86_64-linux-gnu/octave/site/oct/x86_64-pc-linux-gnu
/usr/libexec
/usr/libexec/octave
/usr/libexec/octave/5.2.0
/usr/libexec/octave/5.2.0/exec
/usr/libexec/octave/5.2.0/exec/x86_64-pc-linux-gnu
/usr/libexec/octave/5.2.0/exec/x86_64-pc-linux-gnu/octave-gui
/usr/libexec/octave/5.2.0/exec/x86_64-pc-linux-gnu/octave-svgconvert
/usr/libexec/octave/5.2.0/site
/usr/libexec/octave/5.2.0/site/exec
/usr/libexec/octave/5.2.0/site/exec/x86_64-pc-linux-gnu
/usr/libexec/octave/api-v53
/usr/libexec/octave/api-v53/site
/usr/libexec/octave/api-v53/site/exec
/usr/libexec/octave/api-v53/site/exec/x86_64-pc-linux-gnu
/usr/libexec/octave/site
/usr/libexec/octave/site/exec
/usr/libexec/octave/site/exec/x86_64-pc-linux-gnu
/usr/share
/usr/share/applications
/usr/share/applications/org.octave.Octave.desktop
/usr/share/doc
/usr/share/doc/octave
/usr/share/doc/octave/AUTHORS.gz
/usr/share/doc/octave/BUGS.gz
/usr/share/doc/octave/NEWS.gz
/usr/share/doc/octave/README
/usr/share/doc/octave/README.Debian
/usr/share/doc/octave/copyright
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/octave
/usr/share/man
/usr/share/man/man1
/usr/share/man/man1/octave-cli.1.gz
/usr/share/man/man1/octave.1.gz
/usr/share/metainfo
/usr/share/metainfo/org.octave.Octave.appdata.xml
/usr/share/octave
/usr/share/octave/packages
/usr/lib/x86_64-linux-gnu/octave/5.2.0/liboctgui.so
/usr/lib/x86_64-linux-gnu/octave/5.2.0/liboctgui.so.5
/usr/share/doc/octave/NEWS.Debian.gz
/usr/share/doc/octave/changelog.Debian.gz

I found a similar post on askubuntu, maybe something is wrong in the Ubuntu shipped version?

I see the following with Ubuntu 20.10:

$ dpkg -L liboctave7
/.
/usr
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/liboctave.so.7.0.1
/usr/lib/x86_64-linux-gnu/liboctinterp.so.7.0.1
/usr/share
/usr/share/doc
/usr/share/doc/liboctave7
/usr/share/doc/liboctave7/NEWS.Debian.gz
/usr/share/doc/liboctave7/changelog.Debian.gz
/usr/share/doc/liboctave7/copyright
/usr/share/lintian
/usr/share/lintian/overrides
/usr/share/lintian/overrides/liboctave7
/usr/lib/x86_64-linux-gnu/liboctave.so.7
/usr/lib/x86_64-linux-gnu/liboctinterp.so.7

So the libraries should be installed in the location you indicated in a previous post.
And I can compile the example with the following command:

mkoctfile --link-stand-alone /usr/share/doc/liboctave-dev/examples/embedded.cc -o embedded

See also: Standalone Programs (GNU Octave (version 5.2.0))

I can confirm that the libraries are there indeed:

tverbeke@oa-tverbeke:/usr/lib/x86_64-linux-gnu$ ls -al liboct*
lrwxrwxrwx 1 root root       18 Feb  4  2020 liboctave.so -> liboctave.so.7.0.1
lrwxrwxrwx 1 root root       18 Feb  4  2020 liboctave.so.7 -> liboctave.so.7.0.1
-rw-r--r-- 1 root root 17737416 Feb  4  2020 liboctave.so.7.0.1
lrwxrwxrwx 1 root root       21 Feb  4  2020 liboctinterp.so -> liboctinterp.so.7.0.1
lrwxrwxrwx 1 root root       21 Feb  4  2020 liboctinterp.so.7 -> liboctinterp.so.7.0.1
-rw-r--r-- 1 root root 20513672 Feb  4  2020 liboctinterp.so.7.0.1

and compiling the example works as expected:

$ mkoctfile --link-stand-alone /usr/share/doc/liboctave-dev/examples/embedded.cc -o embedded
$ ./embedded 
GCD of [10, 15] is 5

Will report back if I find out more - thanks!

Thanks for looking into this.
A bit more information: starting from the embedded.cc example, we’ve added

extern “C”
{
int main(void);
}

and created a shared library using

g++ -I/usr/include/octave-5.2.0/octave/… -std=c++17 -fPIC -O3 -DNDEBUG -c embedded.cpp
g++ -shared -fPIC -o embedded.so embedded.o -L/usr/lib/x86_64-linux-gnu -loctave -loctinterp -L/usr/lib/x86_64-linux-gnu/octave/5.2.0 -loctgui

We’ve additionally included the liboctgui since

nm -D /usr/lib/x86_64-linux-gnu/octave/5.2.0/liboctgui.so | grep ZTI18
U _ZTI18handle_cdef_object
U _ZTI18QAbstractListModel@@Qt_5
00000000002f50d0 V _ZTI18Ui_settings_dialog

Running the python code

import ctypes
shared_lib = ctypes.CDLL(’/<path>/embedded.so’)
shared_lib.main()

results in

error: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/PKG_ADD: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/init_gnuplot.oct: failed to load: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/init_gnuplot.oct: undefined symbol: _ZTI18handle_cdef_object
GCD of [10, 15] is 5

So it does seem that function is being called but the error is still there. Note that compiling mkoctfile --link-stand-alone embedded.cpp -o embedded still works perfectly.

Any ideas would be greatly appreciated.

What does “ldd init_gnuplot.oct” return?

Dmitri.

I see the following on Ubuntu 20.10:

$ mkoctfile --link-stand-alone /usr/share/doc/liboctave-dev/examples/embedded.cc -o embedded -v
g++ -c -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/octave-5.2.0/octave/.. -I/usr/include/octave-5.2.0/octave  -pthread -fopenmp -g -O2 -fdebug-prefix-map=/build/octave-TC4r0Y/octave-5.2.0=. -fstack-protector-strong -Wformat -Werror=format-security    /usr/share/doc/liboctave-dev/examples/embedded.cc -o /tmp/oct-EqiAya.o
g++ -Wdate-time -D_FORTIFY_SOURCE=2 -I/usr/include/octave-5.2.0/octave/.. -I/usr/include/octave-5.2.0/octave  -pthread -fopenmp -g -O2 -fdebug-prefix-map=/build/octave-TC4r0Y/octave-5.2.0=. -fstack-protector-strong -Wformat -Werror=format-security -rdynamic  -fPIC -Wl,-Bsymbolic-functions -Wl,-z,relro  -o embedded  /tmp/oct-EqiAya.o    -L/usr/lib/x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu/octave/5.2.0 -loctinterp -loctave  

You might need to sort the flags to have -L/usr/lib/x86_64-linux-gnu/octave/5.2.0 before -loctave -loctinterp?

I tried:

g++ -c -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/octave-5.2.0/octave/… -I/usr/include/octave-5.2.0/octave -pthread -fopenmp -g -O2 -fdebug-prefix-map=/build/octave-TC4r0Y/octave-5.2.0=. -fstack-protector-strong -Wformat -Werror=format-security embedded.cpp
g++ -shared -Wdate-time -D_FORTIFY_SOURCE=2 -I/usr/include/octave-5.2.0/octave/… -I/usr/include/octave-5.2.0/octave -pthread -fopenmp -g -O2 -fdebug-prefix-map=/build/octave-TC4r0Y/octave-5.2.0=. -fstack-protector-strong -Wformat -Werror=format-security -rdynamic -fPIC -Wl,-Bsymbolic-functions -Wl,-z,relro -o embedded.so embedded.o -L/usr/lib/x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu/octave/5.2.0 -loctinterp -loctave

to create the shared library. Unfortunately, this resulted in the same error when running the python code.

FYI:

mkoctfile --link-stand-alone embedded.cpp -o embedded -v
g++ -c -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/octave-5.2.0/octave/… -I/usr/include/octave-5.2.0/octave -pthread -fopenmp -g -O2 -fdebug-prefix-map=/build/octave-TC4r0Y/octave-5.2.0=. -fstack-protector-strong -Wformat -Werror=format-security embedded.cpp -o /tmp/oct-jjMiRM.o
g++ -Wdate-time -D_FORTIFY_SOURCE=2 -I/usr/include/octave-5.2.0/octave/… -I/usr/include/octave-5.2.0/octave -pthread -fopenmp -g -O2 -fdebug-prefix-map=/build/octave-TC4r0Y/octave-5.2.0=. -fstack-protector-strong -Wformat -Werror=format-security -rdynamic -fPIC -Wl,-Bsymbolic-functions -Wl,-z,relro -o embedded /tmp/oct-jjMiRM.o -L/usr/lib/x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu/octave/5.2.0 -loctinterp -loctave

Thanks for the help @dasergatskov

$ pwd
/usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu
$ ldd __init_gnuplot__.oct 
	linux-vdso.so.1 (0x00007ffc374b2000)
	libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f757c990000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f757c96d000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f757c77b000)
	libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f757c760000)
	libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f757c611000)

This all look strange. Does your octave work? Can you run it and do some plots with gnuplot backend?
Is this a conteinerasid installation (via snap or similar)?

Dmitri.

Octave works, including the use of the gnuplot backend:

x = linspace(1, 100, 1000);
y = x+3;
graphics_toolkit("gnuplot");
plot(x, y);

This is a standard installation on Ubuntu 20.04 LTS (no use of snaps nor containers):

sudo apt install octave octave-dev

Let me know if I can provide other relevant information / perform other tests. Thanks again for the help!

Is it possible that you have multiple octave installed?
what is the output of “which octave”?

Dmitri.

I installed octave 5.2 rpm (on Fedora) and it does show the same undefined symbol.
I do not see it in a self-compiled 6.1.1 I do not understand what is going on here.

Dmitri.

I also tried with a build from the default branch and it seems to work:

$ g++ -c -I/usr/include/hdf5/serial -I/usr/include/suitesparse -fPIC -I/home/osboxes/usr/include/octave-7.0.0/octave/.. -I/home/osboxes/usr/include/octave-7.0.0/octave -I/home/osboxes/usr/include  -pthread -fopenmp -g -O2    ../examples/code/embedded.cc -o /tmp/oct-CNPWgH.o
$ g++ -shared -I/usr/include/hdf5/serial -I/usr/include/suitesparse -I/home/osboxes/usr/include/octave-7.0.0/octave/.. -I/home/osboxes/usr/include/octave-7.0.0/octave -I/home/osboxes/usr/include  -pthread -fopenmp -g -O2 -rdynamic  -o embedded.so  /tmp/oct-CNPWgH.o   -fPIC  -L/home/osboxes/usr/lib   -L/home/osboxes/usr/lib -L/home/osboxes/usr/lib/octave/7.0.0 -loctinterp -loctave
$ LD_PRELOAD=./libinterp/.libs/liboctinterp.so:./liboctave/.libs/liboctave.so python embedded.py
GCD of [10, 15] is 5

embedded.py:

import ctypes
shared_lib = ctypes.CDLL('./embedded.so')
shared_lib.main()

It doesn’t seem to matter if this diff is applied or not:

diff -r 7854d5752dd2 examples/code/embedded.cc
--- a/examples/code/embedded.cc Wed Feb 10 10:10:40 2021 -0500
+++ b/examples/code/embedded.cc Thu Feb 18 10:25:11 2021 +0100
@@ -4,6 +4,11 @@
 #include <octave/parse.h>
 #include <octave/interpreter.h>
 
+extern "C"
+{
+int main(void);
+}
+
 int
 main (void)
  {

Also works with the Octave 5.2.0 distributed with Ubuntu 20.10. But I need to preload the libraries (not sure why):

$ g++ -c -Wdate-time -D_FORTIFY_SOURCE=2 -fPIC -I/usr/include/octave-5.2.0/octave/.. -I/usr/include/octave-5.2.0/octave  -pthread -fopenmp -g -O2 -fdebug-prefix-map=/build/octave-TC4r0Y/octave-5.2.0=. -fstack-protector-strong -Wformat -Werror=format-security    /usr/share/doc/liboctave-dev/examples/embedded.cc -o /tmp/oct-RhNJBU.o
$ g++ -shared -Wdate-time -D_FORTIFY_SOURCE=2 -I/usr/include/octave-5.2.0/octave/.. -I/usr/include/octave-5.2.0/octave  -pthread -fopenmp -g -O2 -fdebug-prefix-map=/build/octave-TC4r0Y/octave-5.2.0=. -fstack-protector-strong -Wformat -Werror=format-security -rdynamic  -fPIC -Wl,-Bsymbolic-functions -Wl,-z,relro  -o embedded.so  /tmp/oct-RhNJBU.o    -L/usr/lib/x86_64-linux-gnu -L/usr/lib/x86_64-linux-gnu/octave/5.2.0 -loctinterp -loctave   
$ python embedded.py
error: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/PKG_ADD: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__init_gnuplot__.oct: failed to load: /usr/lib/x86_64-linux-gnu/octave/5.2.0/oct/x86_64-pc-linux-gnu/__init_gnuplot__.oct: undefined symbol: _ZTI18handle_cdef_object
GCD of [10, 15] is 5
$ LD_PRELOAD=/usr/lib/x86_64-linux-gnu/liboctinterp.so:/usr/lib/x86_64-linux-gnu/liboctave.so python embedded.py
GCD of [10, 15] is 5

Many thanks, @mmuetzel and @dasergatskov for all the help on this issue. Using the LD_PRELOAD with Octave 5.2.0 allowed us to revive the RcppOctave R package and we can now execute code in Octave from R and retrieve results. Next on our list is to support the just-released Octave 6.2.0, so we can interface with the latest and greatest Octave. If we discover more, we will report back on the list on this next adventure. Thanks again!