Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

path.d folder should NOT be searched using ResourceFinder #522

Open
drdanz opened this issue Jul 1, 2015 · 10 comments
Open

path.d folder should NOT be searched using ResourceFinder #522

drdanz opened this issue Jul 1, 2015 · 10 comments
Labels
Milestone

Comments

@drdanz
Copy link
Member

drdanz commented Jul 1, 2015

Resource finder looks for the path.d folder using the YARP_DATA_DIRS variable that, if not set, uses the XDG_DATA_DIRS variable, that defaults in /usr/local/share/:/usr/share/. This means that if the user has a folder in /usr/local/share/yarp/path.d from some old installation and YARP and iCub are installed using the packages (therefore in /usr), YARP will see the wrong path.d folder and therefore will not be able to locate iCub files.

The right behaviour is to use only the path.d folder in the executable prefix (in this case /usr/share/yarp/path.d

CC @mbrunettini

@drdanz drdanz added this to the YARP 2.4.0 milestone Jul 1, 2015
@drdanz
Copy link
Member Author

drdanz commented Jul 1, 2015

Also the path.d folder should be used ONLY if yarp is installed, not from the build directory

@drdanz
Copy link
Member Author

drdanz commented Jul 15, 2015

Locating the position of the libYARP_OS library could be a way to locate the path.d folder without hard coding the path inside.

This small test detects the path of the linked libYARP_OS.so library on linux and uses it to generate the name path.d of the directory. Original example taken from here.

I don't know yet if it could be adapted for windows and mac, perhaps using ACE.

CMAKE_LIBRARY_DIR and CMAKE_INSTALL_DATADIR are relative paths and could be exported from CMake.

In this way the executable will not contain hard coded paths and can be relocated without issues.

This will not avoid that the path.d folder is located in the build directory, but I think we can live with that.

#include <yarp/os/Network.h>
#include <link.h>
#include <string>

#define CMAKE_LIBRARY_DIR "lib"
#define CMAKE_INSTALL_DATADIR "share"
#define PATH_D "/yarp/config/path.d"


int main(int argc, char *argv[])
{
    yarp::os::Network yarp;

    struct unknown_struct
    {
       void*  pointers[3];
       struct unknown_struct* ptr;
    };

    void* handle = dlopen(NULL, RTLD_NOW);
    unknown_struct* p = reinterpret_cast<unknown_struct*>(handle)->ptr;
    link_map* map = reinterpret_cast<link_map*>(p->ptr);

    while (map) {
        std::string name = map->l_name;
        size_t pos = name.find(CMAKE_LIBRARY_DIR "/libYARP_OS.so");
        // do something with |map| like with handle, returned by |dlopen()|.
        if (pos != std::string::npos) {
            std::string path = name.substr(0, pos);
            std::string path_d = path + CMAKE_INSTALL_DATADIR + PATH_D;
            std::cout << path_d << std::endl;
            break;
        }
        map = map->l_next;
    }
}

@drdanz drdanz removed this from the YARP 2.4.0 milestone Jun 20, 2016
@drdanz
Copy link
Member Author

drdanz commented Aug 19, 2016

The code above:

  • will not work for Windows (Is path.d used on windows? the install prefix is usually different anyway. Maybe we can find a different way to detect the dll on windows)
  • will not work for macOS (maybe changing .so to .dylib is enough?)
  • will not work for YARP static builds (I'm not sure how to handle this)

I copied the code in a gist and added a CMakeLists.txt so that it is easier to test: https://gist.github.com/drdanz/d5fb1d85ffdb9122692c36715e2b3e53

@francesco-romano
Copy link
Collaborator

francesco-romano commented Aug 19, 2016

Regarding macOS this stack overflow issue can help solving the problem on macOS.

I adapted the code for our limited use.

The following code

#include <mach-o/dyld.h>
#include <string>
#include <iostream>

#define CMAKE_LIBRARY_DIR "lib"
#define CMAKE_INSTALL_DATADIR "share"
#define PATH_D "/yarp/config/path.d"


int main(int argc, char *argv[])
{

    for (uint32_t count = 0; count < _dyld_image_count(); ++count) {
        std::string name = _dyld_get_image_name(count);
        size_t pos = name.find(CMAKE_LIBRARY_DIR "/libYARP_OS.");
        // do something with |map| like with handle, returned by |dlopen()|.
        if (pos != std::string::npos) {
            std::string path = name.substr(0, pos);
            std::string path_d = path + CMAKE_INSTALL_DATADIR + PATH_D;
            std::cout << path_d << std::endl;
            break;
        }
    }
}

Outputs:

/Users/makaveli/Projects/src/local/share/yarp/config/path.d

@drdanz
Copy link
Member Author

drdanz commented Aug 19, 2016

@francesco-romano Awesome, thanks! just for information, is there a difference between #include and #import on macOS?

@francesco-romano
Copy link
Collaborator

francesco-romano commented Aug 20, 2016

@drdanz ops sorry. I modified the snippet.

Yes, #import is like #include but it checks that the file is included only once. Of course is something related to Objective C extensions, and it is probably not portable.

@drdanz
Copy link
Member Author

drdanz commented Aug 20, 2016

No problem, I updated the gist above, it should now work both for linux and macos...

@traversaro
Copy link
Member

cc @diegoferigo is probably also interested in this.

@drdanz drdanz added the Type: Breaking/Behaviour Change Involves breaking user code or behaviour label Apr 13, 2018
@drdanz
Copy link
Member Author

drdanz commented Apr 13, 2018

It would be nice if we could get this in YARP 3.0

@traversaro
Copy link
Member

traversaro commented Jan 12, 2024

A variant of what was proposed here that work on Linux, macOS and Windows natively is implemented in reloc-cpp. The trick there is to use dladdr on Linux/macOS and GetModuleFileNameA on Windows to get the location of the shared library. The related C++ code is in https://github.com/ami-iit/reloc-cpp/blob/57cb7fadbda5282eb4931329ddda6a6fa458916c/RelocCPPGenerate.cmake#L128-L156 .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants