Is it possible to build with shared libraries included?

I try to build OCaml project via dune.
I want to let contain “libissl.so” and “libcrypto.so” in OCaml binary.(main.exe)

My dune file is following:

(executable
 (public_name sample_pj)
 (name main)
 (libraries sample_pj lwt cohttp cohttp-lwt-unix ssl ptime)
 (flags -cclib -lcrypto -cclib -lssl)
 (preprocess
  (pps ppx_deriving.std)))

I build that OCaml project and copy to a Ubuntu Docker container(for test).
And i check depends libraries…

root@b565f1720b1f:/tmp# ldd main.exe
        linux-vdso.so.1 (0x00007fff6ea4c000)
        libssl.so.1.1 => not found
        libcrypto.so.1.1 => not found
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fadf5af5000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fadf5757000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fadf5553000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fadf5162000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fadf63ac000)
root@b565f1720b1f:/tmp# 

So, main.exe does not contain “libssl.so” and “libcrypto.so”.
How can i let contain these shared library into OCaml binary?

I do not have much knowledge about C and shared libraries…
Maybe I’m fundamentally making various misunderstandings?

You probably want your ‘flags’ field to be a ‘link_flags’ field.

Edit: actually that can’t be your issue because you appear to have built your main.exe. So I cannot really understand how you reached the point of dynamic link failure at run time. (I can’t really understand either how you got your main.exe build to complete with your link time dependencies specified in the ‘flags’ field.)

What you want to do is to link libssl and libcrypto statically. This means that you need to have libssl.a and libcrypto.a (which are the static versions of libssl.so and libcrypto.so) available in directory, say, dir and you want to pass -cclib -Ldir in the flag field so that the libraries can be found at link time.

Best wishes,
Nicolás

2 Likes

@cvine @nojb

Thank you for reply!

I builded with following flags and link_flags:

(flags -cclib -L/usr/lib/x86_64-linux-gnu -cclib -lcrypto -cclib -lssl)

and

(link_flags -cclib -L/usr/lib/x86_64-linux-gnu -cclib -lcrypto -cclib -lssl) 

There is libssl.a and libcrypto.a.

[koji:~]$ find /usr/lib/x86_64-linux-gnu -type f | grep -E (libssl|libcrypto)
/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
/usr/lib/x86_64-linux-gnu/libcrypto.so.1.0.0
/usr/lib/x86_64-linux-gnu/libssl.so.1.1
/usr/lib/x86_64-linux-gnu/libssl.a
/usr/lib/x86_64-linux-gnu/libssl3.so
/usr/lib/x86_64-linux-gnu/libcrypto.a
/usr/lib/x86_64-linux-gnu/pkgconfig/libssl.pc
/usr/lib/x86_64-linux-gnu/pkgconfig/libcrypto.pc
/usr/lib/x86_64-linux-gnu/libssl.so.1.0.0
[koji:~]$ 

then i executed:

[koji:sample_pj]$ dune build && sudo sh -c "sudo docker cp ./_build/default/bin/main.exe 0812956fe9e8:/tmp"
[koji:sample_pj]$ sudo docker exec 0812956fe9e8 ldd /tmp/main.exe
        linux-vdso.so.1 (0x00007fff156a1000)
        libssl.so.1.1 => not found
        libcrypto.so.1.1 => not found
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f38925d4000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3892485000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f389247f000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f389228d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f3892c95000)
[koji:sample_pj]$ 

so i can build without error.
But yet libssl and libcrypto are not included…
My assumption is that libssl and libcrypto should not be included in the ldd results.
I epect a result like :

[koji:sample_pj]$ sudo docker exec 0812956fe9e8 ldd /tmp/main.exe
        linux-vdso.so.1 (0x00007fff156a1000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f38925d4000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f3892485000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f389247f000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f389228d000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f3892c95000)

Am i maiking a mistake?

The compiler is probably choosing the shared library (.so) over the static one (.a).
You can try by using an explicit file name, as in -l:libssl.a -l:libcrypto.a instead of -lssl -lcrypto.

Cheers,
Nicolás

1 Like

@nojb

Thank you!
I was able to build including the 2 libraries!

At first, i tryed with follwoing flags

(flags  -cclib -L/usr/lib/x86_64-linux-gnu -cclib -l:libssl.a -cclib -l:libcrypto.a)

But did not work.
Without error but 2 libraries were not included.

Then i tryed create a new empty directory and copy only 2 static library into that.

[koji:~]$ mkdir /tmp/ocaml
[koji:~]$ cd /tmp/ocaml
[koji:ocaml]$ cp /usr/lib/x86_64-linux-gnu/libssl.a .
[koji:ocaml]$ cp /usr/lib/x86_64-linux-gnu/libcrypto.a .

edided -L optoin on flags.

(flags  -cclib -L/tmp/ocaml -cclib -l:libssl.a -cclib -l:libcrypto.a)

Then worked!

root@0812956fe9e8:/# ldd /tmp/main.exe
        linux-vdso.so.1 (0x00007ffc3fbf1000)
        libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f50c4e7e000)
        libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f50c4d2f000)
        libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f50c4d29000)
        libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f50c4b37000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f50c586b000)
root@0812956fe9e8:/#

And i tested following flags.
It works too.

(flags  -cclib -L/tmp/ocaml -cclib -lssl -cclib -lcrypto) 

In conclusion, SharedLibrary (.so) and StaticLibrary (.a) must not be stored in same directory to link statically.

Great thanks for your support!

1 Like