jbeder / yaml-cpp

A YAML parser and emitter in C++
MIT License
4.91k stars 1.78k forks source link

add_library cannot create ALIAS target "yaml-cpp::yaml-cpp" because target "yaml-cpp" is imported but not globally visible. #1241

Closed tianshilande closed 7 months ago

tianshilande commented 8 months ago

add_ompl_demo(demo_SpaceTimePlanning SpaceTimePlanning.cpp)

find_package(yaml-cpp CONFIG)
set_package_properties(yaml-cpp PROPERTIES
    URL "https://github.com/jbeder/yaml-cpp"
    PURPOSE "Used for parsing input data for the PlanarManipulator demo.")
if (yaml-cpp_FOUND)
    # yaml-cpp might not come with alias or namespaced target names, so add it here.
    # https://github.com/jbeder/yaml-cpp/issues/1025
    # https://github.com/jbeder/yaml-cpp/pull/1196
    if(NOT TARGET yaml-cpp::yaml-cpp AND TARGET yaml-cpp)
        add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
    endif()

    add_ompl_demo(demo_PlanarManipulator
        PlanarManipulator/PlanarManipulatorDemo.cpp
        PlanarManipulator/PlanarManipulator.cpp
        PlanarManipulator/PolyWorld.cpp
    )

add_ompl_demo(demo_SpaceTimePlanning SpaceTimePlanning.cpp)

find_package(yaml-cpp CONFIG)
set_package_properties(yaml-cpp PROPERTIES
    URL "https://github.com/jbeder/yaml-cpp"
    PURPOSE "Used for parsing input data for the PlanarManipulator demo.")
if (yaml-cpp_FOUND)
    # yaml-cpp might not come with alias or namespaced target names, so add it here.
    # https://github.com/jbeder/yaml-cpp/issues/1025
    # https://github.com/jbeder/yaml-cpp/pull/1196
    if(NOT TARGET yaml-cpp::yaml-cpp AND TARGET yaml-cpp)
        add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp)
    endif()

    add_ompl_demo(demo_PlanarManipulator
        PlanarManipulator/PlanarManipulatorDemo.cpp
        PlanarManipulator/PlanarManipulator.cpp
        PlanarManipulator/PolyWorld.cpp
    )

When compiling to this point, an error occurs: if (NOT TARGET yaml-cpp::yaml-cpp AND TARGET yaml-cpp) add_library(yaml-cpp::yaml-cpp ALIAS yaml-cpp) endif()

Levi-Armstrong commented 8 months ago

This is also an issue for me as it has broken all of my repositories CI builds.

jbeder commented 7 months ago

What's the error? (And how should we fix it?)

Levi-Armstrong commented 7 months ago

Error:

2023-11-05T05:51:54.6932528Z CMake Error at D:/a/tesseract/tesseract/vcpkg/installed/x64-windows-release/share/yaml-cpp/yaml-cpp-config.cmake:46 (add_library):
2023-11-05T05:51:54.6934199Z   add_library cannot create imported target "yaml-cpp" because another target
2023-11-05T05:51:54.6935049Z   with the same name already exists.
2023-11-05T05:51:54.6935666Z Call Stack (most recent call first):
2023-11-05T05:51:54.6936253Z   CMakeLists.txt:17 (find_package)

I think the issues has to do with what is going on in the yaml-cpp-config.cmake.in file.

https://github.com/jbeder/yaml-cpp/blob/db03655d58c66f31952c772718d0394eac2e5481/yaml-cpp-config.cmake.in#L22-L28

I also do not think these lines should be needed, because the target yaml-cpp::yaml-cpp should be create by the yam-cpp-targets.cmake file.

https://github.com/jbeder/yaml-cpp/blob/db03655d58c66f31952c772718d0394eac2e5481/CMakeLists.txt#L84C13-L84C31

https://github.com/jbeder/yaml-cpp/blob/db03655d58c66f31952c772718d0394eac2e5481/CMakeLists.txt#L152C5-L152C19

https://github.com/jbeder/yaml-cpp/blob/db03655d58c66f31952c772718d0394eac2e5481/CMakeLists.txt#L158

Levi-Armstrong commented 7 months ago

I think you can update to the following to solve the issue.

if(NOT TARGET yaml-cpp)
    add_library(yaml-cpp INTERFACE IMPORTED) 
    target_link_libraries(yaml-cpp INTERFACE yaml-cpp::yaml-cpp) 
endif()

if(CMAKE_VERSION VERSION_GREATER_EQUAL 3.17) 
   set_target_properties(yaml-cpp PROPERTIES  
     DEPRECATION "The target yaml-cpp is deprecated and will be removed in version 0.10.0. Use the yaml-cpp::yaml-cpp target instead." 
   ) 
jbeder commented 7 months ago

