Skip to content

Commit

Permalink
Merge pull request #3069 from traversaro/fix2445
Browse files Browse the repository at this point in the history
Ensure that files generated by yarp_configure_plugins_installation are relocatable
  • Loading branch information
randaz81 authored Jan 17, 2024
2 parents 6e5676b + 16e76d7 commit c59779f
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 12 deletions.
11 changes: 6 additions & 5 deletions cmake/YarpInstallationHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -65,17 +65,18 @@ function(YARP_CONFIGURE_PLUGINS_INSTALLATION _package)
mark_as_advanced(YARP_FORCE_DYNAMIC_PLUGINS)

set(_in_file "${CMAKE_BINARY_DIR}/CMakeFiles/${_package}.ini.in")
set(_build_file "${CMAKE_BINARY_DIR}/${${YCPI_INSTALL_VARS_PREFIX}_PLUGIN_MANIFESTS_INSTALL_DIR}/${_package}.ini")
set(_build_destination "${CMAKE_BINARY_DIR}/${${YCPI_INSTALL_VARS_PREFIX}_PLUGIN_MANIFESTS_INSTALL_DIR}")
set(_build_file "${_build_destination}/${_package}.ini")
set(_install_file "${CMAKE_BINARY_DIR}/CMakeFiles/${_package}_for_install.ini")
set(_destination "${${YCPI_INSTALL_VARS_PREFIX}_PLUGIN_MANIFESTS_INSTALL_DIR}")

