Help with pkg_check_modules

I am trying to use pkg_check_modules to locate the sndfile library module on Linux. The library has an entry in the pkg-config database and the log shows that the sndfile module has been found.

Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
 Checking for module 'sndfile'
   Found sndfile, version 1.0.31

However the sndfile_FOUND property is not set. The cache does contain some sndfile related entries.

pkgcfg_lib_REQUIRED_sndfile:FILEPATH=/usr/lib/x86_64-linux-gnu/libsndfile.so
REQUIRED_LDFLAGS:INTERNAL=-L/usr/lib/x86_64-linux-gnu;-lsndfile
REQUIRED_LIBRARIES:INTERNAL=sndfile
REQUIRED_MODULE_NAME:INTERNAL=sndfile
REQUIRED_STATIC_LDFLAGS:INTERNAL=-L/usr/lib/x86_64-linux-gnu;-lsndfile;-lFLAC;-lm;-lvorbisenc;-lvorbis;-lm;-logg;-lopus;-lm
REQUIRED_STATIC_LIBRARIES:INTERNAL=sndfile;FLAC;m;vorbisenc;vorbis;m;ogg;opus;m
REQUIRED_sndfile_INCLUDEDIR:INTERNAL=
REQUIRED_sndfile_LIBDIR:INTERNAL=
REQUIRED_sndfile_PREFIX:INTERNAL=
REQUIRED_sndfile_VERSION:INTERNAL=
__pkg_config_arguments_REQUIRED:INTERNAL=sndfile
//ADVANCED property for variable: pkgcfg_lib_REQUIRED_sndfile
pkgcfg_lib_REQUIRED_sndfile-ADVANCED:INTERNAL=1

I have made a minimal test script.

cmake_minimum_required(VERSION 3.1)
project(cmt)
find_package(PkgConfig REQUIRED)

pkg_check_modules(REQUIRED IMPORTED_TARGET sndfile)
#pkg_check_modules(REQUIRED sndfile)
message(STATUS "sndfile_FOUND ${sndfile_FOUND}")
message(STATUS "sndfile_LIBRARIES ${sndfile_LIBRARIES}")
message(STATUS "sndfile_LINK_LIBRARIES ${sndfile_LINK_LIBRARIES}")
message(STATUS "sndfile_LIBRARY_DIRS ${sndfile_LIBRARY_DIRS}")
message(STATUS "sndfile_LDFLAGS ${sndfile_LDFLAGS}")
message(STATUS "sndfile_LDFLAGS_OTHER ${sndfile_LDFLAGS_OTHER}")
message(STATUS "sndfile_INCLUDE_DIRS ${sndfile_INCLUDE_DIRS}")
message(STATUS "sndfile_CFLAGS ${sndfile_CFLAGS}")
message(STATUS "sndfile_CFLAGS_OTHER ${sndfile_CFLAGS_OTHER}")

What am I doing wrong?
It has been a number of years since I last used CMake. All help gratefully received.

Why using PkgConfig if a cmake export package exists?

