diffkemp icon indicating copy to clipboard operation
diffkemp copied to clipboard

Nix: add runtime dependencies

Open PLukas2018 opened this issue 9 months ago • 1 comments

When running DiffKemp using binary build by nix (result/bin/diffkemp), DiffKemp did not work if the user did not install the dependencies that are used at runtime (like llvm - opt, llvm-config, ...) on his local machine. This commit wraps the necessary dependencies to the program.

Note: It looks like this change creates a problem eg. if the user installs dependencies for building the kernel (like libelf-dev, ...) on his local machine and then he would run result/bin/diffkemp build-kernel. He would be unable to build the kernel because the wrapped dependencies (clang/gcc) would not find the locally installed dependencies (libelf-dev, ...).

PLukas2018 avatar May 13 '24 16:05 PLukas2018

When running DiffKemp using binary build by nix (result/bin/diffkemp), DiffKemp did not work if the user did not install the dependencies that are used at runtime (like llvm - opt, llvm-config, ...) on his local machine. This commit wraps the necessary dependencies to the program.

Note: It looks like this change creates a problem eg. if the user installs dependencies for building the kernel (like libelf-dev, ...) on his local machine and then he would run result/bin/diffkemp build-kernel. He would be unable to build the kernel because the wrapped dependencies (clang/gcc) would not find the locally installed dependencies (libelf-dev, ...).

Nice discovery!

So, IIUC, without this change, you cannot run DiffKemp built by Nix if you don't have some dependent binaries installed. But with this change, you cannot run diffkemp build-kernel at all?

Could we somehow limit the amount of wrapped runtime dependencies? For example, I'd try to avoid GCC as it's not a hard dependency of DiffKemp, it's just required to analyse a project which is normally built by GCC so I'd let user install it on his local machine. The only thing that I'd wrap are binaries which we explicitly call, i.e. opt, llvm-config, ...

viktormalik avatar May 14 '24 15:05 viktormalik

So, IIUC, without this change, you cannot run DiffKemp built by Nix if you don't have some dependent binaries installed.

Yes, without this change it is not possible to run result/bin/diffkemp created by nix if a user does not have clang, opt, llvm-config, ... installed. But in the shell env (using nix develop) it should normally work.

But with this change, you cannot run diffkemp build-kernel at all?

With this change, it looks like it is not possible to use result/bin/diffkemp build-kernel (binary build by nix) even if the user installs the necessary dependencies for kernel compilation (libelf-dev, openssl-dev ...) to his local machine. I think it is caused by the added nix clang/cc binary which is used when build-kernel tries to find out which command it should use for file compilation, but the nix clang/cc probably does not use the locally installed libraries. Using build-kernel in locally build DiffKemp (bin/diffkemp) and in nix shell (nix develop, ...) should work fine.

Could we somehow limit the amount of wrapped runtime dependencies?

So probably these dependencies would make sense to leave

llvmPackages.clangNoLibcxx
llvmPackages.libllvm.dev
llvmPackages.libllvm

and the rest remove --make, gcc and diff should probably a C developer have installed. The cscope does not make sense if build-kernel is not possible to make work because of llvmPackages.clangNoLibcxx.

I am not sure if it is possible to add individual binary files to PATH, but I can look into it.

PLukas2018 avatar May 16 '24 16:05 PLukas2018

So probably these dependencies would make sense to leave

llvmPackages.clangNoLibcxx
llvmPackages.libllvm.dev
llvmPackages.libllvm

and the rest remove --make, gcc and diff should probably a C developer have installed.

So, my reasoning is the following: we should bundle all the tools that DiffKemp actually runs for any kind of analysed project - tools for creating and working with LLVM IR files (clang, opt, other LLVM tools) and tools for post-processing the results (diff). For project-specific tools, we should let user install them - make, gcc, cscope, autotools, etc.

The cscope does not make sense if build-kernel is not possible to make work because of llvmPackages.clangNoLibcxx.

So, IIUC, having llvmPackages.clangNoLibcxx will install clang which will not be usable to build kernel sources b/c it will fail to find libelf of openssl libraries? I'd be curious to see the produced errors, maybe we could figure that out.

I am not sure if it is possible to add individual binary files to PATH, but I can look into it.

I'm not sure I understand the purpose of this.

viktormalik avatar May 17 '24 06:05 viktormalik

So, IIUC, having llvmPackages.clangNoLibcxx will install clang which will not be usable to build kernel sources b/c it will fail to find libelf of openssl libraries? I'd be curious to see the produced errors, maybe we could figure that out.

This

wrapProgram $out/bin/diffkemp --prefix PATH : ${lib.makeBinPath [
  llvmPackages.clangNoLibcxx
  ...
]}

adds the path containing clang installed by nix to the PATH when running result/bin/diffkemp.

I inspect more deeply the source of the problem -- the result/bin/diffkemp build-kernel is unable to compile file to LLVM IR because there is an error when the build-kernel command runs make V=1 --just-print <object.o> .... The make runs something like gcc -lelf ... (to check that libelf-dev is installed) which results in error:

/nix/store/zkjq96ik8cbv6ijh1lylnkk2bni9qvas-binutils-2.40/bin/ld: /usr/libexec/gcc/x86_64-redhat-linux/14/liblto_plugin.so: error loading plugin: /nix/store/46m4xx889wlhsdj72j38fnlyyvvvvbyb-glibc-2.37-8/lib/libc.so.6: version `GLIBC_2.38' not found (required by /usr/libexec/gcc/x86_64-redhat-linux/14/liblto_plugin.so)
collect2: error: ld returned 1 exit status

So IIUC there is a problem because it runs ld which is added to the path with the llvmPackages.clangNoLibcxx which uses incompatible glibc version.

Adding the dependencies to the end of PATH (using --suffix instead of --prefix) looks like solves the problem (the local ld is run) but I am not sure if it is a good solution -- if there would not be a problem (I did not yet test how it would behave) if a user had locally installed a different version of clang and llvm than the simpLL was build with because in that case the local clang and llvm would be probably used instead of the nix installed ones...

PLukas2018 avatar May 20 '24 12:05 PLukas2018

The solution right now is to use the Nix environment (using nix develop) or if you want to use result/bin/diffkemp (created by nix build) you have to install necessary dependencies (clang, llvm, ...) to your local machine.

PLukas2018 avatar May 21 '24 11:05 PLukas2018