I’m trying to build a simple embedding example in C++. I’m working on a CentOS 7 machine with GCC 4.8.5. I am using the generic Linux binaries from the downloads page for Julia 1.0.
You need to be careful with using the CFLAGS as given by julia-config.jl when compiling a C++ file as some of the flags might not be valid. For example, julia-config.jl --cflags gives me a -std=gnu99 flag, which is not valid for C++. In order to compile a C++ program, this flag has to be removed. Something similar might causing your problem.
I don’t have a system with such an old stdlibc++ to test and the error message is quite strange so I’ll have to guess…
The error comes from the LLVM ships with julia to not able to find the right symbol. Assuming the julia runs fine the stdlibc++ julia need should be fine (i.e. it was not missing from your download). Since compiling with C also didn’t error it suggests that the linker does not have issue with it either.
As for linking as c++ program, there’s one difference that I can think of that could lead to this problem, which is that c++ programs are automatically linked to libstdc++. It’s then possible that the automatically linked one is the system one that is too old which make the linker unhappy about the llvm’s requirement.
If this is indeed the issue, you need to convince g++ to find the right libstdc++ or at least avoid the wrong one. It’s a very unusual thing to do and as I said I don’t have a setup to test so you’ll need to figure out what to do on your own. A few things that you might find useful are,
You can stop the compiler from linking libstdc++ by using gcc or ld as linker instead of g++ (requires you to compile .c to .o with g++ first as a separate step)
You can use -nodefaultlibs to disable libstdc++ (there could be option for libstdc++ directly)
-D_GLIBCXX_USE_CXX11_ABI=1 since julia is probably using the newer one ( version 1 ) and default for gcc 4.8.5/centos 6 is 0. If this doesn’t solve it I can find my old julia embedded makefile and see what I have in there. You may need to set your LD_LIBRARY_PATH to point a compatible libstdc++.so. I’m on CentOS 6 at work as well.
Thank you for the thorough answer and suggestions!
I tried using the -nodefaultlibs option. It gave me the same error. Then I went inside the lib/julia directory of the generic Linux binaries, and found that there isn’t a symlink for libstdc++.so, there’s just the one versioned file. After adding that symlink, I was able to compile.
Did you try using gcc as a linker instead? I feel like that should work without the symlink.
Hard to say. None of that is needed for execution and you only hit an issue since you are trying (indirectly) to link to it. However, at least in this case, you are not actually linking to it, it’s just llvm that needs it, which means that it’s not a super unambiguous argument for shipping the dev file (symlink). I don’t really see what’s bad about shipping it either though.
You should try building with D_GLIBCXX_USE_CXX11_ABI=1
Pretty sure gcc 4.8.5 on your CentOS is going to default to ABI=0 ( the older one ). Julia’s libs were very likely built with ABI=1 ( that’s what the __cxx11 namespace indicates ). Hopefully this will do it. If you do link with any other ABI=0 libs you’d need to rebuild those with ABI=1.
During runtime you may need to set the LD_LIBRARY_PATH environment var so it will pick up the ABI=1 libs before your default system ABI=0 libs, but I’m not sure if that is necessary after setting the correct ABI. Alternatively ( maybe more recommended way? ) is to set the RPATH. Or a symlink can work as well, which is what you are doing.
Well, I’m not totally clear on the relationship between linking a .so and runtime loading of the .so. I’m also not clear on the what the symlink is doing in this case.
I do know that building a program with gcc 4.8.5 on CentOS 6 requires you to set the ABI=1 if you are linking with any libs that are built with ABI=1. Which is the maybe the case here ( non-standard CentOS 6 environment vs CentOS 7 ).
Symptomatically, if I see that exact error, I set the ABI to 1 and it fixes it. Possibly also setting the LD_LIBRARY_PATH.
I was using g++ to link, and I was passing -nodefaultlibs, but I also mistakenly put -lstdc++ in my command. If I remove -lstdc++ from the linking command, I don’t need the symlink.