Context
During the OpenUSDKit modularization/client-live split, downstream aggregate live targets such as OpenUSDKitVariantsLive and OpenUSDKitMaterialsLive started failing in Xcode with:
Clang dependency scanning failure: .../_OpenUSD_SwiftBindingHelpers/include/module.modulemap:22:8: error: module '_OpenUSD_SwiftBindingHelpers' requires feature 'cplusplus'
Unable to resolve module dependency: 'std'
The immediate fix in OpenUSDKit 0.2.22 was to add .interoperabilityMode(.Cxx) to the aggregate live re-export targets, even though those targets are only tiny modules that @_exported import their concrete live client modules.
That works, but it is a smell: C++ interop requirements from SwiftUsdShellOpenUSD are leaking through re-export/aggregate targets and forcing package consumers to know more about the implementation graph than they should.
Why this matters
OpenUSDKit is moving toward a pick-and-match SDK shape:
- contract/client modules should stay pure Swift
- concrete live modules may bridge to Shell/OpenUSD
- aggregate live products should be ergonomic and boring to import
- app/package authors should not have to chase transitive C++ interop settings on re-export-only targets
If every aggregate module that re-exports a live implementation must enable C++ interop, the SDK boundary becomes harder to reason about and easy to break when modules are split further.
Current workaround
OpenUSDKit 0.2.22 added C++ interop settings to:
OpenUSDKitVariantsLive
OpenUSDKitMaterialsLive
The concrete live targets already had C++ interop enabled where they directly import SwiftUsdShellOpenUSD.
Requested follow-up
Investigate whether SwiftUsdShell can reduce or better contain this exposure.
Questions to answer:
- Should
SwiftUsdShellOpenUSD avoid exposing any public signatures or re-exported symbols that force downstream importers/re-exporters into C++ interop mode?
- Can the pure Swift
SwiftUsdShell product remain the only product visible to most SDK live aggregation layers, with OpenUSD-specific runtime implementation hidden behind narrower modules?
- Is there a packaging/target arrangement that prevents
_OpenUSD_SwiftBindingHelpers and std module dependencies from appearing in downstream aggregate-target dependency scans?
- If this is unavoidable with Swift/Xcode's current C++ interop scanner, should we document a hard rule: any target that imports or re-exports a module depending on
SwiftUsdShellOpenUSD must opt into .interoperabilityMode(.Cxx)?
Acceptance criteria
- Reproduce or explain why re-export-only targets need C++ interop when they depend on a live module that imports
SwiftUsdShellOpenUSD.
- Either reduce the leakage through target/API changes, or document the exact package authoring rule with examples.
- Add a lightweight guard or manifest audit if possible so future OpenUSDKit/Preflight module splits fail early before Xcode emits dependency-scanner errors.
Related commits
- OpenUSDKit
fb280da / tag 0.2.22: enabled C++ interop for aggregate live targets as a workaround.
- Preflight
b6d8a905: bumped OpenUSDKit to consume the workaround.
Context
During the OpenUSDKit modularization/client-live split, downstream aggregate live targets such as
OpenUSDKitVariantsLiveandOpenUSDKitMaterialsLivestarted failing in Xcode with:The immediate fix in OpenUSDKit
0.2.22was to add.interoperabilityMode(.Cxx)to the aggregate live re-export targets, even though those targets are only tiny modules that@_exported importtheir concrete live client modules.That works, but it is a smell: C++ interop requirements from
SwiftUsdShellOpenUSDare leaking through re-export/aggregate targets and forcing package consumers to know more about the implementation graph than they should.Why this matters
OpenUSDKit is moving toward a pick-and-match SDK shape:
If every aggregate module that re-exports a live implementation must enable C++ interop, the SDK boundary becomes harder to reason about and easy to break when modules are split further.
Current workaround
OpenUSDKit
0.2.22added C++ interop settings to:OpenUSDKitVariantsLiveOpenUSDKitMaterialsLiveThe concrete live targets already had C++ interop enabled where they directly import
SwiftUsdShellOpenUSD.Requested follow-up
Investigate whether SwiftUsdShell can reduce or better contain this exposure.
Questions to answer:
SwiftUsdShellOpenUSDavoid exposing any public signatures or re-exported symbols that force downstream importers/re-exporters into C++ interop mode?SwiftUsdShellproduct remain the only product visible to most SDK live aggregation layers, with OpenUSD-specific runtime implementation hidden behind narrower modules?_OpenUSD_SwiftBindingHelpersandstdmodule dependencies from appearing in downstream aggregate-target dependency scans?SwiftUsdShellOpenUSDmust opt into.interoperabilityMode(.Cxx)?Acceptance criteria
SwiftUsdShellOpenUSD.Related commits
fb280da/ tag0.2.22: enabled C++ interop for aggregate live targets as a workaround.b6d8a905: bumped OpenUSDKit to consume the workaround.