Question about yaml

include(FetchContent)

FetchContent_Declare(
  yaml-cpp
  GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
  GIT_TAG <tag_name> # Can be a tag (yaml-cpp-x.x.x), a commit hash, or a branch name (master)
)
FetchContent_MakeAvailable(yaml-cpp)

target_link_libraries(YOUR_LIBRARY PUBLIC yaml-cpp::yaml-cpp) # The library or executable that require yaml-cpp library

Q1. YAML_CPP_INCLUDE_DIR and YAML_CPP_LIBRARIES are “”?

Q2. Why is it unnecessary to use target_include_directories(test ${YAML_CPP_INCLUDE_DIR})?
only use target_link_libraries

Q3. I write a library with opencv and yaml-cpp and set this

# lib cmake
target_link_libraries(YOUR_LIBRARY PRIVATE ${OpenCV_LIBS} yaml-cpp::yaml-cpp)

Now I want to use another program to call YOUR_LIBRARY

# new project cmake
target_link_libraries(test PRIVATE YOUR_LIBRARY::YOUR_LIBRARY)

It show the

# on new project error
'yaml-cpp/yaml.h': No such file or directory

Until I only change yaml-cpp::yaml-cpp from PRIVATE to PUBLIC, it build successly.

# lib cmake
target_link_libraries(YOUR_LIBRARY PRIVATE ${OpenCV_LIBS} 
PUBLIC yaml-cpp::yaml-cpp)

Why does it must be PUBLIC for yaml? But the opencv can PRIVATE.

May be you can ask thoses questions to yaml-cpp author?

Q1. I do not understand the question.
Q2. Because the imported library yaml-cpp::yaml-cpp already convey the information and yo ulink to it.

Q3. Because it is the way it works for PRIVATE linking. See: https://cmake.org/cmake/help/latest/manual/cmake-buildsystem.7.html#target-command-scope

Q1: It seems that this library produces a proper CMake config, so those variables aren’t needed and thus aren’t set, as the library’s target is discovered in CONFIG mode.

Q2 and Q3: Already answered by Eric here.

I would only add that if you, as the maintainer of YOUR_LIBRARY, know for sure that consuming projects will use some of its dependencies, then you might want to use the PUBLIC scope on linking to those dependencies (and also consider adding the corresponding find_dependency() to your library’s CMake config, which in most cases you should do anyway, no matter the linking scope).

Thanks for your help

But I still can not understand the Q3.
I found the key place.

Because YOUR_LIBRARY use the yaml-cpp lib and define the yaml header file on YOUR_LIBRARY.hpp .

When I chane the defination that define the yaml header file on YOUR_LIBRARY.cpp, and It success.

# lib cmake
target_link_libraries(YOUR_LIBRARY PRIVATE ${OpenCV_LIBS} yaml-cpp::yaml-cpp)


# lib .h       build fail
#include <yaml-cpp/yaml.h>


# lib.cpp   build success
#include <yaml-cpp/yaml.h>

When you are linking to a dependency with PRIVATE scope, that dependency’s public headers won’t be “exposed” to other projects, so only YOUR_LIBRARY will “see” them. Since those other projects don’t(?) need to do anything with your lib.cpp, you can include that dependency header there, and the build should go just fine.

But if you include that header in your lib.h, which I assume in turn is included in those other projects, then it is only natural that the build will fail, which is why if you intend to include the depedendency’s public header in your library’s public header (do you actually need to do that?), then you should probably link to that dependency with a PUBLIC scope (or explicitly link to that dependency in those other projects too).

If you’d be interested to know some more, then here is some documentation and here is a much more detailed post from the mailing list. There is also this article, but this one is not part of the official documentation and does not originate from CMake maintainers.