Skip to content

Commit 18e60af

Browse files
Merge pull request #1127 from johnhaddon/dlopenFlagsPR
Add IECORE_RTLD_GLOBAL environment variable
2 parents 6360d04 + 73d3136 commit 18e60af

File tree

7 files changed

+69
-43
lines changed

7 files changed

+69
-43
lines changed

.github/workflows/main.yml

+6-4
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ jobs:
4444
buildType: RELEASE
4545
containerImage: gafferhq/build:1.0.0
4646
options: .github/workflows/main/options.posix
47-
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/2.1.1/gafferDependencies-2.1.1-Python2-linux.tar.gz
47+
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/3.0.0a2/gafferDependencies-3.0.0-Python2-linux.tar.gz
4848
tests: testCorePython testScene testImage testAlembic testUSD testVDB testArnold testAppleseed
4949
publish: true
5050

@@ -53,7 +53,7 @@ jobs:
5353
buildType: DEBUG
5454
containerImage: gafferhq/build:1.0.0
5555
options: .github/workflows/main/options.posix
56-
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/2.1.1/gafferDependencies-2.1.1-Python2-linux.tar.gz
56+
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/3.0.0a2/gafferDependencies-3.0.0-Python2-linux.tar.gz
5757
tests: testCorePython testScene testImage testAlembic testUSD testVDB testArnold testAppleseed
5858
publish: false
5959

@@ -62,7 +62,7 @@ jobs:
6262
buildType: RELEASE
6363
containerImage: gafferhq/build:1.0.0
6464
options: .github/workflows/main/options.posix
65-
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/2.1.1/gafferDependencies-2.1.1-Python3-linux.tar.gz
65+
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/3.0.0a2/gafferDependencies-3.0.0-Python3-linux.tar.gz
6666
tests: testCorePython testScene testImage testAlembic testUSD testVDB testArnold testAppleseed
6767
publish: true
6868

@@ -71,7 +71,7 @@ jobs:
7171
buildType: RELEASE
7272
containerImage:
7373
options: .github/workflows/main/options.posix
74-
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/2.1.1/gafferDependencies-2.1.1-Python2-osx.tar.gz
74+
dependenciesURL: https://github.com/GafferHQ/dependencies/releases/download/3.0.0a2/gafferDependencies-3.0.0-Python2-osx.tar.gz
7575
# `testArnold` currently omitted due to problems loading `libai.dylib` on MacOS workers (possible SIP issue),
7676
# and `testAppleseed` due to clashes with system image IO frameworks.
7777
tests: testCorePython testScene testImage testAlembic testUSD testVDB
@@ -164,6 +164,8 @@ jobs:
164164
- name: Test
165165
run: |
166166
scons ${{ matrix.tests }} BUILD_TYPE=${{ matrix.buildType }} OPTIONS=${{ matrix.options }} CXXSTD=c++14 BUILD_CACHEDIR=sconsCache
167+
env:
168+
IECORE_RTLD_GLOBAL: 0
167169
# We have some work to do before we can run the tests
168170
# successfully on Windows. Until then, we satisfy ourselves
169171
# with checking that it at least _builds_.

.github/workflows/main/options.posix

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ APPLESEED_LIB_PATH = deps + "/appleseed/lib"
6666
# Environment
6767
# ===========
6868

69-
ENV_VARS_TO_IMPORT = "PATH"
69+
ENV_VARS_TO_IMPORT = "PATH IECORE_RTLD_GLOBAL"
7070

7171
if platform.system() == "Darwin" :
7272
os.environ["DYLD_FRAMEWORK_PATH"] = libs

SConstruct