unset(_path)
unset(_relative_path)
unset(_extension)
unset(_type)
file(WRITE "${_in_file}"
"###### This file is automatically generated by CMake.
[search ${_package}]
path \"@_path@\"
relative_path \"@_relative_path@\"
extension \"@_extension@\"
type \"@_type@\"
")
Expand All @@ -88,10 +89,10 @@ type \"@_type@\"
set(_type "static")
endif()

set(_path "${CMAKE_BINARY_DIR}/${${YCPI_INSTALL_VARS_PREFIX}_DYNAMIC_PLUGINS_INSTALL_DIR}") # (build tree)
file(RELATIVE_PATH _relative_path "${_build_destination}" "${CMAKE_BINARY_DIR}/${${YCPI_INSTALL_VARS_PREFIX}_DYNAMIC_PLUGINS_INSTALL_DIR}") # (build tree)
configure_file("${_in_file}" "${_build_file}" @ONLY)

set(_path "${CMAKE_INSTALL_PREFIX}/${${YCPI_INSTALL_VARS_PREFIX}_DYNAMIC_PLUGINS_INSTALL_DIR}") # (install tree)
file(RELATIVE_PATH _relative_path "${CMAKE_INSTALL_PREFIX}/${_destination}" "${CMAKE_INSTALL_PREFIX}/${${YCPI_INSTALL_VARS_PREFIX}_DYNAMIC_PLUGINS_INSTALL_DIR}") # (install tree)
configure_file("${_in_file}" "${_install_file}" @ONLY)
install(FILES "${_install_file}"
RENAME ${_package}.ini
Expand Down
2 changes: 2 additions & 0 deletions doc/release/master.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,5 +25,7 @@ Deprecations and removals
Fixes
-----

* Configuration files installed by the `yarp_configure_plugins_installation` CMake macro are now relocatable (https://github.com/robotology/yarp/issues/2445, ).

New Features
------------
37 changes: 30 additions & 7 deletions src/libYARP_os/src/yarp/os/YarpPlugin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

#include <cstdio>
#include <cstdlib>
#include <filesystem>

using namespace yarp::os;
using namespace yarp::os::impl;
Expand Down Expand Up @@ -90,7 +91,19 @@ bool YarpPluginSettings::open(SharedLibraryFactory& factory)
Bottle paths = selector->getSearchPath();
for (size_t i = 0; i < paths.size(); i++) {
Searchable& options = paths.get(i);
std::string path = options.find("path").asString();
std::string absolute_search_path;
if (options.check("path")) {
// If path is present in the .ini file generated by yarp_configure_plugins_installation,
// we use it directly
absolute_search_path = options.find("path").asString();
} else if (options.check("relative_path")) {
// If instead relative_path is present, we use it to build absolute_search_path
// using relative_path and the absolute path to hte .ini file, contained in inifile
std::filesystem::path relative_search_path = std::filesystem::path(options.find("relative_path").asString());
std::filesystem::path absolute_ini_file_path = std::filesystem::path(options.find("inifile").asString());
absolute_search_path = std::filesystem::weakly_canonical(absolute_ini_file_path.parent_path() / relative_search_path).string();
}

std::string ext = options.find("extension").asString();
std::string basename = (dll_name.find('.') != std::string::npos) ? name : dll_name;
std::string fn = (fn_name.empty()) ? name : fn_name;
Expand All @@ -99,20 +112,20 @@ bool YarpPluginSettings::open(SharedLibraryFactory& factory)

#if defined(_MSC_VER) && !defined(NDEBUG)
// MSVC DEBUG build: try debug name before basic name
fullpath = std::string(path).append("/").append(basename).append("d").append(ext);
fullpath = std::string(absolute_search_path).append("/").append(basename).append("d").append(ext);
if (subopen(factory, fullpath, fn))
return true;
#endif // defined(_MSC_VER) && !defined(NDEBUG)

// Basic name
fullpath = std::string(path).append("/").append(basename).append(ext);
fullpath = std::string(absolute_search_path).append("/").append(basename).append(ext);
if (subopen(factory, fullpath, fn)) {
return true;
}

#if defined(_MSC_VER) && defined(NDEBUG)
// MSVC RELEASE build: try debug name after basic name
fullpath = std::string(path).append("/").append(basename).append("d").append(ext);
fullpath = std::string(absolute_search_path).append("/").append(basename).append("d").append(ext);
if (subopen(factory, fullpath, fn))
return true;
#endif // defined(_MSC_VER) && defined(NDEBUG)
Expand All @@ -124,19 +137,19 @@ bool YarpPluginSettings::open(SharedLibraryFactory& factory)

# if defined(_MSC_VER) && !defined(NDEBUG)
// MSVC DEBUG build: try debug name before basic name
fullpath = std::string(path).append("/" CMAKE_INTDIR "/").append(dll_name).append("d").append(ext);
fullpath = std::string(absolute_search_path).append("/" CMAKE_INTDIR "/").append(dll_name).append("d").append(ext);
if (subopen(factory, fullpath, fn))
return true;
# endif // defined(_MSC_VER) && !defined(NDEBUG)

// Basic name
fullpath = std::string(path).append("/" CMAKE_INTDIR "/").append(dll_name).append(ext);
fullpath = std::string(absolute_search_path).append("/" CMAKE_INTDIR "/").append(dll_name).append(ext);
if (subopen(factory, fullpath, fn))
return true;

# if defined(_MSC_VER) && defined(NDEBUG)
// MSVC RELEASE build: try debug name after basic name
fullpath = std::string(path).append("/" CMAKE_INTDIR "/").append(dll_name).append("d").append(ext);
fullpath = std::string(absolute_search_path).append("/" CMAKE_INTDIR "/").append(dll_name).append("d").append(ext);
if (subopen(factory, fullpath, fn))
return true;
# endif // defined(_MSC_VER) && defined(NDEBUG)
Expand Down Expand Up @@ -258,6 +271,8 @@ void YarpPluginSelector::scan()
for (size_t i = 0; i < inilst.size(); i++) {
std::string inifile = inilst.get(i).asString();
Bottle inigroup = config.findGroup(inifile);

// If a .ini file containes a "plugin" key, it identifies a plugin
Bottle lst = inigroup.findGroup("plugin").tail();
for (size_t i = 0; i < lst.size(); i++) {
std::string plugin_name = lst.get(i).asString();
Expand All @@ -267,10 +282,18 @@ void YarpPluginSelector::scan()
plugins.addList() = group;
}
}

// If a .ini file containes a "search" key, it is a .ini file used to identify
// a search path, created by the yarp_configure_plugins_installation CMake macro
// from YarpInstallationHelpers.cmake
lst = inigroup.findGroup("search").tail();
for (size_t i = 0; i < lst.size(); i++) {
std::string search_name = lst.get(i).asString();
Bottle group = inigroup.findGroup(search_name);
// Propagate the inifile absolute path, so it can be used in YarpPluginSettings::open
// to obtain the absolute search path given the relative_path contained in the .ini file
// generated by yarp_configure_plugins_installation
group.add(Value::makeValue(std::string("(inifile \"") + inifile + "\")"));
search_path.addList() = group;
}
}
Expand Down

0 comments on commit c59779f

Please sign in to comment.