I want to FFI to a third-party C library from Idris but I'm getting "undefined symbol". I'm new to C/C compilation.
I'm doing this by wrapping the C in a pure C layer which I call from Idris. The C code is provided as a bunch of .h
headers and a single .so
shared library. At the moment I only have one C file, but I may have more later.
Here's the C library header include/foo.h
#include <some/other/library/header.h>
namespace mynamespace {
class Foo {
public:
Foo();
}
}
and the C wrapper wrapper.cpp
#include <foo.h>
extern "C" {
struct cFoo;
using namespace mynamespace;
struct cFoo* cFoo_new() {
return reinterpret_cast<cFoo*>(new Foo());
}
}
The shared library is lib/libfoo_ext.so and I'm compiling these with
g -shared -Iinclude -Llib -lfoo_ext -o libfoo.so wrapper.cpp
That runs without errors. Meanwhile, the Idris code is
module Foo
import System.FFI
export
Foo : Type
Foo = Struct "cFoo" []
%foreign "C:cFoo_new,libfoo"
export
mkFoo : Foo
and I'm calling mkFoo
in a test file. When I do this I get
Exception: (while loading libfoo.so) .../build/exec/_tmpchez_app/libfoo.so: undefined symbol: _ZN17mynamespace6FooC1Ev
CodePudding user response:
This command:
g -shared -Iinclude -Llib -lfoo_ext -o libfoo.so wrapper.cpp
is incorrect. Assuming libfoo_ext
is the 3rd party library which implements mynamespace::Foo::Foo()
, the link command should be:
g -shared -Iinclude -Llib -o libfoo.so wrapper.cpp -lfoo_ext
The order of libraries and sources on the link line matters, yours is wrong.