Zulip Chat Archive

Stream: lean4

Topic: building shared library depending on another project


Tomas Skrivan (Feb 28 2024 at 18:27):

edit: For anyone from the future, working example project can be found at https://github.com/lecopivo/ReverseFFIwithMathlib


How do I build shared library that is depending on another project like std or mathlib? The issue I'm having is that the symbols from dependencies are not included in the created shared library.

Here is an example:

lakefile.lean

import Lake
open Lake DSL

package «SharedLibTest» where

lean_lib «SharedLibTest» where

@[default_target]
lean_lib «sharedlibtest» where
  roots := #[`SharedLibTest]
  defaultFacets := #[`shared]

require std from git "https://github.com/leanprover/std4.git" @ "main"

Main file SharedLibTest.lean

import Std.Data.RBMap.Basic

def minNumber (x y z : USize) : USize :=
  let map : Std.RBSet USize compare := Std.RBSet.ofList [x,y,z] _
  map.toList.head!

running

lake build && nm .lake/build/lib/libsharedlibtest.so

produces

output

See the last lines

                 U l_Std_RBNode_insert___rarg
                 U l_Std_RBNode_setBlack___rarg
                 U l_Std_RBNode_toList___rarg

indicates that functions Std.RBNode.insert, Std.RBNode.setBlack and Std.RBNode.toList are not included in the shared library.

How do I make sure that all the functions from dependencies are included in the generated library? (I'm expecting this question is just for @Mac Malone)

Mac Malone (Feb 28 2024 at 18:33):

@Tomas Skrivan The shared libraries Lake builds for a Lean library only include the symbols of the library itself. Unfortunately, there is no way to build a "fat" shared library with Lake yet. You instead must also link the shared libraries of the dependencies as well as the library itself to whatever itt consuming this shared library.

Tomas Skrivan (Feb 28 2024 at 18:36):

So in my project I should do lake build Std:shared Mathlib:shared ..., then hunt those libraries down somewhere in .lake/... and link it against the main shared library I want to use?

Tomas Skrivan (Feb 28 2024 at 18:39):

This is of course unfortunate as I'm forced to build everything, not only the stuff I'm actually using.

Eric Wieser (Feb 28 2024 at 19:13):

I think you can build just +YourModule:dynlib and it will build all the intermediate libraries?

Tomas Skrivan (Feb 28 2024 at 19:15):

Eric Wieser said:

I think you can build just +YourModule:dynlib and it will build all the intermediate libraries?

I do not understand, do you mean lake build +sharedlibtest:dynlib? That does not work.

Eric Wieser (Feb 28 2024 at 19:16):

I assume you had it as SharedLibTest not lowercase?

Tomas Skrivan (Feb 28 2024 at 19:17):

Ohh lake build +SharedLibTest:dynlib is doing something, let me investigate.

Tomas Skrivan (Feb 28 2024 at 19:20):

Running lake build +SharedLibTest:dynlib && nm .lake/build/lib/libSharedLibTest-1.so produces

output

In particular, the Std.RBNode... functions are not included

                 U l_Std_RBNode_insert___rarg
                 U l_Std_RBNode_setBlack___rarg
                 U l_Std_RBNode_toList___rarg

Tomas Skrivan (Feb 28 2024 at 20:06):

Ok I got it working when working with std. Now I'm struggling to get it working with mathlib. When compiling test c++ file using generated shared library I'm getting this error:

/usr/bin/ld: ~/ReverseFFIWithMathlib/.lake/packages/importGraph/.lake/build/lib//libImportGraph.so: undefined reference to `initialize_Lake_Load_Manifest'
/usr/bin/ld: ~/ReverseFFIWithMathlib/.lake/packages/importGraph/.lake/build/lib//libImportGraph.so: undefined reference to `l_Lake_Manifest_load_x3f'

where do I find initialize_Lake_Load_Manifest and l_Lake_Manifest_load_x3f?

Eric Wieser (Feb 28 2024 at 20:07):

Yes, you still have to link all the transitive .so files

Tomas Skrivan (Feb 28 2024 at 20:07):

And I created example repo for any unfortunate soul doing this in the future
https://github.com/lecopivo/ReverseFFIwithMathlib

Tomas Skrivan (Feb 28 2024 at 20:09):

Oh those functions are in libLake.a

Tomas Skrivan (Feb 28 2024 at 20:10):

And adding -lLake flag in lakefile fixes this!

Tomas Skrivan (Feb 28 2024 at 20:35):

It would be nice to have shared version of libLake.a as my shared library has 23kB but because I have to link statically against libLake.a it balloons to 1.3MB.


Last updated: May 02 2025 at 03:31 UTC