ENH: reimplement Foam::dlOpen() for macOS (#2801)
- The Apple SIP (System Integrity Protection) clears environment variables, which affects the behaviour of dynamic library loading (the DYLD_LIBRARY_PATH env variable). OpenFOAM shadows this variable as FOAM_LD_LIBRARY_PATH, which has been used to restore DYLD_LIBRARY_PATH (eg, in RunFunctions script). However, this solution is not quite complete, as it (a) requires sourcing of RunFunctions file, (b) additional errors appear depending on a user workflow. This changeset alleviates the problem by also iterating through paths stored in the shadow variable when loading dynamic libraries (if the DYLD_LIBRARY_PATH is empty).
This commit is contained in:
parent
83b1ebee6f
commit
f584ec97d0
@ -23,13 +23,6 @@
|
|||||||
# If dispatching via foamExec
|
# If dispatching via foamExec
|
||||||
foamExec="$WM_PROJECT_DIR/bin/tools/foamExec"
|
foamExec="$WM_PROJECT_DIR/bin/tools/foamExec"
|
||||||
|
|
||||||
# Darwin workaround - SIP clearing DYLD_LIBRARY_PATH variable
|
|
||||||
if [ -n "$FOAM_LD_LIBRARY_PATH" ] && [ -z "$DYLD_LIBRARY_PATH" ]
|
|
||||||
then
|
|
||||||
export DYLD_LIBRARY_PATH="$FOAM_LD_LIBRARY_PATH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
usage() {
|
usage() {
|
||||||
|
@ -25,13 +25,6 @@
|
|||||||
# Basic sanity checks
|
# Basic sanity checks
|
||||||
[ -d "$FOAM_TUTORIALS" ] || echo "No OpenFOAM tutorials? : $FOAM_TUTORIALS" 1>&2
|
[ -d "$FOAM_TUTORIALS" ] || echo "No OpenFOAM tutorials? : $FOAM_TUTORIALS" 1>&2
|
||||||
|
|
||||||
# Darwin workaround - SIP clearing DYLD_LIBRARY_PATH variable
|
|
||||||
if [ -n "$FOAM_LD_LIBRARY_PATH" ] && [ -z "$DYLD_LIBRARY_PATH" ]
|
|
||||||
then
|
|
||||||
export DYLD_LIBRARY_PATH="$FOAM_LD_LIBRARY_PATH"
|
|
||||||
fi
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -41,6 +41,7 @@ Description
|
|||||||
#include "timer.H"
|
#include "timer.H"
|
||||||
#include "DynamicList.H"
|
#include "DynamicList.H"
|
||||||
#include "CStringList.H"
|
#include "CStringList.H"
|
||||||
|
#include "stringOps.H"
|
||||||
#include "IOstreams.H"
|
#include "IOstreams.H"
|
||||||
#include "Pstream.H"
|
#include "Pstream.H"
|
||||||
|
|
||||||
@ -108,6 +109,52 @@ static inline void redirects(const bool bg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Library loading is normally simply via dlopen(),
|
||||||
|
// but SIP (System Integrity Protection) on Apple will generally
|
||||||
|
// clear out the DYLD_LIBRARY_PATH set from shell scripts.
|
||||||
|
// We thus have FOAM_LD_LIBRARY_PATH as a shadow parameter and use
|
||||||
|
// that to attempt loading ourselves
|
||||||
|
static inline void* loadLibrary(const Foam::fileName& libName)
|
||||||
|
{
|
||||||
|
constexpr int ldflags = (RTLD_LAZY|RTLD_GLOBAL);
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
const char* normal = nullptr;
|
||||||
|
const char* shadow = nullptr;
|
||||||
|
|
||||||
|
if
|
||||||
|
(
|
||||||
|
!libName.isAbsolute()
|
||||||
|
&& ((normal = ::getenv("DYLD_LIBRARY_PATH")) == nullptr || !*normal)
|
||||||
|
&& ((shadow = ::getenv("FOAM_LD_LIBRARY_PATH")) != nullptr && *shadow)
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// SIP appears to have cleared DYLD_LIBRARY_PATH but the
|
||||||
|
// shadow parameter is available
|
||||||
|
|
||||||
|
const Foam::string ldPaths(shadow);
|
||||||
|
const auto paths = Foam::stringOps::split<Foam::string>(ldPaths, ':');
|
||||||
|
|
||||||
|
for (const auto& p : paths)
|
||||||
|
{
|
||||||
|
if (p.length()) // Split removes empty, but be paranoid
|
||||||
|
{
|
||||||
|
const Foam::fileName fullPath(p.str()/libName);
|
||||||
|
void* handle = ::dlopen(fullPath.c_str(), ldflags);
|
||||||
|
if (handle)
|
||||||
|
{
|
||||||
|
return handle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Regular loading
|
||||||
|
return ::dlopen(libName.c_str(), ldflags);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// * * * * * * * * * * * * * * * * Local Classes * * * * * * * * * * * * * * //
|
// * * * * * * * * * * * * * * * * Local Classes * * * * * * * * * * * * * * //
|
||||||
|
|
||||||
namespace Foam
|
namespace Foam
|
||||||
@ -1752,16 +1799,13 @@ int Foam::system(const Foam::UList<Foam::string>& command, const bool bg)
|
|||||||
|
|
||||||
void* Foam::dlOpen(const fileName& libName, const bool check)
|
void* Foam::dlOpen(const fileName& libName, const bool check)
|
||||||
{
|
{
|
||||||
constexpr int ldflags = (RTLD_LAZY|RTLD_GLOBAL);
|
|
||||||
|
|
||||||
if (POSIX::debug)
|
if (POSIX::debug)
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
<< "dlOpen(const fileName&)"
|
<< "dlopen() of " << libName << std::endl;
|
||||||
<< " : dlopen of " << libName << std::endl;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void* handle = ::dlopen(libName.c_str(), ldflags);
|
void* handle = loadLibrary(libName);
|
||||||
|
|
||||||
if (!handle)
|
if (!handle)
|
||||||
{
|
{
|
||||||
@ -1771,13 +1815,12 @@ void* Foam::dlOpen(const fileName& libName, const bool check)
|
|||||||
{
|
{
|
||||||
// Try with 'lib' prefix
|
// Try with 'lib' prefix
|
||||||
libso = "lib" + libName;
|
libso = "lib" + libName;
|
||||||
handle = ::dlopen(libso.c_str(), ldflags);
|
handle = loadLibrary(libso);
|
||||||
|
|
||||||
if (POSIX::debug)
|
if (POSIX::debug)
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
<< "dlOpen(const fileName&)"
|
<< " dlopen() as " << libso << std::endl;
|
||||||
<< " : dlopen of " << libso << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -1790,13 +1833,12 @@ void* Foam::dlOpen(const fileName& libName, const bool check)
|
|||||||
if (!handle && !libso.has_ext(EXT_SO))
|
if (!handle && !libso.has_ext(EXT_SO))
|
||||||
{
|
{
|
||||||
libso.replace_ext(EXT_SO);
|
libso.replace_ext(EXT_SO);
|
||||||
handle = ::dlopen(libso.c_str(), ldflags);
|
handle = loadLibrary(libso);
|
||||||
|
|
||||||
if (POSIX::debug)
|
if (POSIX::debug)
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
<< "dlOpen(const fileName&)"
|
<< " dlopen() as " << libso << std::endl;
|
||||||
<< " : dlopen of " << libso << std::endl;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1810,8 +1852,7 @@ void* Foam::dlOpen(const fileName& libName, const bool check)
|
|||||||
if (POSIX::debug)
|
if (POSIX::debug)
|
||||||
{
|
{
|
||||||
std::cout
|
std::cout
|
||||||
<< "dlOpen(const fileName&)"
|
<< "dlopen() of " << libName
|
||||||
<< " : dlopen of " << libName
|
|
||||||
<< " handle " << handle << std::endl;
|
<< " handle " << handle << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user