Need Help in embeding julia in c/c++

greeting, i would really appreciate if some one let me know why my code in not working:
currently i am on gcc version 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) and my julia version is 1.3.1

i was trying to embed the julia in to c/c++ but i am failing to to the simplest thing here is my code :
this is my testing.c file :

#include <julia.h>
JULIA_DEFINE_FAST_TLS()

int main(int argc, char *argv[]){
    jl_init();
    jl_eval_string("println(\"Hi!\")");
    jl_atexit_hook(0);
    return 0;
}

and this is my makefile :

JL_SHARE = ../../../../../mnt/e/"Program Files"/Julia-1.3.1/Linux/julia-1.3.1/share/julia
CFLAGS   += $(shell $(JL_SHARE)/julia-config.jl --cflags)
CXXFLAGS += $(shell $(JL_SHARE)/julia-config.jl --cflags)
LDFLAGS  += $(shell $(JL_SHARE)/julia-config.jl --ldflags)
LDLIBS   += $(shell $(JL_SHARE)/julia-config.jl --ldlibs)

CC := gcc
CXX := g++

.PHONY: all
all: testing

main: testing.c makefile
	$(CC) $(CFLAGS) $(LDFLAGS) $(LDLIBS) -o test testing.c

.PHONY: clean
clean:
	$(RM) main

after trying to make : i get the following error which i have no clue what to do with spend 2 to 3 hour on the net to figure it out so you guys are my last hope :

Two passes with the same argument (-juliaO0) attempted to be registered!

signal (11): Segmentation fault
in expression starting at /mnt/e/Program Files/Julia-1.3.1/Linux/julia-1.3.1/share/julia/julia-config.jl:136
_ZN4llvm14PassNameParser14passRegisteredEPKNS_8PassInfoE at /mnt/e/Program Files/Julia-1.3.1/Linux/julia-1.3.1/bin/../lib/julia/libLLVM-6.0.so (unknown line)
Allocations: 2451 (Pool: 2443; Big: 8); GC: 0
Segmentation fault (core dumped)
Two passes with the same argument (-juliaO0) attempted to be registered!

signal (11): Segmentation fault
in expression starting at /mnt/e/Program Files/Julia-1.3.1/Linux/julia-1.3.1/share/julia/julia-config.jl:136
_ZN4llvm14PassNameParser14passRegisteredEPKNS_8PassInfoE at /mnt/e/Program Files/Julia-1.3.1/Linux/julia-1.3.1/bin/../lib/julia/libLLVM-6.0.so (unknown line)
Allocations: 2450 (Pool: 2442; Big: 8); GC: 0
Segmentation fault (core dumped)
gcc -std=gnu99 -I'/mnt/e/Program Files/Julia-1.3.1/Linux/julia-1.3.1/include/julia' -fPIC    testing.c   -o testing
/tmp/ccCupFXK.o: In function `jl_register_ptls_states_getter':
testing.c:(.text+0x24): undefined reference to `jl_set_ptls_states_getter'
/tmp/ccCupFXK.o: In function `main':
testing.c:(.text+0x3b): undefined reference to `jl_init__threading'
testing.c:(.text+0x47): undefined reference to `jl_eval_string'
testing.c:(.text+0x51): undefined reference to `jl_atexit_hook'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'testing' failed
make: *** [testing] Error 1

i even tried to compile it from the comand line as follow : /mnt/e/"Program Files"/Julia-1.3.1/Linux/julia-1.3.1/share/julia/julia-config.jl --cflags --ldflags --ldlibs | xargs gcc testing.c

but the above resulted to a almost similar thing :

Two passes with the same argument (-juliaO0) attempted to be registered!

signal (11): Segmentation fault
in expression starting at /mnt/e/Program Files/Julia-1.3.1/Linux/julia-1.3.1/share/julia/julia-config.jl:136
_ZN4llvm14PassNameParser14passRegisteredEPKNS_8PassInfoE at /mnt/e/Program Files/Julia-1.3.1/Linux/julia-1.3.1/bin/../lib/julia/libLLVM-6.0.so (unknown line)
Allocations: 2452 (Pool: 2443; Big: 9); GC: 0
/tmp/ccpMGJGH.o: In function `jl_register_ptls_states_getter':
testing.c:(.text+0x24): undefined reference to `jl_set_ptls_states_getter'
/tmp/ccpMGJGH.o: In function `main':
testing.c:(.text+0x3b): undefined reference to `jl_init__threading'
testing.c:(.text+0x47): undefined reference to `jl_eval_string'
testing.c:(.text+0x51): undefined reference to `jl_atexit_hook'
collect2: error: ld returned 1 exit status

Please, quote your code

i did a edit is that what you meant ?

