Compiling to shared library with static dependencies
Tanel L via Digitalmars-d
digitalmars-d at puremagic.com
Wed Dec 14 14:17:25 PST 2016
First of all thanks Johan for urging me to compile it with only
with that flag. It worked! Previously I tried to compile it with
only BUILD_SHARED or both - and that failed. But I got it
working. Thanks! More details below.
On Wednesday, 14 December 2016 at 21:41:53 UTC, Relja
Ljubobratovic wrote:
> On Wednesday, 14 December 2016 at 20:46:15 UTC, Tanel L wrote:
>> Hi, thanks for the answer.
>>
>> I had tried disabling all imports, but now I created a clean
>> new project to test this - it worked.
>
> Awesome. So LDC compile-link is ok, and also python runtime
> linking is good.
>
>>
>> After that I moved the compiling and linking over to DUB, with
>> dependencies:
>>
>> dependency "dcv" version="0.1.7"
>> dependency "mir" version="0.22.0"
>> targetPath "output"
>> targetType "dynamicLibrary"
>> dflags "-defaultlib=phobos2"
>
> Why are you defining defaultlib explicitly here? - wouldn't
> this work fine without it? Also, like I said before, try
> removing mir from dependencies since its included with dcv.
>
Yes it probably would, call it inexperience :) I'm now much
smarter b/c I got it working :D
>>
>> The library source:
>> import std.stdio;
>> import dcv;
>> import core.runtime:Runtime;
>> extern (C) int doit(int a, int b) {
>> return a*b + dcv.imread("1.jpg").width.to!int;
>> }
>
> Did you actually call Runtime.initialize before calling doit?
> Also, did you try the same code in ordinary D app? Anyways,
> this works for me:
>
No, I will use your example as an example for the future, but It
seems it is not required. Although I really did it with
Initialize, I just forgot it from the sample I pasted here - it
didn't make a difference.
> D source
> ========
> import std.stdio;
> import core.runtime;
>
> extern (C) void initd()
> {
> Runtime.initialize;
> }
>
> extern (C) void terminated()
> {
> Runtime.terminate();
> }
>
> extern (C) void showim()
> {
> import dcv;
> auto im = imread("img.jpg");
> imshow(im);
> waitKey();
> }
> ========
>
Thanks, I will use this as a template in the future.
> Python source
> ========
> from ctypes import *
>
> d = CDLL("libctypestest.so")
> d.initd()
> d.showim()
> d.terminated()
> ========
>
>>
>> This created an .so with huge amount of all kinds of external
>> so deps, but it still failed with the same error:
>> OSError: libdynlibtest.so: undefined symbol: _d_eh_personality
>
> All kinds of external deps are expected since dcv is linking to
> ggplotd and ffmpeg, which also link to whole lotta libraries.
> I'm not sure about the binary size though. If you can, use only
> dcv:core which has no other dependencies other than Mir. Also,
> dcv:io links to ffmpeg at the moment, but if you need only
> image i/o and would like to avoid linking to ffmpeg, you could
> use just dcv:core with imageformats[1] (dcv wraps it's io
> methods in imread). If you need help with this let me know.
>
Thanks, I don't need ffmpeg and I will surely use your advice. I
am not worried about the size much. Is there any way to include
many/most of them into the binary? Or should I just ship the deps
alongside the shared lib?
>>
>> Otherwise:
>> Linux Mint 18 (basically Ubuntu 16.04)
>> LDC - the LLVM D compiler (1.1.0-beta6):
>> based on DMD v2.071.2 and LLVM 3.9.0
>> built with LDC - the LLVM D compiler (1.0.0)
>> gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
>> DUB version 1.1.1, built on Nov 30 2016
>>
>> Thank you for helping! :)
>
> Hey, no sweat - its a pleasure! I'm really glad you'd like to
> use D (and Mir and DCV for that matter). I'd really like to
> help you out as much as I can, so this can work out for you! :)
>
> Cheers,
> Relja
So I got it working.
Going to leave a mark behind about what I did incase someone else
runs into this.
First of all, I successfully compiled ldc2 with:
cmake .. -DBUILD_SHARED_LIBS=ON
make -j 7
I then removed the installed "dmd" DEB package because it would
always link with its libphobos2.so. I installed only "dub" from
the apt repo instead.
Added the "lflags" param to dub, to have a final dub.sdl:
targetPath "output"
targetType "dynamicLibrary"
--dflags "-defaultlib=phobos2-ldc"
lflags "-L/home/tanel/thirdparty/ldc-dynamic-working/build/lib/"
Mucked around figuring out why dub enforces a
"-defaultlib=phobos2" argument to ldc2 - didn't figure it out.
LDC won't compile because it doesn't exists and if I add my own
to dub.sdl LDC whines that the flag is declared twice.
So i created a symlink in the dynamic ldc lib dir and removed the
"dflags" from my .sdl:
ln -s libphobos2-ldc.so libphobos2.so
Then it still couldn't find it, so I discovered that I had used
LD_LIBRARY_PATH, instead of LIBRARY_PATH - doh! Fixed it.
In .bashrc:
export
LIBRARY_PATH=/home/tanel/thirdparty/ldc-dynamic-working/build/lib/
$ dub run --config=library --compiler=ldc2
$ python -c "from ctypes import *; print
CDLL('libdynlibtest.so').doit(10,10)"
> 2020
Success!
Thank you both so much. With this I can successfully move forward
with using D in our company :)
More information about the Digitalmars-d
mailing list