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

api: make a 2-level namespace scheme #4567

Merged
merged 2 commits into from
Jan 15, 2025

Conversation

lgritz
Copy link
Collaborator

@lgritz lgritz commented Dec 22, 2024

TL;DR: In main, change the enclosing namespace from OpenImageIO_v3_1 to a 2-level scheme: OpenImageIO::v3_1. This can't be backported to the current release for obvious ABI cmopatibility reasons; it is a forward-looking change only.

More ponderous explanation follows:

We have for some time had a single namespace that incorporates the version, defaulting to OpenImageIO_v3_0 in the current release, for example. A namespace alias, OIIO, always aliases the current namespace, so client applications can just say OIIO::foo without needing to change source code for every minor release (let alone if a build-time option sets up a custom namespace).

By bumping the namespace for every minor release, we use the symbol names themselves to enforce a rigid ABI compatibility test, so you can't accidentally compile against one minor release and link against an older minor release. This gives us the freedom to break the ABI (link compatibility) for each minor release, without subtle user errors. (Doing it wrong makes a total failure to link, which is hard to miss.)

But being able to introduce ABI changes annually by changing the enclosing namespace comes at the cost of a complete ABI compatibility break with every minor release. Even classes or functions that haven't changed at all will be incompatible by virtue of their changed symbol names.

This is an unfortunate limitation, and in an ideal world, we would like downstream users to be able to upgrade to a newer minor release more painlessly, and confident that they could even relink or perhaps compile with a request to use an old ABI.

I haven't fully worked out all the details, or even if this is going to be worth the trouble, but I think that a change we can introduce now that will allow more flexibiity in the future is to switch to a 2-level namespace scheme, for example, OpenImageIO::v3_1 instead of the current OpenImageIO_v3_1.

The reason this might be helpful in the future is that we can use "inline" namespaces that default to finding things that are in, say, OpenImageIO::v3_2 without needing to specify it explicitly, while giving the ability to explicitly give an alternate inner versioned namespace. I haven't implemented that part here, it's reserved for future expansion (though I have experimented with it, it does work, but I want to discuss separately whether or not to actually do it).

@lgritz
Copy link
Collaborator Author

lgritz commented Jan 11, 2025

Comments? I'd like to discuss this PR at the TSC meeting on Monday. I can give an outline I can present for how we might build on this going forward to achieve a very high degree of back compatibility for ABI even as we move from one minor release to another, but I seek feedback about whether that goal is worth the amount of clutter that it will introduce.

@lgritz
Copy link
Collaborator Author

lgritz commented Jan 14, 2025

Hi, this has been in review for 3 weeks without comment and we also discussed it in yesterday's TSC meeting. I will merge it tomorrow if there are no objections raised before then.

lgritz added a commit to lgritz/OpenShadingLanguage that referenced this pull request Jan 15, 2025
Related OIIO PR: AcademySoftwareFoundation/OpenImageIO#4567

Like in the corresponding OIIO PR, I'm proposing switching to a
2-level namespace scheme (basically, `OSL::v1_14` instead of the
current `OSL_v1_14) because that opens the door to possible future
schemes to preserve better ABI compatibility between minor releases.

I would like to squeeze this in before I finalize a 1.14 beta, so that
it doesn't change again during the beta period.

Also, I changed some macro names.

Signed-off-by: Larry Gritz <[email protected]>
lgritz added a commit to lgritz/OpenShadingLanguage that referenced this pull request Jan 15, 2025
Related OIIO PR: AcademySoftwareFoundation/OpenImageIO#4567

Like in the corresponding OIIO PR, I'm proposing switching to a
2-level namespace scheme (basically, `OSL::v1_14` instead of the
current `OSL_v1_14) because that opens the door to possible future
schemes to preserve better ABI compatibility between minor releases.

I would like to squeeze this in before I finalize a 1.14 beta, so that
it doesn't change again during the beta period.

Also, I changed some macro names.

Signed-off-by: Larry Gritz <[email protected]>
lgritz added a commit to lgritz/OpenShadingLanguage that referenced this pull request Jan 15, 2025
Related OIIO PR: AcademySoftwareFoundation/OpenImageIO#4567

