Last active
March 27, 2019 13:59
-
-
Save drdanz/d5fb1d85ffdb9122692c36715e2b3e53 to your computer and use it in GitHub Desktop.
getLibraryPath, getCurrentExecutablePath, and getInstallPrefix
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "bar.h" | |
void bar::dummy() {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef BAR_H | |
#define BAR_H | |
namespace bar { | |
void dummy(); | |
} | |
#endif // BAR_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cmake_minimum_required(VERSION 3.0) | |
project(foo) | |
find_package(YARP REQUIRED) | |
add_library(foo SHARED foo.cpp foo.h) | |
target_link_libraries(foo PRIVATE dl) | |
add_library(bar STATIC bar.cpp bar.h) | |
add_executable(main main.cpp) | |
target_link_libraries(main PRIVATE YARP::YARP_OS | |
YARP::YARP_init | |
foo | |
bar) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "foo.h" | |
#include <string> | |
#if defined(__linux__) | |
# include <link.h> | |
# include <unistd.h> | |
# include <limits.h> | |
#elif defined (__APPLE__) | |
# include <mach-o/dyld.h> | |
#endif | |
namespace { | |
// FIXME Replace with string_view.size() | |
static size_t constexpr strlength(const char* str) | |
{ | |
return *str ? 1 + strlength(str + 1) : 0; | |
} | |
} | |
// Linux: http://stackoverflow.com/a/27522149 | |
// macOS: http://stackoverflow.com/a/30293362 | |
// Windows: http://stackoverflow.com/a/6706716 | |
std::string yarp::os::getLibraryPath(const std::string& libname) | |
{ | |
std::string library_path; | |
#if defined(__linux__) // MINGW? CYGWIN? | |
link_map* map = reinterpret_cast<link_map*>(dlopen(NULL, RTLD_NOW)); | |
if (map && map->l_next) { | |
map = map->l_next->l_next;; | |
} | |
while (map) { | |
std::string name = map->l_name; | |
size_t pos = name.find("/lib" + libname + "."); | |
if (pos != std::string::npos) { | |
library_path = name.substr(0, pos); | |
break; | |
} | |
map = map->l_next; | |
} | |
#elif defined(__APPLE__) | |
for (uint32_t count = 0; count < _dyld_image_count(); ++count) { | |
std::string name = _dyld_get_image_name(count); | |
size_t pos = name.find("/lib" + libname + "."); | |
if (pos != std::string::npos) { | |
library_path = name.substr(0, pos); | |
break; | |
} | |
} | |
#elif defined(WIN32) // MSVC? MINGW? CYGWIN? | |
// FIXME should check for "YARP_OSd.dll" as well | |
HMODULE hModule = GetModuleHandle(_T(libname + ".dll")); | |
TCHAR dllPath[_MAX_PATH]; | |
GetModuleFileName(hModule, dllPath, _MAX_PATH); | |
library_path = dllPath; | |
#else | |
// path.d not supported | |
#endif | |
return library_path; | |
} | |
std::string yarp::os::getCurrentExecutablePath() | |
{ | |
std::string current_executable_path; | |
// FIXME | |
#if defined(__linux__) // MINGW? CYGWIN? | |
char buf[PATH_MAX + 1]; | |
if (readlink("/proc/self/exe", buf, sizeof(buf) - 1) != -1) { | |
current_executable_path = buf; | |
current_executable_path = current_executable_path.substr(0, current_executable_path.rfind('/')); | |
} | |
#elif defined(__APPLE__) | |
// _NSGetExecutablePath | |
#elif defined(WIN32) | |
// GetModuleFileName / GetModuleFileNameA | |
#endif | |
return current_executable_path; | |
} | |
std::string yarp::os::getInstallPrefix() | |
{ | |
#if defined(_MSC_VER) && !defined(NDEBUG) | |
std::string install_prefix = yarp::os::getLibraryPath("YARP_OSd"); | |
#else | |
std::string install_prefix = yarp::os::getLibraryPath("YARP_OS"); | |
#endif | |
if(install_prefix.empty()) { | |
// YARP is compiled statically | |
install_prefix = yarp::os::getCurrentExecutablePath(); | |
} else { | |
static constexpr size_t lib_dir_size = strlength(CMAKE_LIBRARY_DIR); | |
if (install_prefix.substr(install_prefix.size() - lib_dir_size) == CMAKE_LIBRARY_DIR) { | |
install_prefix = install_prefix.substr(0, install_prefix.size() - (lib_dir_size + 1)); | |
} | |
} | |
return install_prefix; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#ifndef FOO_H | |
#define FOO_H | |
// FIXME | |
#define YARP_OS_API | |
#define CMAKE_LIBRARY_DIR "lib" | |
#include <string> | |
namespace yarp { | |
namespace os { | |
/** | |
* @brief Get the install prefix for the library @c libname | |
* | |
* @param libname The name of the library, without prefix and extension | |
*/ | |
YARP_OS_API std::string getLibraryPath(const std::string& libname); | |
YARP_OS_API std::string getCurrentExecutablePath(); | |
/** | |
* @brief Get YARP install prefix | |
*/ | |
YARP_OS_API std::string getInstallPrefix(); | |
} | |
} | |
#endif // FOO_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "foo.h" | |
#include "bar.h" | |
#include <yarp/os/Network.h> | |
#include <iostream> | |
int main(int argc, char *argv[]) | |
{ | |
bar::dummy(); | |
yarp::os::Network yarp; | |
std::cout << "YARP install prefix: " << yarp::os::getInstallPrefix() << '\n'; | |
std::cout << "foo (shared): " << yarp::os::getLibraryPath("foo") << '\n'; | |
std::cout << "bar (static): " << yarp::os::getLibraryPath("bar") << '\n'; | |
std::cout << "baz (missing): " << yarp::os::getLibraryPath("baz") << '\n'; | |
std::cout << "current executable path: " << yarp::os::getCurrentExecutablePath() << '\n'; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment