cpm-cmake / CPM.cmake

📦 CMake's missing package manager. A small CMake script for setup-free, cross-platform, reproducible dependency management.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CPM name of the package MUST NOT be exported target name

artiomn opened this issue · comments

NAME # The unique name of the dependency (should be the exported target's name)

There are two problems:

  • Package can export several targets (i.e. lib and lib_static).
  • find_package() will not work for some packages. I.e. for ZeroMQ. If I name the dependency ZeroMQ I will get an error in the Windows build, if I name dependency libzmq, it will be always downloaded, because find_package() doesn't found it.

The find_package command has a NAMES argument, which enables you to specify an alternative search string for CMake to utilize.
CPM provides FIND_PACKAGE_ARGUMENTS, through which you can pass arguments to find_package.

CPMFindPackage(
    NAME libzmq
    ...
    FIND_PACKAGE_ARGUMENTS "NAMES ZeroMQ"
)

I'm not sure if this is properly explained in the docs.


I'm not quite following your first point. This behavior seems typical for most larger dependencies, like Boost. Even for smaller dependencies the name used to declare a dependency often doesn't match the exported target names, regardless of the dependency provider/package manager that is being used.

However, I can see situations where the statement "should be the exported target's name" might mislead someone into thinking they actually have to match. It doesn't really matter what you set as NAME.
Perhaps adhering to whatever find_package expects could be a more advisable approach in general.

FIND_PACKAGE_ARGUMENTS "NAMES ZeroMQ"

Thank you. This is very useful, but not obvious. I probably missed this when I read the documentation.

However, I can see situations where the statement "should be the exported target's name" might mislead someone into thinking they actually have to match. It doesn't really matter what you set as NAME.

Yes. You are right. The problem was with ZeroMQ under Windows+MSVS. Under Linux all works.
But under Windows I wrote this workaround:

if (NOT ZeroMQ_FOUND)
    add_third_party(NAME "libzmq"
                    GITHUB_REPOSITORY "zeromq/libzmq"
                    VERSION "4.3.5"
                    OPTIONS
                        "WITH_DOCS OFF"
                        "BUILD_TESTS OFF"
                        "ENABLE_CPACK OFF")
endif()

Main part of the add_third_party() code:

    if(NOT "${module_name}" STREQUAL NAME)
        cpm_parse_add_package_single_arg("${module_name};${ARGN}" ARGN)
        # The shorthand syntax implies EXCLUDE_FROM_ALL and SYSTEM
        list(GET ARGN 1 _repo_name)
        get_filename_component(_repo_name ${_repo_name} NAME)
        CPMADDPackage(${ARGN}
                      EXCLUDE_FROM_ALL YES
                      SYSTEM YES
                      SOURCE_DIR "${KNP_ROOT_DIR}/third-party/${_repo_name}")
    else()
        list(GET ARGN 0 _m_name)
        CPMADDPackage("${module_name}" ${ARGN}
                      EXCLUDE_FROM_ALL YES
                      SYSTEM YES
                      SOURCE_DIR "${KNP_ROOT_DIR}/third-party/${_m_name}")
    endif()

Perhaps adhering to whatever find_package expects could be a more advisable approach in general.

Yes, it will be more obvious.
And I think you know, but I will mention that some dependency managers like Conan or Hunter use "patches" or "plugins" for specific packages.
This is probably is not very convenient and universal, but it works in specific cases.