find_package only works with -DCMAKE_PREFIX_PATH with default install directory

Hi!
I have a library, say A, which depends on B. A uses find_dependency in its AConfig.cmake and B is downloaded via FetchContent. A is, before being built manually with cmake, installed in some directory C:/Program files (x86)/A. It contains:

# C:/Program files (x86)/
A/
  include/
  lib/
    B.lib
    Bd.lib
    cmake/
      A/
        AConfig.cmake
        AConfigVersion.cmake
        ATargets.cmake
      B/
        B-config.cmake
        B-config-version.cmake
        B-targets-cmake
        # debug and release cmake files

In another project, say C, I want to use A. I’m doing this in the following manner:

# boilerplate ...
find_package(A CONFIG REQUIRED)
target_link_libraries(my-target A::A)

But I’m getting the error it cant find the dependency of A (B in this case). It says I have to set B_dir (or CMAKE_PREFIX_PATH), but this “feels” weird, because the dependency B is in the same installation directory as A. What can I do to solve this without using B_dir, if this is even possible? Related note: AConfig.cmake looks as follows:

include(CMakeFindDependencyMacro)
find_dependency(B)

include("${CMAKE_CURRENT_LIST_DIR}/ATargets.cmake")

Can you expand on how you’ve arranged for B to be downloaded using FetchContent, specifically what details were in its FetchContent_Declare() call? In order for find_dependency(B) to be redirected to the B that you obtained with FetchContent, you need to use the appropriate options in FetchContent_Declare().

The FetchContent_Declare isn’t too exciting I think. Also, I think it is handy to know that the code did work on my Linux (Ubuntu) laptop. Anyway, the following code is used:

FetchContent_Declare(B
	URL https://github.com/Blib/B/archive/refs/tags/9.1.0.tar.gz 
	UPDATE_DISCONNECTED YES 
	URL_MD5 21fac48cae8f3b4a5783ae06b443973a
	DOWNLOAD_EXTRACT_TIMESTAMP TRUE
)
FetchContent_MakeAvailable(B)
# ...
target_link_libraries(A INTERFACE B::B)

Using

#...
find_dependency(B HINTS "${CMAKE_CURRENT_LIST_DIR}/../B/"

Also solves the problem, but again, I don’t think this is meant to be.

That FetchContent_Declare() call won’t set up the redirection of find_package(B) or find_dependency(B) calls. You would have to add either OVERRIDE_FIND_PACKAGE or FIND_PACKAGE_ARGS to the FetchContent_Declare() call to trigger that behavior. Please take a look at the FetchContent docs for what those options do and how to use them appropriately.

That seems dubious. It suggests your Linux case was picking up a different B from somewhere else.

So adding:

FetchContent_Declare(B
    URL https://github.com/Blib/B/archive/refs/tags/9.1.0.tar.gz 
    UPDATE_DISCONNECTED YES 
    URL_MD5 21fac48cae8f3b4a5783ae06b443973a
    DOWNLOAD_EXTRACT_TIMESTAMP TRUE
    OVERRIDE_FIND_PACKAGE # <----
)

Would be sufficient? (if so, this unfortunately does not work) If not, then I am not sure I understand the documentation, or maybe my question was formulated poorly. I’d also like to point out again that A is an installed library in C:/Program Files (x86)/A, and C is somewhere located in C:/Users/my-name/Documents/C.

Taking a step back, I wouldn’t recommend using FetchContent calls embedded in A’s AConfig.cmake to provide B unless that’s the only way B can be obtained (i.e. B does not provide its own BConfig.cmake). Even then, I’d only typically consider that for a company environment where things are fairly controlled, not for a general open source project where people may want to use it in all sorts of different ways. I don’t know which situation you are in.

I don’t know that I can help too much without seeing the whole picture with more details. I won’t be around for the next few weeks though, so you may need others to help you out.

That is rather unfortunate since the discourse what sort of my “last resort”. However, the problem is not that important and it can wait a few weeks because, and this is a nice bridge to what you asked earlier:

Actually, it is a hobby open-source project so maybe it is better to see the whole picture. The CMakeLists can be found here: cpp-lazy/CMakeLists.txt at master · MarcDirven/cpp-lazy · GitHub.

Basically, I want people to give the freedom to do one of the following:

  1. Use my project in their project using FetchContent, which is already possible.
  2. Use my project in theirs, using find_package(cpp-lazy CONFIG REQUIRED) without -DCMAKE_PREFIX_PATH or -Dfmt_DIR after they’ve (built cpp-lazy from source and) installed it. But this gives the error describe above. It can’t find the fmt dir, which is a dependency of cpp-lazy. Ofcourse, this only should be possible if it is installed in a default installation directory; i.e. C:\Program Files\cpp-lazy or some Linux equivalent.