Unidata / netcdf-c

Official GitHub repository for netCDF-C libraries and utilities.
BSD 3-Clause "New" or "Revised" License
512 stars 262 forks source link

Linking a program on mingw fails with 'cannot find -loptimized' and 'cannot find -ldebug' #2540

Open DusanJovic-NOAA opened 1 year ago

DusanJovic-NOAA commented 1 year ago

When I try to build a program that uses netcdf library (4.9.0) on Windows (MinGW) I see the following errors:

C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -ldebug: No such file or directory
C:/msys64/mingw64/bin/../lib/gcc/x86_64-w64-mingw32/12.2.0/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -loptimized: No such file or directory
collect2.exe: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

The "missing" libraries ('debug' and 'optimized') are specified in Libs.private in netcdf.pc:

$ cat lib/pkgconfig/netcdf.pc
prefix=C:/develop/install
exec_prefix=C:/develop/install
libdir=C:/develop/install/lib
includedir=C:/develop/install/include
ccompiler=C:/msys64/mingw64/bin/cc.exe

Name: netCDF
Description: NetCDF Client Library for C
URL: https://www.unidata.ucar.edu/netcdf
Version: 4.9.0
Libs: -L${libdir} -lnetcdf
Libs.private: -lhdf5_hl -lhdf5 -lz -ldebug -lzstd -loptimized -lbz2 -lcurl
Cflags: -I${includedir}

which is obviously incorrect, since debug and optimized are not actual libraries. They are just cmake keywords used to indicate whether a (actual) library that follows that keyword is a debug or optimized library and, as such, these two keywords should not be added to netcdf.pc and nc-config.

WardF commented 1 year ago

Interesting, and thank you for letting us know. I'll take a look and try to get that fixed in v4.9.1!

DusanJovic-NOAA commented 1 year ago

Somewhat related to this issue is the following. This is what I see when I run cmake to configure v4.9.0 on mingw:

# cmake ../netcdf-c-4.9.0 -DENABLE_NETCDF_4=OFF
-- Building for: Ninja
-- The C compiler identification is GNU 12.2.0
-- The CXX compiler identification is GNU 12.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: C:/msys64/mingw64/bin/cc.exe - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: C:/msys64/mingw64/bin/c++.exe - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Performing Test LIBTOOL_HAS_NO_UNDEFINED
-- Performing Test LIBTOOL_HAS_NO_UNDEFINED - Success
-- Performing Test CC_HAS_WCONVERSION
-- Performing Test CC_HAS_WCONVERSION - Success
-- Performing Test CC_HAS_SHORTEN_64_32
-- Performing Test CC_HAS_SHORTEN_64_32 - Failed
-- Performing Test CC_HAS_MACRO_PREFIX_MAP
-- Performing Test CC_HAS_MACRO_PREFIX_MAP - Success
-- Found CURL: C:/msys64/mingw64/lib/libcurl.dll.a (found version "7.86.0")
-- Performing Test HAVE_LIBCURL_766
-- Performing Test HAVE_LIBCURL_766 - Success
-- Found ZLIB: C:/msys64/mingw64/lib/libz.dll.a (found version "1.2.13")
-- Found Bz2: headers at C:/msys64/mingw64/include, libraries at C:/msys64/mingw64/lib
--      library is debug;C:/msys64/mingw64/lib/libbz2.dll.a;optimized;C:/msys64/mingw64/lib/libbz2.dll.a
-- Found Zstd: headers at C:/msys64/mingw64/include, libraries at C:/msys64/mingw64/lib
--      library is debug;C:/msys64/mingw64/lib/libzstd.dll.a;optimized;C:/msys64/mingw64/lib/libzstd.dll.a
>>> Standard Filter: zstd
>>> Standard Filter: bz2
-- Found LibXml2: C:/msys64/mingw64/lib/libxml2.dll.a (found version "2.10.3")
-- Enabling use of fill value when NC_ERANGE
-- Enabling a more relaxed check for NC_EINVALCOORDS

Note how the same library, for example libzstd.dll.a is listed both as debug version and as optimized version. This happens because in cmake/modules/FindZstd.cmake in this block:

  # Find Zstd libraries
  FIND_LIBRARY(Zstd_DEBUG_LIBRARY NAMES zstdd zstd_d libzstdd libzstd_d libzstd
               PATH_SUFFIXES Debug ${CMAKE_LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_ARCHITECTURE}/Debug
               PATHS ${Zstd_LIBRARY_DIRS} NO_DEFAULT_PATH)
  FIND_LIBRARY(Zstd_RELEASE_LIBRARY NAMES zstd libzstd
               PATH_SUFFIXES Release ${CMAKE_LIBRARY_ARCHITECTURE} ${CMAKE_LIBRARY_ARCHITECTURE}/Release
               PATHS ${Zstd_LIBRARY_DIRS} NO_DEFAULT_PATH)

libzstd is listed in both FIND_LIBRARY(Zstd_DEBUG_LIBRARY ... and FIND_LIBRARY(Zstd_RELEASE_LIBRARY ..., and later Zstd_LIBRARIES variable is set by appending effectively the same library file twice. I think libzstd should be listed as a potential library name only when the release version is being searched for and names with d and _d suffix when debug version is searched.

Similar thing happens in other Find<NAME>.cmake modules, like FindBz2.cmake and probably others.