Build a Python package which uses a C library

Hi, I’m trying to build a Python package (fcmaes) which uses a C library (MKL). I wrote this default.nix:

{ lib, buildPythonPackage, fetchPypi, python, scipy, mkl }:

buildPythonPackage rec {
  pname = "fcmaes";
  version = "0.9.5.7";

  src = fetchPypi {
    inherit pname version;
    sha256 = "1za05afp6x98dmdj61brkkdfzkgv0ixyafp8zh94fa001vs2qrvl";
  };

  propagatedBuildInputs = [
    scipy
    mkl
  ];

  # preCheck = ''
  #   export LD_LIBRARY_PATH=${lib.strings.makeLibraryPath [ mkl ]}:$LD_LIBRARY_PATH;
  # '';

  meta = with lib; {
    description = "Fast Python implementation of the CMA-ES optimization algorithm";
    homepage = "https://github.com/dietmarwo/fast-cma-es";
    license = licenses.mit;
    maintainers = [ maintainers.juliendehos ];
  };
}

but I get this error when I build the package:

OSError: libmkl_rt.so: cannot open shared object file: No such file or directory

I can build the package if I uncomment the preCheck attribute but I still have the error when I try to use the package. How can I include correctly the MKL path in the package?

2 Likes

Usually, I would recommend hardcoding the path using a patch, see for example cairocffi:

But here it does not look like mkl is used by the Python package itself but rather by the C++ library from the _fcmaescpp directory.

I would guess that the error comes from the pre-built .so file in the fcmaes/lib directory. I would suggest building the library yourself (using a separate stdenv.mkDerivation call with sourceRoot in the _fcmaescpp directory and cmake as a dependency and then replace the pre-built .so file with a symlink to the one from your auxiliary derivation.

2 Likes

Indeed, it seems that mkl is used by the pre-built lib. I’ll try to package this lib as you suggested. Thank you very much.

1 Like

If you want to import or use that package from another package, then you will have to patch and hardcode the paths.

Using wrapXXXX doesn’t compose.

1 Like