esa / pagmo2

A C++ platform to perform parallel computations of optimisation tasks (global and local) via the asynchronous generalized island model.
https://esa.github.io/pagmo2/
GNU General Public License v3.0
823 stars 161 forks source link

[BUG] Installs cmake scripts with missing NLOPT::header and IPOPT::header targets #445

Closed yurivict closed 4 years ago

yurivict commented 4 years ago

Installed cmake scripts:

$ grep NLOPT::header `pkg info -l pagmo2`
grep: pagmo2-2.15.0.95:: No such file or directory
/usr/local/lib/cmake/pagmo/FindNLOPT.cmake:    if(NLOPT_FOUND AND NOT TARGET NLOPT::header)
/usr/local/lib/cmake/pagmo/FindNLOPT.cmake:        message(STATUS "Creating the 'NLOPT::header' imported target.")
/usr/local/lib/cmake/pagmo/FindNLOPT.cmake:        add_library(NLOPT::header INTERFACE IMPORTED)
/usr/local/lib/cmake/pagmo/FindNLOPT.cmake:        set_target_properties(NLOPT::header PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${NLOPT_INCLUDE_DIR}")
/usr/local/lib/cmake/pagmo/pagmo_export.cmake:  INTERFACE_LINK_LIBRARIES "Threads::Threads;Boost::boost;Boost::serialization;Eigen3::eigen3;NLOPT::header;IPOPT::header"

only contain the definition of NLOPT::header in your private FindNLOPT.cmake that isn't called by dependent packages, yet you export this target to dependent packages through pagmo_export.cmake.

Same with IPOPT::header.

This breaks DART: https://github.com/dartsim/dart/issues/1473

bluescarni commented 4 years ago

Thanks for the report!

I am a bit confused, because invoking find_package(pagmo) should invoke the FindNLOPT.cmake script, which in turn defines the NLOPT::header target. For instance, when we compile pygmo (which invokes find_package(pagmo)), we don't have any issues.

Could the problem be some naming collisions here:

https://github.com/dartsim/dart/blob/e480e2f06bd8c0dbd0be6862b7e5b4cb01df6cdf/cmake/DARTFindpagmo.cmake#L9

Here find_package(pagmo) will define some NLOPT-related targets/variables, but then DART's own machinery for detecting NLOPT is also invoked. Perhaps they are clashing?

yurivict commented 4 years ago

I am a bit confused, because invoking find_package(pagmo) should invoke the FindNLOPT.cmake script

I think this might not happen when the dependent project has its own FindNLOPT.cmake? This is because they would both define variables with the same names.

bluescarni commented 4 years ago

I think this might not happen when the dependent project has its own FindNLOPT.cmake? This is because they would both define variables with the same names.

Ahh right, probably the FindNLOPT.cmake from Dart takes the precedence over pagmo's own FindNLOPT.cmake due to the way the CMake moduie path is set up.

In other projects I have renamed the FindFoo.cmake files to FindBarFoo.cmake, where Bar is the name of the project. This way further namespacing is introduced which helps avoiding clashes if Bar is a dependency in a project that also needs Foo.

I'll make sure to implement the same approach for pagmo 2.16, which should solve this issue I think.

bluescarni commented 4 years ago

There is now a PR up at #451 in which:

@Bidski @jslee02 perhaps libdart/dartsim should also start using the CMake targets provided by the NLopt installation?

bluescarni commented 4 years ago

@yurivict I will go ahead and close this for the time being, please re-open or open a new report in case of issues with pagmo 2.16.

acxz commented 3 years ago

@bluescarni still having trouble with this issue with pagmo 2.16, here is my output when installing dartsim:

-- Found Boost: /usr/lib64/cmake/Boost-1.72.0/BoostConfig.cmake (found suitable version "1.72.0", minimum required is "1.60.0") found components: serialization 
-- Detected Boost version: 1.72.0
-- Boost include dirs: /usr/include
-- Requested IPOPT components: header
CMake Error at /usr/lib64/cmake/pagmo/Findpagmo_IPOPT.cmake:9 (message):
  'header' is not a valid component for IPOPT.
Call Stack (most recent call first):
  /usr/lib64/cmake/pagmo/pagmo-config.cmake:13 (find_package)
  cmake/DARTFindpagmo.cmake:9 (find_package)
  cmake/DARTMacros.cmake:81 (include)
  dart/optimizer/pagmo/CMakeLists.txt:2 (dart_find_package)

-- Configuring incomplete, errors occurred!
See also "/home/acxz/.cache/yay/libdart/src/dart-6.9.4/build/CMakeFiles/CMakeOutput.log".
bluescarni commented 3 years ago

@acxz thanks for the report, this looks puzzling.

Can you please post the content of /usr/lib64/cmake/pagmo/Findpagmo_IPOPT.cmake and /usr/lib64/cmake/pagmo/pagmo-config.cmake?

acxz commented 3 years ago
`cat /usr/lib64/cmake/pagmo/Findpagmo_IPOPT.cmake`: ``` include(FindPackageHandleStandardArgs) message(STATUS "Requested IPOPT components: ${pagmo_IPOPT_FIND_COMPONENTS}") # Check the components that were passed to find_package(). set(_pagmo_IPOPT_ALLOWED_COMPONENTS header libipopt) foreach(_pagmo_IPOPT_CUR_COMPONENT ${pagmo_IPOPT_FIND_COMPONENTS}) if(NOT ${_pagmo_IPOPT_CUR_COMPONENT} IN_LIST _pagmo_IPOPT_ALLOWED_COMPONENTS) message(FATAL_ERROR "'${_pagmo_IPOPT_CUR_COMPONENT}' is not a valid component for IPOPT.") endif() endforeach() unset(_pagmo_IPOPT_ALLOWED_COMPONENTS) # Setup the list of arguments to be passed to # find_package_handle_standard_args(). set(_pagmo_IPOPT_FPHSA_ARGS) if ("header" IN_LIST pagmo_IPOPT_FIND_COMPONENTS) # The header component was requested. # The associated variable is PAGMO_IPOPT_INCLUDE_DIR. list(APPEND _pagmo_IPOPT_FPHSA_ARGS PAGMO_IPOPT_INCLUDE_DIR) find_path(PAGMO_IPOPT_INCLUDE_DIR NAMES IpIpoptNLP.hpp PATH_SUFFIXES coin coin-or) endif() if ("libipopt" IN_LIST pagmo_IPOPT_FIND_COMPONENTS) # The libipopt component was requested. # The associated variable is PAGMO_IPOPT_LIBRARY. list(APPEND _pagmo_IPOPT_FPHSA_ARGS PAGMO_IPOPT_LIBRARY) find_library(PAGMO_IPOPT_LIBRARY NAMES ipopt) endif() # Run the standard find_package() machinery. find_package_handle_standard_args(pagmo_IPOPT DEFAULT_MSG ${_pagmo_IPOPT_FPHSA_ARGS}) unset(_pagmo_IPOPT_FPHSA_ARGS) if("header" IN_LIST pagmo_IPOPT_FIND_COMPONENTS) mark_as_advanced(PAGMO_IPOPT_INCLUDE_DIR) if(pagmo_IPOPT_FOUND AND NOT TARGET pagmo::IPOPT::header) message(STATUS "Creating the 'pagmo::IPOPT::header' imported target.") add_library(pagmo::IPOPT::header INTERFACE IMPORTED) message(STATUS "Path to the ipopt headers: ${PAGMO_IPOPT_INCLUDE_DIR}") set_target_properties(pagmo::IPOPT::header PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${PAGMO_IPOPT_INCLUDE_DIR}") endif() endif() if ("libipopt" IN_LIST pagmo_IPOPT_FIND_COMPONENTS) mark_as_advanced(PAGMO_IPOPT_LIBRARY) if(pagmo_IPOPT_FOUND AND NOT TARGET pagmo::IPOPT::libipopt) message(STATUS "Creating the 'pagmo::IPOPT::libipopt' imported target.") # Otherwise, we proceed as usual. message(STATUS "Path to libipopt: ${PAGMO_IPOPT_LIBRARY}") add_library(pagmo::IPOPT::libipopt UNKNOWN IMPORTED) set_target_properties(pagmo::IPOPT::libipopt PROPERTIES IMPORTED_LOCATION "${PAGMO_IPOPT_LIBRARY}") endif() endif() ```
`cat /usr/lib64/cmake/pagmo/pagmo-config.cmake`: ``` # Get current dir. get_filename_component(_PAGMO_CONFIG_SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) # Find the deps. Alter the cmake module path. set(_PAGMO_CONFIG_OLD_MODULE_PATH "${CMAKE_MODULE_PATH}") list(APPEND CMAKE_MODULE_PATH "${_PAGMO_CONFIG_SELF_DIR}") set(THREADS_PREFER_PTHREAD_FLAG YES) find_package(Threads REQUIRED) unset(THREADS_PREFER_PTHREAD_FLAG) include(PagmoFindBoost) find_package(Eigen3 3.3 REQUIRED NO_MODULE) find_package(NLopt 2.6 REQUIRED NO_MODULE) find_package(pagmo_IPOPT REQUIRED COMPONENTS header) # Restore original module path. set(CMAKE_MODULE_PATH "${_PAGMO_CONFIG_OLD_MODULE_PATH}") unset(_PAGMO_CONFIG_OLD_MODULE_PATH) include(${_PAGMO_CONFIG_SELF_DIR}/pagmo_export.cmake) # Clean up. unset(_PAGMO_CONFIG_SELF_DIR) ```
bluescarni commented 3 years ago

@acxz

Can you try to change, in Findpagmo_IPOPT.cmake,

foreach(_pagmo_IPOPT_CUR_COMPONENT ${pagmo_IPOPT_FIND_COMPONENTS})
  if(NOT ${_pagmo_IPOPT_CUR_COMPONENT} IN_LIST _pagmo_IPOPT_ALLOWED_COMPONENTS)
      message(FATAL_ERROR "'${_pagmo_IPOPT_CUR_COMPONENT}' is not a valid component for IPOPT.")
  endif()
endforeach()

to

foreach(_pagmo_IPOPT_CUR_COMPONENT ${pagmo_IPOPT_FIND_COMPONENTS})
  message(STATUS "DEBUG cur component: ${_pagmo_IPOPT_CUR_COMPONENT}")
  message(STATUS "DEBUG component list: ${_pagmo_IPOPT_ALLOWED_COMPONENTS}")
  if(NOT ${_pagmo_IPOPT_CUR_COMPONENT} IN_LIST _pagmo_IPOPT_ALLOWED_COMPONENTS)
      message(FATAL_ERROR "'${_pagmo_IPOPT_CUR_COMPONENT}' is not a valid component for IPOPT.")
  endif()
endforeach()

and report the output?

acxz commented 3 years ago

Sure:

-- Requested IPOPT components: header
-- DEBUG cur component: header
-- DEBUG component list: header;libipopt
CMake Error at /usr/lib64/cmake/pagmo/Findpagmo_IPOPT.cmake:11 (message):
  'header' is not a valid component for IPOPT.
Call Stack (most recent call first):
  /usr/lib64/cmake/pagmo/pagmo-config.cmake:13 (find_package)
  cmake/DARTFindpagmo.cmake:9 (find_package)
  cmake/DARTMacros.cmake:81 (include)
  dart/optimizer/pagmo/CMakeLists.txt:2 (dart_find_package)
Bidski commented 3 years ago

@bluescarni Changing

foreach(_pagmo_IPOPT_CUR_COMPONENT ${pagmo_IPOPT_FIND_COMPONENTS})
  if(NOT ${_pagmo_IPOPT_CUR_COMPONENT} IN_LIST _pagmo_IPOPT_ALLOWED_COMPONENTS)
      message(FATAL_ERROR "'${_pagmo_IPOPT_CUR_COMPONENT}' is not a valid component for IPOPT.")
  endif()
endforeach()

to

foreach(_pagmo_IPOPT_CUR_COMPONENT ${pagmo_IPOPT_FIND_COMPONENTS})
  if(NOT "${_pagmo_IPOPT_CUR_COMPONENT}" IN_LIST _pagmo_IPOPT_ALLOWED_COMPONENTS)
      message(FATAL_ERROR "'${_pagmo_IPOPT_CUR_COMPONENT}' is not a valid component for IPOPT.")
  endif()
endforeach()

seems to resolve this error

acxz commented 3 years ago

@Bidski nice find do you want to make a PR for this?

bluescarni commented 3 years ago

@Bidski thanks for the PR, I just merged it.