FindNetCDF.cmake creates an unusable namespaced library
I am using the CMake module for NetCDF in a different project, and I found what may be a small oversight in the CMake section of the NetCDF module provided by VTK.
Colleagues and myself were noticing that with the new release of netCDF, 4.7.3, that the namespaced version of the library, NetCDF::NetCDF, caused linking errors. It took us a moment to realize that while that imported target has the correct library name - netCDF, it doesn't provide any path information. This caused a situation where our build would find the locally compiled netCDF library, by name, but at link time would find an older system library in /usr/lib that didn't have the newer symbols. This happened even when using target_link_directories explicitly. When we hardcode the path to the correct library, all works as expected.
We were able to temporarily work around the issue by using the exported target netCDF_LIB_DIR from the lib/cmake/*config, and altering the target properties on the namespace to be SHARED instead of INTERFACE, and providing an IMPORTED_LOCATION based on the libname, and the netCDF_LIB_DIR above. The code below shows the changes we made (roughly). Is this an appropriate approach? I'm fairly well-versed in CMake, but I feel as if I'm missing something, or that it's not quite working as intended, compared to similarly namespaced targets. It'll work for us, on a single machine, but otherwise it goes against the 'create relocatable package' guidelines from CMake.
Any advice? Is there a way to get the path information using the Module as-is? Thanks in advance.
Old Section of code
# Try to find a CMake-built NetCDF.
find_package(netCDF CONFIG QUIET)
if (netCDF_FOUND)
# Forward the variables in a consistent way.
set(NetCDF_FOUND "${netCDF_FOUND}")
set(NetCDF_INCLUDE_DIRS "${netCDF_INCLUDE_DIR}")
set(NetCDF_LIBRARIES "${netCDF_LIBRARIES}")
set(NetCDF_VERSION "${NetCDFVersion}")
if (NOT TARGET NetCDF::NetCDF)
add_library(NetCDF::NetCDF INTERFACE IMPORTED)
set_target_properties(NetCDF::NetCDF PROPERTIES
INTERFACE_LINK_LIBRARIES "${NetCDF_LIBRARIES}")
endif ()
# Skip the rest of the logic in this file.
return ()
endif ()
New section of code
# Try to find a CMake-built NetCDF.
find_package(netCDF CONFIG QUIET)
if (netCDF_FOUND)
# Forward the variables in a consistent way.
set(NetCDF_FOUND "${netCDF_FOUND}")
set(NetCDF_INCLUDE_DIRS "${netCDF_INCLUDE_DIR}")
set(NetCDF_LIBRARIES "${netCDF_LIBRARIES}")
set(NetCDF_VERSION "${NetCDFVersion}")
set(NetCDF_LIBRARY_DIR "${netCDF_LIB_DIR}") <------------------- New
if (NOT TARGET NetCDF::NetCDF)
add_library(NetCDF::NetCDF SHARED IMPORTED) <------------------- Changed
set_target_properties(NetCDF::NetCDF PROPERTIES <------------------- Changed
IMPORTED_LOCATION "${NetCDF_LIBRARY_DIR}"/lib"${NetCDF_LIBRARIES}".so)
endif ()
# Skip the rest of the logic in this file.
return ()
endif ()