'nvlink fatal : Could not open input file' when linking with empty static library

Hi,

nvcc can’t link empty static libraries on linux and returns with error 'nvlink fatal : Could not open input file` :

# docker run -it nvidia/cuda
root@9d500f513721:/# echo "int main(){}" > main.cpp; touch test.a; nvcc main.cpp test.a
nvlink fatal   : Could not open input file 'test.a'

It’s been that way for many versions, but it became especially annoying when libdl was included in the main glibc library (Since version 2.34), leaving an empty libdl.a stub.

On some systems, compiling my code using CMake pulls this empty libdl.a and the compilation ends with an anticlimactic nvlink fatal : Could not open input file '/usr/lib/libdl.a'.
While i get that there is probably some issues to fix on the cmake side to avoid adding useless libraries to the link list, i feel that linking an empty library should not break the compilation.

Have you found any way to fix this?

No, never found a way to successfully link empty libraries with nvcc.

The only solution is to avoid loading empty libraries.

  • Obviously one solution could be to remove the library from de command line : if it’s empty you probably shouldn’t link it in the first place
  • For libdl specifically, you can use nvcc -ldl instead of nvcc /lib/libdl.a and it works.
  • If you have no control over the command line options when you compile, as a workaround you can replace the empty library file with one that you compile yourself containing dummy symbols.

The problem is that I’m using CMake to compile and therefore it adds the libdl.a automatically. What have you done to fix the problem from your CMakeLists.txt?

If you’re linking libdl yourself in you CMakeLists.txt, you can try using target_link_libraries( myexe dl ) without doing a find_library()for libdl, that’s the same as just using -ldlin the command line.

But when libdl is added inside a find_package() there is not much you can do. That’s my main issue with this. Then you need to modify the Findxxx.cmake to change how libdl is linked… Not ideal, not portable unless you distribute your modified Findxxx.cmake . You could ask the maintainers of the Findxxx.cmake to change that for the next release of CMake.

You could also use something else than nvcc as your linker with CMAKE_CXX_LINK_EXECUTABLE : CMake: use a custom linker - Stack Overflow
, but it’s tricky because some targets will add nvcc specific flags to the linker flags

Because i use multiple machines to compile, i use different workarounds while i wait for nvidia to fix the issue:

  1. Use clang as my CUDA compiler when it’s available
  2. Modify my system libdl.a so it’s not empty when i own the machine
  3. As a last resort, i use CMAKE_CXX_LINK_EXECUTABLE to link with g++

I’m not linking libdl because I want @n0n0 - It’s something that cmake does by itself since some version… I don’t know why (see my post in this same category), I tried to put the dl in target_link_libraries( myexe dl ), but it didn’t work. Couple of questions:

  • Is it possible to use clang compiler with CMake?
  • How are you modifying libdl.a?

One possible temporary solution is mentionned here:

In your cmake project build dir, just do the following:

touch empty.c
gcc -fpic -c empty.c
ar rcsv libdl.a empty.o
it create an empty valid lib

Then just rerun cmake configure with flags : -DLIBDL_LIBRARY=$PWD/libdl.a
I believe this problem will be fixed in a future release of cuda toolkit for OS with libc >= 2.34

@carcamovski FYI, as expected, with the lastest cuda 11.7 release, on ubuntu 22.04, everything works fine again.