Cxx.jl LLVM error / unresolved external function

Today I though I ruin my day by trying to interface our main DAQ framework (written in C++ and ROOT) in Julia and I think I am quite successful so far (haha). The best thing is, the software is closed source so I cannot share that code.
Anyways, maybe someone can push me into the right direction…

The framework I am trying to interface is mostly header-only and as a first step I tried to compile a basic function, which should not need any linking (as far as I can judge). At least, the code inside the cxx string can be compiled with the following flags:

CC = g++
CFLAGS = -I${FRAMEWORK_DIR}/software -std=c++11

Here is a simple call of a dummy function which utilises a class from the framework (namely JMatrixND):

using Cxx

const incpath = joinpath(ENV["FRAMEWORK_DIR"], "software")

addHeaderDir(incpath, kind=C_System)

cxx"""
#include <chrono>
#include <iostream>
#include "JMath/JMatrixND.hh"

void matrix_test(int N) {
    std::cout << "Generating two " << N << "x" << N << " matrices." << std::endl;
    JMATH::JMatrixND A(N);
    JMATH::JMatrixND B(N);

    for (size_t i = 0; i != A.size(); ++i) {
        for (size_t j = 0; j != A.size(); ++j) {
            A.at(i, j) = rand() / double(RAND_MAX);
            B.at(i, j) = rand() / double(RAND_MAX);
        }
    }

    std::cout << "Multiplying them..." << std::endl;

    std::chrono::steady_clock::time_point begin = std::chrono::steady_clock::now();
    A.mul(B);
    std::chrono::steady_clock::time_point end = std::chrono::steady_clock::now();

    int delta_t = std::chrono::duration_cast<std::chrono::microseconds>(end - begin).count();

    std::cout << "Elapsed time: " << delta_t << " us" << std::endl;
}
"""

@cxx matrix_test(10)

When I run it, I get

LLVM ERROR: Program used external function '_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev' which could not be resolved!

and after commenting out some lines, I figured that it fails at A.mul(B);, however things like std::cout << A.at(1, 2) << std::endl; work, so it seems to be able to run some code.

I examined mul and also copied the main multiplication routine into the cxx string and it worked. Besides that, there is nothing more other than throwing an exception when the matrix sizes differ (which is not the case). Here is the source, which I simplified to not get any trouble:

    JMatrixND& mul(const JMatrixND& A,
		   const JMatrixND& B)
    {
      if (A.size() == B.size()) {

	this->resize(A.size());

	// here the routine which works when copy&pasted instead of calling `A.mul(B)`
        // the only methods used in the block are `.at()` and `.size()`

      } else {

	THROW(JException, "JMatrixND::mul() inconsistent matrix dimensions " << A.size() << ' ' << B.size());
      }

      return *this;
    }

Any ideas?

A bit more information, the THROW is defined like this:

#define THROW(JException_t, A) do {
    throw JException_t(static_cast<std::ostringstream&>(JLANG::getOstream() 
    << __FILE__ << ':' << __LINE__ << std::endl << A).str());
} while(0)

I guess it’s hard to help without having access to the code base. It seems that this JException_t pulls in a library dependency, which I have to figure out how to resolve.

I boiled it down to

using Cxx
using Libdl

const incpath = joinpath(ENV["FRAMEWORK_DIR"], "software")
const libpath = ENV["JPP_LIB"]

addHeaderDir(incpath, kind=C_System)
Libdl.dlopen(joinpath(libpath, "liblang.so"), Libdl.RTLD_GLOBAL)

cxx"""
#include <iostream>
#include "JLang/JException.hh"

void throw_test() {
    std::cout << "Throwing..." << std::endl;
    THROW(JLANG::JException, "meeeeh");
    return;
}
"""

@cxx throw_test()

and I still get:

LLVM ERROR: Program used external function '_ZNSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEC1Ev' which could not be resolved!

In fact, it’s not even needed to link against liblang.so from the core library. Compiling and running manually works (I added a main and called throw_test() inside it):

░ tgal@staticbox:~/tmp/jinterface
░ 16:24:03 > g++ -I${JPP_DIR}/software -std=c++11 throw.cc

░ tgal@staticbox:~/tmp/jinterface
░ 16:24:06 > ./a.out
Throwing...
terminate called after throwing an instance of 'JLANG::JException'
  what():  throw.cc:6
meeeeh
[1]    2309 abort (core dumped)  ./a.out

How should I debug this?

I guess the main problem is that the core framework cannot be compiled with clang, but only with gcc.