Like in the corresponding OIIO PR, I'm proposing switching to a
2-level namespace scheme (basically, `OSL::v1_14` instead of the
current `OSL_v1_14) because that opens the door to possible future
schemes to preserve better ABI compatibility between minor releases.

I would like to squeeze this in before I finalize a 1.14 beta, so that
it doesn't change again during the beta period.

Also, I changed some macro names.

Signed-off-by: Larry Gritz <[email protected]>
TL;DR: In main, change the enclosing namespace from `OpenImageIO_v3_1`
to a 2-level scheme: `OpenImageIO::v3_1`.  This can't be backported to
the current release for obvious reasons; it is a forward-looking
change only.

More ponderous explanation follows:

We have for some time had a single namespace that contains the
version, defaulting to `OpenImageIO_v3_0` in the current release, for
example.  A namespace alias, `OIIO`, always aliases the current
namespace, so client applications can just say `OIIO::foo` without
needing to change code for every minor release (let alone if a
build-time option sets up a custom namespace).

By bumping the namespace for every minor release, we make the symbol
names themselves enforce a rigid ABI compatibility test, so you can't
accidentally compile against one minor release and link against an
older minor release. This gives us the freedom to break the ABI (link
compatibility) for each minor release, without subtle user errors.
(Doing it wrong makes a total failure to link, which is hard to miss.)

But being able to introduce ABI changes annually by changing the
enclosing namespace comes at the cost of a *complete* ABI compatibility
break with every minor release. Even classes or functions that haven't
change at all will be incompatible by virtue of their changed symbol
names.

This is an unfortunate limitation, and in an ideal world, we would
like downstream users to be able to upgrade to a newer minor release
more painlessly, and confident that they could even relink or perhaps
compile with a request to use an old ABI.

I haven't fully worked out all the details, or even if this is going
to be worth the trouble, but I think that a change we can introduce
now that will allow more flexibiity in the future is to switch to a
2-level namespace scheme, for example, `OpenImageIO::v3_1` instead of
the current `OpenImageIO_v3_1`.

The reason this might be helpful in the future is that we can use
"inline" namespaces that default to finding things that are in, say,
OpenImageIO::v3_2 without needing to specify it explicitly, while
giving the ability to explicitly give an alternate inner versioned
namespace. I haven't implemented that part here, it's reserved for
future expansion (though I have experimented with it, it does work,
but I want to discuss separately whether or not to actually do it).

Signed-off-by: Larry Gritz <[email protected]>
Signed-off-by: Larry Gritz <[email protected]>
@lgritz lgritz merged commit b76165b into AcademySoftwareFoundation:main Jan 15, 2025
28 checks passed
lgritz added a commit that referenced this pull request Jan 15, 2025
TL;DR: In main, change the enclosing namespace from `OpenImageIO_v3_1`
to a 2-level scheme: `OpenImageIO::v3_1`.  This can't be backported to
the current release for obvious reasons; it is a forward-looking
change only.

More ponderous explanation follows:

We have for some time had a single namespace that contains the
version, defaulting to `OpenImageIO_v3_0` in the current release, for
example.  A namespace alias, `OIIO`, always aliases the current
namespace, so client applications can just say `OIIO::foo` without
needing to change code for every minor release (let alone if a
build-time option sets up a custom namespace).

By bumping the namespace for every minor release, we make the symbol
names themselves enforce a rigid ABI compatibility test, so you can't
accidentally compile against one minor release and link against an
older minor release. This gives us the freedom to break the ABI (link
compatibility) for each minor release, without subtle user errors.
(Doing it wrong makes a total failure to link, which is hard to miss.)

But being able to introduce ABI changes annually by changing the
enclosing namespace comes at the cost of a *complete* ABI compatibility
break with every minor release. Even classes or functions that haven't
change at all will be incompatible by virtue of their changed symbol
names.

This is an unfortunate limitation, and in an ideal world, we would
like downstream users to be able to upgrade to a newer minor release
more painlessly, and confident that they could even relink or perhaps
compile with a request to use an old ABI.

I haven't fully worked out all the details, or even if this is going
to be worth the trouble, but I think that a change we can introduce
now that will allow more flexibiity in the future is to switch to a
2-level namespace scheme, for example, `OpenImageIO::v3_1` instead of
the current `OpenImageIO_v3_1`.

The reason this might be helpful in the future is that we can use
"inline" namespaces that default to finding things that are in, say,
OpenImageIO::v3_2 without needing to specify it explicitly, while
giving the ability to explicitly give an alternate inner versioned
namespace. I haven't implemented that part here, it's reserved for
future expansion (though I have experimented with it, it does work,
but I want to discuss separately whether or not to actually do it).

Signed-off-by: Larry Gritz <[email protected]>
@lgritz lgritz deleted the lg-ns2level branch January 15, 2025 19:12
lgritz added a commit to AcademySoftwareFoundation/OpenShadingLanguage that referenced this pull request Jan 16, 2025
Related OIIO PR: AcademySoftwareFoundation/OpenImageIO#4567

Like in the corresponding OIIO PR, I'm proposing switching to a
2-level namespace scheme (basically, `OSL::v1_14` instead of the
current `OSL_v1_14) because that opens the door to possible future
schemes to preserve better ABI compatibility between minor releases.

I would like to squeeze this in before I finalize a 1.14 beta, so that
it doesn't change again during the beta period.

Also, I changed some macro names.

Signed-off-by: Larry Gritz <[email protected]>
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.

1 participant