Reputation: 41
I'm using yaml-cpp library recently. I follow the config file in "yaml-cpp-config.cmake.in" which content is
# - Config file for the yaml-cpp package
# It defines the following variables
# YAML_CPP_INCLUDE_DIR - include directory
# YAML_CPP_LIBRARIES - libraries to link against
# Compute paths
get_filename_component(YAML_CPP_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
set(YAML_CPP_INCLUDE_DIR "@CONFIG_INCLUDE_DIRS@")
# Our library dependencies (contains definitions for IMPORTED targets)
include("${YAML_CPP_CMAKE_DIR}/yaml-cpp-targets.cmake")
# These are IMPORTED targets created by yaml-cpp-targets.cmake
set(YAML_CPP_LIBRARIES "@EXPORT_TARGETS@")
According line 8 and line 14 (or the comment section), I edited my CMakeLists.txt
:
cmake_minimum_required(VERSION 3.5)
project(yaml_test)
find_package(yaml-cpp)
include_directories(${YAML_CPP_INCLUDE_DIRS})
add_executable(yaml_test src/test.cpp)
target_link_libraries(yaml_test ${YAML_CPP_LIBRARIES})
and test.cpp
:
#include <yaml-cpp/yaml.h>
int main()
{
YAML::Node node = YAML::LoadFile("test.yaml");
return 0;
}
and I got
CMakeFiles/yaml_test.dir/src/test.cpp.o: In function `main':
test.cpp:(.text+0xf9): undefined reference to `YAML::LoadFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status
CMakeFiles/yaml_test.dir/build.make:94: recipe for target 'yaml_test' failed
make[2]: *** [yaml_test] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/yaml_test.dir/all' failed
make[1]: *** [CMakeFiles/yaml_test.dir/all] Error 2
Makefile:83: recipe for target 'all' failed
make: *** [all] Error 2
I found a solution from undefined reference to YAML::LoadFile
changed my CMakeLists.txt
to
cmake_minimum_required(VERSION 3.5)
project(yaml_test)
find_package(yaml-cpp)
include_directories(${YAMLCPP_INCLUDE_DIRS})
add_executable(yaml_test src/test.cpp)
target_link_libraries(yaml_test ${YAMLCPP_LIBRARIES})
And I can build my code succesfully.
My question is how can I tell the right include_directories
and target_link_libraries
straight from yaml-cpp package's CMakeLists.txt
or config file?
Upvotes: 3
Views: 3737
Reputation: 155
Instead of installing yaml-cpp
locally and then including and linking it, you can do it directly with cmake as follows.
include(FetchContent)
FetchContent_Declare(yaml-cpp
GIT_REPOSITORY https://github.com/jbeder/yaml-cpp.git
GIT_TAG yaml-cpp-0.7.0) #tag of a release
FetchContent_GetProperties(yaml-cpp)
if(NOT yaml-cpp_POPULATED)
message(STATUS "Fetching yaml-cpp...")
FetchContent_Populate(yaml-cpp)
add_subdirectory(${yaml-cpp_SOURCE_DIR} ${yaml-cpp_BINARY_DIR})
endif()
target_link_libraries(<YOUR_LIBRARY/EXECUTABLE> PUBLIC yaml-cpp::yaml-cpp) # The library or executable that require yaml-cpp library
Answer is from: https://github.com/jbeder/yaml-cpp/pull/1143/files
PS:
Even though this not answer following question
My question is how can I tell the right include_directories and target_link_libraries straight from yaml-cpp package's CMakeLists.txt or config file?
This answers the main question of linking yaml-cpp
with a project.
Upvotes: 0
Reputation: 65938
My question is how can I tell the right "include_directories" and "target_link_libraries" straight from yaml-cpp package's CMakeLists.txt or config file?
Just make sure you look into the config file, which is actually used by CMake.
E.g. yaml-cpp-config.cmake.in
is just a template for future yaml-cpp-config.cmake
, but your system could have other config files for the same package.
CMake stores the exact path to the config file in the <PackageName>_CONFIG
variable so you may print value of this variable if unsure:
...
find_package(yaml-cpp)
message(STATUS "Used config file: ${yaml-cpp_CONFIG}")
When read a config file, aside from the documentation at the top it is useful for check the set
line which assigns a value to the documented variable like *_LIBRARY
or *_LIBRARIES
. If that value is empty, then the "config" file is probably broken and documented variables most likely cannot be used. But you may resort to the using of IMPORTED targets, see below.
Note, that most "config" files provide IMPORTED target(s) for use by other code.
This mechanism is preferred over using variables *_INCLUDE_DIR
and *_LIBRARIES
. If cannot find the documentation about which exact IMPORTED target to use, then see into the value of *_LIBRARIES
variable in the config file: The variable may contain a list of IMPORTED targets, which you could try to use in your code via target_link_libraries
.
For more details look into find_package
documentation.
Upvotes: 2