bash-5.2$ tree /usr/local/Cellar/libsndfile/1.2.2/lib/cmake/SndFile/
/usr/local/Cellar/libsndfile/1.2.2/lib/cmake/SndFile/
|-- SndFileConfig.cmake
|-- SndFileConfigVersion.cmake
|-- SndFileTargets-release.cmake
`-- SndFileTargets.cmake

1 directory, 4 files
bash-5.2$ 

Dit you read the manual page pkg_check_modules?

find_package(SndFile 1.2 REQUIRED)
if(SndFile_FOUND)
  find_package(PkgConfig REQUIRED)
  pkg_check_modules(sndfile REQUIRED IMPORTED_TARGET "sndfile>=1.2")
  message(STATUS "sndfile_FOUND ${sndfile_FOUND}")
endif()

Both work on my host.

The version of sndfile on ubuntu is from the deb package libsndfile1.
The package does not include any of the cmake files.

It also has a huge number of reverse dependencies, so it is difficult to replace.

This looks like a real catch 22.

Yes, I have read (TFM) :slight_smile:

I am out of my depth here. I have never used the output of a cmake export command. My last use of cmake was version 2.

The sndfile1 package on ubuntu does not install a cmake find script or an export file.

Any ideas on where I go from here?

should work, or not?

Quotes make no differrence :frowning:

Am I correct in assuming that I have go to the original libsndfile source and do something with CMake build files in there to create the export file?

From what I know about pkg-config and CMake, in the case of absent CMake configs, one should be able to find the package with pkg_check_modules(), which is what you did (although with a bit different syntax, as it seems?). So I am not sure why sndfile_FOUND ends up not being set, especially that all the other variables seem to be set.

Moreover, you should get an error if pkg_check_modules() doesn’t find the package, as you’ve provided REQUIRED argument, but you don’t get an error, do you?

Are there any other *_FOUND variables set after your project configuration is done? Maybe it sets some other variable for some reason? And also if you are not using the latest CMake version, I would try the latest one, just for the sake of experiment.

I have go to the original libsndfile source and do something with CMake build files

That would be my recommendation, but that’s because I’m used to CMake configs and I have never used pkg-config. So yes, if those CMake configs aren’t provided in the package that you get, then the only(?) way to get them would be for you to build that package yourself from sources (and probably patch its project to add a proper installation procedure, which would create those configs). Or you can probably just write your own Findsndfile.cmake module. Here’s actually one example, which seemingly uses pkg_check_modules() underneath (with some strange _pc_SNDFILE variable?).

However, again, like I said, my understanding is that pkg_check_modules() should be able to do the job of discovering the package, so you should be able to rely on that one instead of CMake configs. Just need to find out why it is failing in this particular case.

Just tried the Findsndfile.cmake you found.

It produced the following output

cmake-3.25/Modules/FindPackageHandleStandardArgs.cmak
e:438 (message):

The package name passed to
find_package_handle_standard_args (Sndfile)
does not match the name of the calling package (sndfile).
This can lead to
problems in calling code that expects find_package result variables
(e.g., _FOUND) to follow a certain pattern.
Call Stack (most recent call first):
/usr/share/cmake-3.25/Modules/Findsndfile.cmake:33
(FIND_PACKAGE_HANDLE_STANDARD_ARGS)
CMakeLists.txt:5 (find_package)
This warning is for project developers. Use -Wno-dev to suppress it.
Configuring done

The following variable are set in CMakeCache.txt, same as before.

SNDFILE_LIBRARIES:FILEPATH=/usr/lib/x86_64-linux-gnu/libsndfile.sopkgcfg_lib__pc_SNDFILE_sndfile:FILEPATH=/usr/lib/x86_64-linux-gnu/libsndfile.so

FIND_PACKAGE_MESSAGE_DETAILS_Sndfile:INTERNAL=[/usr/include][/usr/lib/x86_64-linux-gnu/libsndfile.so][v()]

__pkg_config_arguments__pc_SNDFILE:INTERNAL=sndfile
_pc_SNDFILE_LDFLAGS:INTERNAL=-L/usr/lib/x86_64-linux-gnu;-lsndfil _pc_SNDFILE_LIBRARIES:INTERNAL=sndfile

_pc_SNDFILE_MODULE_NAME:INTERNAL=sndfile

_pc_SNDFILE_STATIC_LDFLAGS:INTERNAL=-L/usr/lib/x86_64-linux-gnu;- sndfile;-lFLAC;-lm;-lvorbisenc;-lvorbis;-lm;-logg;-lopus;-lm
_pc_SNDFILE_STATIC_LIBRARIES:INTERNAL=sndfile;FLAC;m;vorbisenc;vorbis;m;ogg;opus;m

_pc_SNDFILE_sndfile_INCLUDEDIR:INTERNAL=

_pc_SNDFILE_sndfile_LIBDIR:INTERNAL=

_pc_SNDFILE_sndfile_PREFIX:INTERNAL=

_pc_SNDFILE_sndfile_VERSION:INTERNAL=
//ADVANCED property for variable: pkgcfg_lib__pc_SNDFILE_sndfile
pkgcfg_lib__pc_SNDFILE_sndfile-ADVANCED:INTERNAL=1

I do not know if the warning is significant. I am now wondering if this is something to do the debian/ubuntu multiarch library paths.

I linked that file just as an example of how you could make your own module. I didn’t really expect that particular one to actually work :slight_smile:
But the warning you got might be still useful, so perhaps you could try different variants of the package name casing with your original project file too.

Anyway, so there are no *_FOUND variables set after the project is configured? Perhaps you can try to check them explicitly, like so:

message(STATUS "sndfile_FOUND ${sndfile_FOUND}")
message(STATUS "SNDFILE_FOUND ${SNDFILE_FOUND}")
message(STATUS "Sndfile_FOUND ${Sndfile_FOUND}")
message(STATUS "SndFile_FOUND ${SndFile_FOUND}")
# etc

And you haven’t confirmed that there was no error on your pkg_check_modules() with REQUIRED.

You got it in one.

As expected, stupid mistake on my part.

pkg_check_modules(sndfile REQUIRED IMPORTED_TARGET sndfile)

I know I started with off with sndfile as the first parameter and libsndfile as the last one. But at somehow lost it along the way.

Doh