Are cmake export targets correct

34 views
Skip to first unread message

Brent Dennis

unread,
Nov 16, 2023, 9:16:40 AM11/16/23
to ArrayFire Users
Hi,

I am currently building Arrayfire 3.9.0 from source.  Also, I am providing many of the required dependencies (fftw, cuda, mkl)  from non standard locations (e.g., /opt/myproj/fftw).   Arrayfire builds fine against its dependencies in non-standard locations.

However, when I try to use Arrayfire in a simple demo with CMake I get linker errors for the libraries it depends upon, see below:

usr/bin/ld: warning: libfftw3.so.3.6.9, needed by /opt/myrproj/arrayfire/lib/libafcpu.so.3.9.0, not found (try using -rpath or -rpath-link)
/usr/bin/ld: warning: libfftw3f.so.3.6.9, needed by /opt/myproj/arrayfire/lib/libafcpu.so.3.9.0, not found (try using -rpath or -rpath-link)
/usr/bin/ld: /opt/myproj/arrayfire/lib/libafcpu.so.3.9.0: undefined reference to `fftwf_execute'

My CMake file has this simple link line:

target_link_libraries( demo PRIVATE ArrayFire::afcpu ).

I can add FFTW to the target_link_libraries() but this introduces a new issue with the fact that CMake wants to link against the versioned library name vs the unversioned name which Arrayfire link against.  Moreover, Arrayfire doesn't encode libfftw.so rpath in it's resulting .so files.

Looking at Arrayfire's CMake code, shouldn't it be using PUBLIC for several of it's target_link_libraries() calls to link in its dependencies.  This would notify an Arrayfire client app about it's dependencies during linking such that the client app doesn't need to know about Arrayfire's internal dependencies, e.g., fftw, cuda. 

Note, this all goes away by updating LD_LIBRARY_PATH or ld.so.conf(.d), but we try to avoid setting system level link options when we can avoid it.

Thanks,
Brent

Umar Arshad

unread,
Nov 29, 2023, 7:32:32 PM11/29/23
to ArrayFire Users
Hi Brent,

The reason you are running into the linking issues is because you are installing fftw in a non-standard location and the linker doesn't know where to look. Even if we made the dependencies public, it will only tell CMake where to look for the library when linking but the loader will not find the libraries. 

You need to figure out where the loader should look for your specific program. As a library you can set the rpath but that may change if you choose to move the binaries to another system. LD_LIBRARY_PATH is most flexible but you have to set it every time. There are tradeoffs for each approach. the easiest approach would be to put all the libs in the same file but that may  not be possible for you.

Umar

Reply all
Reply to author
Forward
0 new messages