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

Symbol visibility #2431

Merged
merged 44 commits into from
Feb 5, 2018
Merged

Symbol visibility #2431

merged 44 commits into from
Feb 5, 2018

Conversation

johnhaddon
Copy link
Member

This is the Gaffer equivalent of ImageEngine/cortex#695. It'll need that merged into GafferHQ/dependencies before the tests will pass.

These were predicated on the knowledge that internally the OpenImageIOReader used an OIIO::ImageCache, but that is no longer the case.
Tests are always run via Python, so it's better just to hide the C++ entirely, rather than add symbol exports for stuff nobody needs.
Even though we're deliberately hiding all the implementation of the class in .cpp files, this is not enough to stop the compiler automating generating typeinfo symbols in every translation unit that includes the TypedObjectPlug header. This meant that libGaffer had one copy of the symbol (the one we wanted), but python/Gaffer/_Gaffer.so had its own copy. On Mac this broke the python bindings with this error :

```
ArgumentError: Python argument types in
    InternedStringVectorDataPlug.defaultValue(InternedStringVectorDataPlug)
did not match C++ signature:
    defaultValue(boost::intrusive_ptr<Gaffer::TypedObjectPlug<IECore::TypedData<std::__1::vector<IECore::InternedString, std::__1::allocator<IECore::InternedString> > > > >, bool _copy=True)
```

Because we had two typeinfo symbols for the same class, type comparisons were failing and boost::python believed it was not receiving an object of the right type. This didn't occur on Linux, because there boost python compares typeinfo names rather than typeinfo addresses.

The solution is to declare the TypedObjectPlug classes as `extern template`, preventing the compiler from emitting typeinfo symbols except when compiling libGaffer.
In addition to the -Werror compiler flag that was always on before, this also controls the -fatal_warnings linker flag, which was always off before.
@andrewkaufman
Copy link
Contributor

Feel free to merge once the dependencies are updated and Travis is content.

This provides the symbol visibility handling from Cortex 10.0.0-a13
The GafferImageTest library no longer exists - it was effectively removed in 3df6cd8.
@andrewkaufman
Copy link
Contributor

I'm not sure what's going on, but the travis tests have failed twice now in a way that looks like it couldn't even install gaffer.

@johnhaddon
Copy link
Member Author

I'm busy wrangling updates to the dependencies project, pushing new builds as I find new problems. I've been updating things for VFXPlatform 2018 and there have been a few teething problems. Hang tight...

@johnhaddon
Copy link
Member Author

Still got some issues to fix - there's one which is a VDB symbol visibility issue on Mac (I have a fix in the works for that), but mostly it's just unrelated build issues with the dependencies. I'm calling it a day now though...

Based on the canonical example at http://www.openvdb.org/documentation/doxygen/codeExamples.html#sGettingMetadata :

- Use `staticTypeName()` rather than hardcoded strings
- Use `static_cast()` rather than `DynamicPtrCast()` (because we've already checked the type)

Other than simplifying things, the motivator here is that the current code was silently failing on OSX. This was because the dynamic_cast was failing, because openvdb doesn't mark the TypedMetadata classes as exported. I presume this led to libGafferVDB.so
and libopenvdb.so having different copies of the typeinfo. Typeinfo comparisons on OSX compare the symbol address, so we would need both libraries to share the same symbol for the comparison to succeed. We get away with it on Linux because there typeinfo comparisons compare the typename strings instead.

Note that this was also fixable by enclosing the openvdb headers in IECORE_PUSH/POP_DEFAULT_VISIBILITY, but it seemed worth following the canonical example instead since it also simplifies the code.
Precise doesn't meet the glibc requirements for VFXPlatform 2018 (it has 2.15, but 2.17 is required as a minimum). Support for it was also discontinued as of April 2017. Trusty provides glibc 2.19 and is supported until April 2019. It is also the default distro for Travis at the time of writing.
Since the AlembicInput node was removed, GafferScene no longer needs any symbols from IECoreAlembic. We now use a startup file to load IECoreAlembic in the same was as we do for IECoreUSD.

For some reason this change was necessary to allow `SceneReaderTest.testAlembic` to pass on Travis, although it was passing OK for me locally. Perhaps some issue whereby the linker on Travis was optimising away unused libraries?
I've spent hours looking at this, both now and the first time we tried to update to the Trusty image. I'm still not sure what's going on, but I've grabbed the image being displayed in the window at the point of failure and copyied it out of the docker container, and it is as it should be. I'm chalking this up to some oddball xvfb problem and moving on...
@johnhaddon johnhaddon merged commit e05c681 into GafferHQ:master Feb 5, 2018
@johnhaddon
Copy link
Member Author

Finally coaxed the Travis tests over the line and merged...

@johnhaddon johnhaddon deleted the symbolVisibility branch February 5, 2018 22:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants