Skip to content

[#25] Reactive: pair each target framework with its own Iceoryx2 build - #26

Open
patdhlk wants to merge 2 commits into
eclipse-iceoryx:mainfrom
patdhlk:csharp-iox2-25-reactive-tfm-pin
Open

[#25] Reactive: pair each target framework with its own Iceoryx2 build#26
patdhlk wants to merge 2 commits into
eclipse-iceoryx:mainfrom
patdhlk:csharp-iox2-25-reactive-tfm-pin

Conversation

@patdhlk

@patdhlk patdhlk commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Notes for Reviewer

One line deleted, plus a comment recording why it must stay deleted, plus a CHANGELOG entry.

src/Iceoryx2.Reactive/Iceoryx2.Reactive.csproj pinned the Iceoryx2 ProjectReference with
<SetTargetFramework>TargetFramework=net8.0</SetTargetFramework>. That overrides MSBuild's
nearest-TFM matching, so every target framework of Iceoryx2.Reactive compiled against and
copied the net8.0 build of Iceoryx2.

This is a pre-existing bug on main, not a regression from #24. Build output before/after,
comparing the Iceoryx2.dll each Iceoryx2.Reactive target framework emits against the matching
Iceoryx2 build (sha1, first 12 hex digits):

TFM Iceoryx2/bin/Release/<tfm>/ Reactive before Reactive after
net8.0 67c296abd6c1 67c296abd6c1 67c296abd6c1
net9.0 2dd619b2fa5c 67c296abd6c1 2dd619b2fa5c
net10.0 c92900c379e5 67c296abd6c1 c92900c379e5

It stayed silent because net8.0 → net9.0/net10.0 assembly references unify forward. Two things it
cost us:

  1. build.yml uploads src/Iceoryx2.Reactive/bin/Release/ wholesale, so the dotnet-build
    artifact's net9.0/ and net10.0/ folders shipped a net8.0 Iceoryx2.dll next to a
    net9.0/net10.0 Iceoryx2.Reactive.dll.
  2. Iceoryx2.Reactive only ever saw the net8.0 surface of Iceoryx2, so target-framework-specific
    API divergence could not fail the build — it would have failed at runtime.

The NuGet packages were never affected: lib/<tfm>/ holds only Iceoryx2.Reactive.dll and the
nuspec declares Iceoryx2 as a package dependency per group, so a restored package always pairs
matching assemblies.

Why removal rather than TargetFramework=$(TargetFramework)

Pass-through hard-fails if the two projects' TFM lists ever diverge; nearest-match degrades
gracefully. I also confirmed the pin was not load-bearing for packaging —
PrivateAssets/IncludeAssets/ReferenceOutputAssembly are what turn the ProjectReference into
a package dependency, and pack output is unchanged (see below).

Verification

  • Solution builds, 0 warnings, 0 errors
  • dotnet format --verify-no-changes clean
  • Tests 28/28 on each of net8.0, net9.0, net10.0
  • dotnet pack unchanged: Iceoryx2 0.1.0 + System.Reactive 6.0.1 in all three nuspec
    dependency groups, lib/<tfm>/ still contains only Iceoryx2.Reactive.dll

Unblocks #24

netstandard2.1 does not unify forward from net8.0, so on #24 (.NET Standard 2.1 / Unity
support) this pin produced 7 × MSB3277: Found conflicts between different versions of ... that could not be resolved (System.Runtime, System.Linq, System.Collections, System.Console,
System.ComponentModel, System.Runtime.InteropServices, System.Threading.Thread). I applied
this change on top of #24 at d42c827 and confirmed it builds with 0 warnings and all four
target frameworks paired — so #24 needs no workaround once this lands.

Not covered

No unit test. The defect lives in MSBuild reference resolution, so the only meaningful assertion is
"the Iceoryx2.dll in each output directory matches that TFM's build", which needs a build-output
check rather than an xUnit test. If you'd like a guard against regression I can add one to
build.yml, but I'd rather do that as a follow-up than widen this PR — the in-file comment is the
lightweight version.

Pre-Review Checklist for the PR Author

  • Add sensible notes for the reviewer
  • PR title is short, expressive and meaningful
  • Consider switching the PR to a draft (Convert to draft)
    • as draft PR, the CI will be skipped for pushes
    • considered; kept open as CI evidence is the point of this change
  • Relevant issues are linked in the References section
  • Branch follows the naming format (csharp-iox2-123-short-description)
    • csharp-iox2-25-reactive-tfm-pin
  • Commits messages are according to this guideline
    • Commit messages have the issue ID ([#123] Add feature description)
  • Tests have been added/updated for new functionality
    • n/a — build-configuration fix, no new functionality; see "Not covered" above
  • XML documentation comments added to public APIs
    • n/a — no public API change
  • Changelog updated in the unreleased section including API breaking changes
    • ### Bugfixes; no API breaking changes
  • Assign PR to reviewer
  • All checks have passed

PR Reviewer Reminders

  • Commits are properly organized and messages are according to the guideline
  • Unit tests have been written for new behavior
  • Public API is documented with XML comments
  • PR title describes the changes
  • Code follows C# conventions (PascalCase for public APIs)
    • dotnet format has been exectued before submitting

References

Closes #25

patdhlk added 2 commits August 4, 2026 08:03
…2 reference

SetTargetFramework overrides MSBuild's nearest-TFM matching, so pinning
TargetFramework=net8.0 on the Iceoryx2 ProjectReference made *every*
target framework of Iceoryx2.Reactive compile against and copy the
net8.0 build of Iceoryx2. Comparing build output on main:

  TFM      Iceoryx2/bin        Reactive/bin
  net8.0   67c296abd6c1        67c296abd6c1
  net9.0   2dd619b2fa5c        67c296abd6c1  <- net8.0
  net10.0  c92900c379e5        67c296abd6c1  <- net8.0

It stayed silent because net8.0 -> net9.0/net10.0 references unify
forward. Two consequences: build.yml uploads
src/Iceoryx2.Reactive/bin/Release/ wholesale, so the published artifact
pairs mismatched assemblies; and Reactive only ever saw the net8.0
surface of Iceoryx2, so TFM-specific API divergence could not fail the
build.

Deleting the metadata restores nearest-TFM matching and pairs each
target framework with its own Iceoryx2 build. Preferred over threading
TargetFramework=$(TargetFramework) through, which would hard-fail if the
two TFM lists ever diverge instead of degrading to nearest-match.

The pin was not load-bearing for packaging: PrivateAssets/IncludeAssets/
ReferenceOutputAssembly are what turn the ProjectReference into a
package dependency. dotnet pack still declares Iceoryx2 0.1.0 and
System.Reactive 6.0.1 in all nuspec dependency groups, and lib/<tfm>/
still contains only Iceoryx2.Reactive.dll.

Also unblocks eclipse-iceoryx#24 (.NET Standard 2.1 support): netstandard2.1 does not
unify forward from net8.0, so the pin produced 7 x MSB3277 unresolvable
assembly conflicts there. Verified that with this change eclipse-iceoryx#24 builds with
0 warnings and all four target frameworks paired.
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.

Iceoryx2.Reactive references the net8.0 Iceoryx2.dll for every target framework

2 participants