Thanks. One question, @tianshilande - I see you have https://github.com/jbeder/yaml-cpp/pull/1196 referenced in your code, but that's merged. Are you running on HEAD?

Levi-Armstrong commented 7 months ago

Running version 0.8.0

jbeder commented 7 months ago

Ok, please try at HEAD just to be certain it's not already fixed.

Levi-Armstrong commented 7 months ago

Still an issue on HEAD. image

Levi-Armstrong commented 7 months ago

The issue is that the cmake.in file is not protected against multiple inclusions. For example if your package depends on two other package which depend on yaml-cpp this would result the yaml-cpp-config.cmake to try and create the target yaml-cpp twice because it is not protect.

If you take a look at the auto generated yaml-cpp-targets.cmake file line 15 comment is about protecting against this. This same protection needs to be done in you yaml-cpp-config.cmake so it does not try and add the target after it has already been created.

# Generated by CMake

if("${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}" LESS 2.5)
   message(FATAL_ERROR "CMake >= 2.6.0 required")
endif()
cmake_policy(PUSH)
cmake_policy(VERSION 2.6)
#----------------------------------------------------------------
# Generated CMake target import file.
#----------------------------------------------------------------

# Commands may need to know the format version.
set(CMAKE_IMPORT_FILE_VERSION 1)

# Protect against multiple inclusion, which would fail when already imported targets are added once more.
set(_targetsDefined)
set(_targetsNotDefined)
set(_expectedTargets)
foreach(_expectedTarget yaml-cpp::yaml-cpp)
  list(APPEND _expectedTargets ${_expectedTarget})
  if(NOT TARGET ${_expectedTarget})
    list(APPEND _targetsNotDefined ${_expectedTarget})
  endif()
  if(TARGET ${_expectedTarget})
    list(APPEND _targetsDefined ${_expectedTarget})
  endif()
endforeach()
if("${_targetsDefined}" STREQUAL "${_expectedTargets}")
  unset(_targetsDefined)
  unset(_targetsNotDefined)
  unset(_expectedTargets)
  set(CMAKE_IMPORT_FILE_VERSION)
  cmake_policy(POP)
  return()
endif()
if(NOT "${_targetsDefined}" STREQUAL "")
  message(FATAL_ERROR "Some (but not all) targets in this export set were already defined.\nTargets Defined: ${_targetsDefined}\nTargets not yet defined: ${_targetsNotDefined}\n")
endif()
unset(_targetsDefined)
unset(_targetsNotDefined)
unset(_expectedTargets)

# Compute the installation prefix relative to this file.
get_filename_component(_IMPORT_PREFIX "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
get_filename_component(_IMPORT_PREFIX "${_IMPORT_PREFIX}" PATH)
if(_IMPORT_PREFIX STREQUAL "/")
  set(_IMPORT_PREFIX "")
endif()

# Create imported target yaml-cpp::yaml-cpp
add_library(yaml-cpp::yaml-cpp STATIC IMPORTED)

set_target_properties(yaml-cpp::yaml-cpp PROPERTIES
  INTERFACE_COMPILE_DEFINITIONS "\$<\$<NOT:\$<BOOL:OFF>>:YAML_CPP_STATIC_DEFINE>"
  INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include"
)

# Load information for each installed configuration.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
file(GLOB CONFIG_FILES "${_DIR}/yaml-cpp-targets-*.cmake")
foreach(f ${CONFIG_FILES})
  include(${f})
endforeach()

# Cleanup temporary variables.
set(_IMPORT_PREFIX)

# Loop over all imported files and verify that they actually exist
foreach(target ${_IMPORT_CHECK_TARGETS} )
  foreach(file ${_IMPORT_CHECK_FILES_FOR_${target}} )
    if(NOT EXISTS "${file}" )
      message(FATAL_ERROR "The imported target \"${target}\" references the file
   \"${file}\"
but this file does not exist.  Possible reasons include:
* The file was deleted, renamed, or moved to another location.
* An install or uninstall procedure did not complete successfully.
* The installation package was faulty and contained
   \"${CMAKE_CURRENT_LIST_FILE}\"
but not all the files it references.
")
    endif()
  endforeach()
  unset(_IMPORT_CHECK_FILES_FOR_${target})
endforeach()
unset(_IMPORT_CHECK_TARGETS)

# This file does not depend on other imported targets which have
# been exported from the same project but in a separate export set.

# Commands beyond this point should not need to know the version.
set(CMAKE_IMPORT_FILE_VERSION)
cmake_policy(POP)
Levi-Armstrong commented 7 months ago

The PR has been updated and tested locally to resolve the issue protecting against multiple inclusions.

jbeder commented 7 months ago

Fixed by #1242

tianshilande commented 7 months ago

thanks,i have solved it.There is a document in front that does not need to be edited。