Replace the quotes with ```

i see done !

I wrestled with some of this a month or so ago, so some details are (already) rusty. Plus I had an additional layer to call from Java! However, in a quick review of my code, I see that when I had the following the wrap the jl_eval_string(), which as the comment notes I copied from code that is part of the Julia distribution. Maybe it will help find errors? If I get some time later I can try to dig more into your example.

// copied from julia/test/embedded/embedding.c
jl_value_t *checked_eval_string(const char* code)
{
  jl_value_t *result = jl_eval_string(code);
  if (jl_exception_occurred()) {
    // none of these allocate, so a gc-root (JL_GC_PUSH) is not necessary
    jl_call2(jl_get_function(jl_base_module, "showerror"),
	     jl_stderr_obj(),
	     jl_exception_occurred());
    jl_printf(jl_stderr_stream(), "\n");
    jl_atexit_hook(1);
    exit(1);
  }
  assert(result && "Missing return value but no exception occurred!");
  return result;
}

Welcome to the Julia Discourse @Fringe!

Looking at your error message it looks like Make wasn’t passing the linker arguments to gcc. I have no idea why that would happen. It might just be a quirk of how the error message is printed though.

It might help if you start even simpler than using julia-config.jl and a Makefile. What do you get if you run the following from a shell prompt?

gcc -o test -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib testing.c -ljulia $JULIA_DIR/lib/julia/libstdc++.so.6

where $JULIA_DIR is the root directory of your julia installation. Does that work?

i just tested the command above as following ways :

gcc -o test -fPIC -I$../../../../../../mnt/s/projectDrone/Linux/julia-1.3.1/include/julia -L$../../../../../../mnt/s/projectDrone/Linux/julia-1.3.1/lib testing.c -ljulia $../../../../../../mnt/s/projectDrone/Linux/julia-1.3.1/lib/julia/libstdc++.so.6  

and

gcc -o test -fPIC -I$/mnt/s/projectDrone/Linux/julia-1.3.1/lib/julia/include/julia -L$mnt/s/projectDrone/Linux/julia-1.3.1/lib testing.c -ljulia $mnt/s/projectDrone/Linux/julia-1.3.1/lib/julia/libstdc++.so.6

both of them resulted with same error which says it cant find libstdc++.so.6:

gcc: error: $../../../../../../mnt/s/projectDrone/Linux/julia-1.3.1/lib/julia/libstdc++.so.6: No such file or directory

so i decided to check if libstdc++.so.6 does exist and typing

test -f ../../../../../../mnt/s/projectDrone/Linux/julia-1.3.1/lib/julia/libstdc++.so.6 && echo "$FILE exist"

gave the answer of

 exist

so currently i am very very confused any idea what is going on ?
(uploaded a pic of exactly what was happening too

Woops. Turns out you don’t actually need that file—well at least I don’t on my machine, which is running Ubuntu 19.04, gcc 8.3.0. Try just running

gcc -o test -fPIC -I$JULIA_DIR/include/julia -L$JULIA_DIR/lib testing.c -ljulia

Now it is telling me that it cannot find julia.h :
i ran the command :

gcc -o test -fPIC -I$/mnt/s/projectDrone/Linux/julia-1.3.1/include/julia -L$/mnt/s/projectDrone/Linux/julia-1.3.1/lib testing.c -ljulia

answer was

testing.c:3:10: fatal error: julia.h: No such file or directory
 #include <julia.h>
          ^~~~~~~~~
compilation terminated.

which is very odd since if i go to the directory :

/mnt/s/projectDrone/Linux/julia-1.3.1/include/julia

i can indeed see julia.h exist i tried to even change the include code in the testing.c file as follow:

#include "/mnt/s/projectDrone/Linux/julia-1.3.1/include/julia/julia.h"

which does get rid of the first error but then it tells me it can not find the files which julia.h are including does this mean -fPIC -I$/mnt/s/projectDrone/Linux/julia-1.3.1/include/julia this portion is not working ?

That’s very strange. I’m not sure what’s going on but it’s definitely a general gcc issue and not a julia specific issue. For some reason adding /mnt/s/projectDrone/Linux/julia-1.3.1/include/julia to your include path is not working. Is that just a normal directory? Are you mounting a remote directory or something? Maybe gcc is having trouble with that?

i am using the Ubuntu bash on windows 10 and all of my windows partitions are located in /mnt and s is one of my hard drives so i have no clue why gcc could have problem with it :frowning:

ahaaaaaaaaaaaaaaaa it seems i am a little bit stupid since i forgot the $ was for when you use variable and i was using the path so deleting the $ made it to compile. now i have to figure out why my make file is not working but having something which does compile i probably will be able to figure it out other wise i will ask few more question thank you for your time :smiley:

actually i got all excited and all but with the way you told me it does compile but i can not run the executable which it does make it gives me the following error :

./test
./test: error while loading shared libraries: libjulia.so.1: cannot open shared object file: No such file or directory

any idea why ?

Yes, fortunately that’s a simple issue to fix. When you build the executable you’re using dynamic linking, so all the libraries the executable uses need to be dynamically loaded at runtime. You’re getting that error because when your system tries to execute the test executable it can’t find the libjulia shared library. It can’t find that because the library isn’t in your system’s library search path. See:

https://unix.stackexchange.com/questions/22926/where-do-executables-look-for-shared-objects-at-runtime

For a very brief intro to understanding how shared libraries are loaded at runtime. In short, you have a few options. You can install the julia libraries in a standard location for system libraries, you can add the location of the julia libraries to your LD_LIBRARY_PATH environment variable, or you can call gcc with the --rpath flag to hardcode the path to the libraries relative to the path to the executable into the executable itself. I recommend doing some general reading on dynamic linking on Unix like systems to get a better understanding of all this. I realize I dumped quite a bit of information all at once there.

1 Like

so for who ever in feature find this topic after hours of struggling finally i was manage to make things work , so it ended up that my initial code was just fine but the code which i downloaded maybe had some compatibility issues or something, quite honestly have no clue what it was but the flag--ldflags pass to the config.gl was causing segfault after hours of thinking it could be from my side i decided to instead of downloading the compiled format of Julia clone the github of julia (checked out v1.3.0) and do a manual make after doing such finally i was able to compile their own test file which is located in embedding folder, initially same segfault as above was resulted in testing the file in embedding folder but after doing a make on julia which i cloned i was able to run the test file and then proceed to run my own code which ran flawlessly with the make file i had. note if you defined the path in bash.bashrc after making the new julia dont forget to change that path too. and good luck.

1 Like

I am trying to embed a Julia library into a c++ application. The Julia library requires loading a large Julia object that takes time to load and I would like to keep the Julia context open so I do not have to reload the Julia object unless I finalize the Juliacontext. Is this possible?