embedding Julia in C/C++ on OSX

2019-06-13 17:07发布

I am trying to compile a very simple C/C++ program to call Julia functions. Following the instructions that you find on the Julia documentation page, I set up my link path to /Users/william.calhoun/Desktop/romeo/lib/julia looking for libjulia.so and I set up my include path to /Users/william.calhoun/Desktop/romeo/include/julia looking for julia.h

I have a C file called test.c which runs the following code:

#include <stdio.h>
#include "skeleton.h"
#include <julia.h>


int main(int argc, const char * argv[]) {

    jl_init(NULL);

    /* run julia commands */
    jl_eval_string("print(sqrt(2.0))");

    /* strongly recommended: notify julia that the
     program is about to terminate. this allows
     julia time to cleanup pending write requests
     and run all finalizers
     */


    jl_atexit_hook();

   return 0;
}

However this yields the following error:

Undefined symbols for architecture x86_64:
    "_jl_atexit_hook", referenced from:
        _main in test.o
    "_jl_eval_string", referenced from:
        _main in test.o
    "_jl_init", referenced from:
        _main in test.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I am not doing anything other than calling functions defined properly (hopefully) within the Julia source code. What am I doing wrong? This seems like the simplest example and I can't figure it out.

Any help would be much appreciated!

标签: c julia
1条回答
Animai°情兽
2楼-- · 2019-06-13 17:42

Linking to libjulia (libjulia.dynlib on OS/X)

This error is a result of not linking to libjulia, as all of the symbols (_jl_atexit_hook, _jl_eval_string, _jl_init) are located in that library. Broadly, for all 3 of the following platforms (Windows, OS/X, Linux), the approach is similar, and though the location of the libjulia library is different on Windows than the other 2 this stackoverflow question is applicable. Also to be completely accurate, on OS/X, dynamic libraries have the extension .dynlib not .so as they do on Linux.

The link step

For simplicity, assuming you've compiled to object code (there is a file called embed.o), here's the link step.

cc -o embed embed.o -L/Users/william.calhoun/Desktop/romeo/lib/julia -Wl,-rpath,/Users/william.calhoun/Desktop/romeo/lib/julia -ljulia

There are 2 important things to note here.

  1. Linking using -ljulia will allow the linker to resolve all of the above symbols.
  2. Since this is a dynamic library and that dynamic library is located in a non standard location (e.g. not in /usr/lib), the dynamic linker will not be able to find it at run time unless you give it special instructions on how to find it. The -rpath directive causes the linker to insert the path /Users/william.calhoun/Desktop/romeo/lib/juliainto the list of paths to search.
查看更多
登录 后发表回答