6

I am trying to write a Find Module for a package that I have installed. But I am having trouble understanding the CMake functions.

Here is a snippet of my code.

find_package(PkgConfig)
pkg_check_modules(PC_zcm QUIET zcm)

find_path(zcm_INCLUDE_DIR
        NAMES zcm.h
        PATHS $ENV{PATH}
        )
mark_as_advanced(zcm_FOUND zcm_INCLUDE_DIR)

include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(zcm DEFAULT_MSG
        REQUIRED_VARS zcm_INCLUDE_DIR
        )

find_path() is able to find my zcm_INCLUDE_DIR just fine: /usr/bin/zcm/usr/local/include

But find_package_handle_standard_args() gives -- Could NOT find zcm (missing: REQUIRED_VARS)

My directory tree looks like this:

└── zcm
    ├── eventlog.h
    ├── json
    │   ├── json-forwards.h
    │   └── json.h
    ├── message_tracker.hpp
    ├── tools
    │   ├── IndexerPlugin.hpp
    │   └── TranscoderPlugin.hpp
    ├── transport
    │   └── generic_serial_transport.h
    ├── transport.h
    ├── transport_register.hpp
    ├── transport_registrar.h
    ├── url.h
    ├── util
    │   └── Filter.hpp
    ├── zcm-cpp-impl.hpp
    ├── zcm-cpp.hpp
    ├── zcm.h
    └── zcm_coretypes.h

My understanding is find_package_handle_standard_args() attempts to find the package at the path, which sounds like it would be straightforward as the path is already determined.

As for REQUIRED_VARS the docs just say "Specify the variables which are required for this package." Which doesn't tell much for a noobie like me.

shawn_WWW
  • 71
  • 1
  • 5

1 Answers1

3

Description of find_package_handle_standard_args notes about two signatures of given function, one signature accepts DEFAULT_MSG option and another one accepts REQUIRED_VARS option.

You are trying to mix these signatures, and this is wrong.

Proper usage of the first signature:

# Everything after DEFAULT_MSG is treated as required variable.
find_package_handle_standard_args(zcm DEFAULT_MSG
    zcm_INCLUDE_DIR
    )

Proper usage of the second signature:

# By default, the standard error message is used.
find_package_handle_standard_args(zcm REQUIRED_VARS
    zcm_INCLUDE_DIR
    )
Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • Can you elaborate a bit on what it actually does and what its use case is? My take is it populates the _FOUND variable if the variables are true / ON / 1, but what does it have to do with packages? – glades Nov 17 '22 at 16:31
  • Have you read [documentation](https://cmake.org/cmake/help/latest/module/FindPackageHandleStandardArgs.html) for that function? What is unclear in it? If you want the real-life examples, then you could look into any `Find.cmake` script. E.g. into [FindZLIB.cmake](https://github.com/Kitware/CMake/blob/master/Modules/FindZLIB.cmake). – Tsyvarev Nov 17 '22 at 16:49
  • Yes I did. But what is unclear to me is what this function has to do with find_package. Doc says `This command handles the REQUIRED, QUIET and version-related arguments of find_package()` Does this mean that a find_package() call is executed underneath? What does `handle` mean in regard to the arguments to find_package? The doc appears very nebulous to me as a beginner. – glades Nov 17 '22 at 17:33
  • The first sentence of the [documentation for the module](https://cmake.org/cmake/help/latest/module/FindPackageHandleStandardArgs.html) is "This module provides functions intended to be used in Find Modules...". And there is even the reference for what "Find Module" is: https://cmake.org/cmake/help/latest/manual/cmake-developer.7.html#find-modules. This description could help you to understand the basis. And it even provides the example of Find module, which uses `find_package_handle_standard_args`. – Tsyvarev Nov 17 '22 at 18:04
  • Reading the find_module part helped! But I still have trouble understanding the connection between find_library, find_package and find_package_handle_standard_args. 1) Does find_library just check if a library can be found in the chosen locations and set the var? In this case it is always required to follow up with find_package or find_package_handle_standard_args? 2) What does it mean to handle the 'QUIET' case of find_package? I thought that the FindModule would be responsible to be "quiet" according to the passed vars, not the caller. – glades Nov 18 '22 at 07:22
  • " Does find_library just check if a library can be found in the chosen locations and set the var?" - Yes, it it is written in [documentation](https://cmake.org/cmake/help/latest/command/find_library.html). "In this case it is always required to" - `find_library` doesn't impose any restrictions about using its result. "I thought that the FindModule would be responsible to be "quiet" according to the passed vars, not the caller." - Yes, FindModule is responsible for that, and exactly FindModule calls `find_package_handle_standard_args`. – Tsyvarev Nov 18 '22 at 09:13