+4-1
Original file line numberDiff line numberDiff line change
@@ -2995,6 +2995,10 @@ arnoldPythonModuleEnv.Append(
29952995
arnoldDriverEnv = arnoldEnv.Clone( IECORE_NAME = "ieOutputDriver" )
29962996
arnoldDriverEnv["SHLIBPREFIX"] = ""
29972997
arnoldDriverEnv["SHLIBSUFFIX"] = ".so" if env["PLATFORM"] != "win32" else ".dll"
2998+
if env["PLATFORM"]=="darwin" :
2999+
# Symbols we need from `libai.dylib` will be resolved at runtime when Arnold
3000+
# loads the driver.
3001+
arnoldDriverEnv.Append( LINKFLAGS = "-Wl,-undefined,dynamic_lookup" )
29983002

29993003
haveArnold = False
30003004

@@ -3041,7 +3045,6 @@ if doConfigure :
30413045

30423046
arnoldDriverEnv.Append(
30433047
LIBS = [
3044-
"ai",
30453048
os.path.basename( coreEnv.subst( "$INSTALL_LIB_NAME" ) ),
30463049
os.path.basename( imageEnv.subst( "$INSTALL_LIB_NAME" ) ),
30473050
os.path.basename( arnoldEnv.subst( "$INSTALL_LIB_NAME" ) ),

config/ie/options

+25-22
Original file line numberDiff line numberDiff line change
@@ -431,28 +431,31 @@ DOXYGEN = os.path.join( "/software/apps/doxygen", os.environ["DOXYGEN_VERSION"],
431431
os.environ["OCIO"] = "/software/config/openColorIO/nuke-default/config.ocio"
432432

433433
# import vars we need to get our doxygen and python wrappers working
434-
envVarsToImport = ["PATH",
435-
"COMPILER",
436-
"COMPILER_VERSION",
437-
"PYTHONPATH",
438-
"IEENV_ROOT",
439-
"IEENV_WORKING_PATH",
440-
"IEENV_LIBRARY_PREFIX_PATH",
441-
"DOXYGEN_VERSION",
442-
"IEENV_DEBUG",
443-
"IEENV_DEBUG_PYTHON",
444-
"IEENV_DEBUGGER",
445-
"IEENV_DEBUGGER_ARGS",
446-
"DELIGHT_CONF",
447-
"SCONS_VERSION",
448-
"DL_VERSION",
449-
"DL_SHADERS_PATH",
450-
"DL_DISPLAYS_PATH",
451-
"solidangle_LICENSE",
452-
"CORTEX_POINTDISTRIBUTION_TILESET",
453-
"OCIO",
454-
"IECORE_DEBUG_WAIT",
455-
"CORTEX_PERFORMANCE_TEST"]
434+
envVarsToImport = [
435+
"PATH",
436+
"COMPILER",
437+
"COMPILER_VERSION",
438+
"PYTHONPATH",
439+
"IEENV_ROOT",
440+
"IEENV_WORKING_PATH",
441+
"IEENV_LIBRARY_PREFIX_PATH",
442+
"DOXYGEN_VERSION",
443+
"IEENV_DEBUG",
444+
"IEENV_DEBUG_PYTHON",
445+
"IEENV_DEBUGGER",
446+
"IEENV_DEBUGGER_ARGS",
447+
"DELIGHT_CONF",
448+
"SCONS_VERSION",
449+
"DL_VERSION",
450+
"DL_SHADERS_PATH",
451+
"DL_DISPLAYS_PATH",
452+
"solidangle_LICENSE",
453+
"CORTEX_POINTDISTRIBUTION_TILESET",
454+
"OCIO",
455+
"IECORE_DEBUG_WAIT",
456+
"CORTEX_PERFORMANCE_TEST",
457+
"IECORE_RTLD_GLOBAL",
458+
]
456459

457460
ENV_VARS_TO_IMPORT= " ".join(envVarsToImport)
458461

python/IECore/__init__.py

+19-13
Original file line numberDiff line numberDiff line change
@@ -38,21 +38,27 @@
3838
#
3939
# Some parts of the IECore library are defined purely in Python. These are shown below.
4040

41-
# Turn on RTLD_GLOBAL to avoid the dreaded cross module RTTI
42-
# errors on Linux. This causes libIECore etc to be loaded into
43-
# the global symbol table and those symbols to be shared between
44-
# modules. Without it, different python modules and/or libraries
45-
# can end up with their own copies of symbols, which breaks a
46-
# great many things.
47-
#
48-
# We use the awkward "__import__" approach to avoid importing sys
49-
# and ctypes into the IECore namespace.
50-
51-
if __import__( "os" ).name == 'posix':
52-
__import__( "sys" ).setdlopenflags(
53-
__import__( "sys" ).getdlopenflags() | __import__( "ctypes" ).RTLD_GLOBAL
41+
import os, sys, ctypes
42+
if os.name == "posix" and os.environ.get( "IECORE_RTLD_GLOBAL", "1" ) == "1" :
43+
# Historically, we had problems with cross-module RTTI on Linux, whereby
44+
# different Python modules and/or libraries could end up with their own
45+
# copies of symbols, which would break things like dynamic casts. We worked
46+
# around this by using RTLD_GLOBAL so that everything was loaded into the
47+
# global symbol table and shared, but this can cause hard-to-diagnose
48+
# knock-on effects from unwanted sharing.
49+
#
50+
# We now manage symbol visibility properly so that RTTI symbols should not
51+
# be duplicated between modules, and we intend to remove RTLD_GLOBAL. To aid
52+
# the transition, this behaviour can be controlled by the
53+
# `IECORE_RTLD_GLOBAL` environment variable, which currently defaults on.
54+
## \todo Get everything tested, default to off, and then remove.
55+
sys.setdlopenflags(
56+
sys.getdlopenflags() | ctypes.RTLD_GLOBAL
5457
)
5558

59+
# Remove pollution of IECore namespace
60+
del os, sys, ctypes
61+
5662
__import__( "imath" )
5763

5864
from ._IECore import *

src/IECoreHoudini/plugin/Plugin.cpp

+5-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,11 @@ extern "C"
7272
{
7373
SYS_VISIBILITY_EXPORT void HoudiniDSOInit( UT_DSOInfo &dsoinfo )
7474
{
75-
dsoinfo.loadGlobal = true;
75+
const char *forceGlobals = std::getenv( "IECORE_RTLD_GLOBAL" );
76+
if( !forceGlobals || !strcmp( forceGlobals, "1" ) )
77+
{
78+
dsoinfo.loadGlobal = true;
79+
}
7680
}
7781
}
7882

src/IECoreMaya/plugin/Loader.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,15 @@ IECORE_EXPORT MStatus initializePlugin( MObject obj )
6666

6767
std::string implName = pluginPath + "/impl/" + pluginName + ".so";
6868

69-
g_libraryHandle = dlopen( implName.c_str(), RTLD_NOW | RTLD_GLOBAL );
69+
const char *forceGlobals = std::getenv( "IECORE_RTLD_GLOBAL" );
70+
if( !forceGlobals || !strcmp( forceGlobals, "1" ) )
71+
{
72+
g_libraryHandle = dlopen( implName.c_str(), RTLD_NOW | RTLD_GLOBAL );
73+
}
74+
else
75+
{
76+
g_libraryHandle = dlopen( implName.c_str(), RTLD_NOW );
77+
}
7078

7179
if (! g_libraryHandle )
7280
{

0 commit comments

Comments
 (0)