<Choose> order for native
Nobody has claimed this yet.
- Dominant language
- F#
- Stars
- 2.1k
- Forks
- 528
- Avg merge
- 1d 12m
- Merged PRs (30d)
- 54
Description
Description
The context is a solution repo with two types of projects - C# and C++ - and both consume a library package that contains both managed and native versions of the library. This packags has a lib folder with the managed library and a build folder with targets for both the native and framework platforms ("native" and "portable-net45+win+MonoAndroid10+xamarinios10+MonoTouch10"). Each folder has a .targets file and extra native dlls (runtime dependencies) to be copied through tasks in the .targets file.
When importing the package with native build targets AND other framework version build targets, a item is added to the .csproj, file with two When Conditions. The first is always true and points to the targets in the build/native folder; the second when works out all the framework versions and profiles.
Because the first is true, the native .targets gets included in the C# project.
Because the first is true, the native .targets gets included (as expected) in the C++ project.
Expected behavior
The expected behaviour is:
- the lib-based reference and the framework specific ,targets file imported to the C# project
- the native .targets file imported into the C++ project
Actual behavior
- the C# project gets a reference to the lib-based library AND the native .targets file
- the C++ project gets the native references
Known workarounds
The workaround is a manual edition of the choose condition in the csproj file and vcxproj file.
In the csproj file, the that determines the .targets path is changed from
<Choose>
<When Condition="true">
<PropertyGroup>
<__paket__LibraryName_targets>native\LibraryName</__paket__LibraryName_targets>
</PropertyGroup>
</When>
<When Condition="($(TargetFrameworkIdentifier) == 'WindowsPhoneApp') Or ($(TargetFrameworkIdentifier) == '.NETCore') Or ($(TargetFrameworkIdentifier) == '.NETStandard' And ($(TargetFrameworkVersion) == 'v1.1' Or $(TargetFrameworkVersion) == 'v1.2' Or $(TargetFrameworkVersion) == 'v1.3' Or $(TargetFrameworkVersion) == 'v1.4' Or $(TargetFrameworkVersion) == 'v1.5' Or $(TargetFrameworkVersion) == 'v1.6')) Or ($(TargetFrameworkIdentifier) == '.NETCoreApp' And $(TargetFrameworkVersion) == 'v1.0')
Or ($(TargetFrameworkIdentifier) == '.NETFramework'
And ($(TargetFrameworkVersion) == 'v4.5'
Or $(TargetFrameworkVersion) == 'v4.5.1'
Or $(TargetFrameworkVersion) == 'v4.5.2'
Or $(TargetFrameworkVersion) == 'v4.5.3'
Or $(TargetFrameworkVersion) == 'v4.6'
Or $(TargetFrameworkVersion) == 'v4.6.1'
Or $(TargetFrameworkVersion) == 'v4.6.2'
Or $(TargetFrameworkVersion) == 'v4.6.3'))
Or ($(TargetFrameworkIdentifier) == 'MonoAndroid') Or ($(TargetFrameworkIdentifier) == 'MonoTouch') Or ($(TargetFrameworkIdentifier) == 'Xamarin.iOS') Or ($(TargetFrameworkIdentifier) == 'Xamarin.Mac') Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile44')">
<PropertyGroup>
<__paket__LibraryName_targets>portable-net45+win+MonoAndroid10+xamarinios10+MonoTouch10\LibraryName</__paket__LibraryName_targets>
</PropertyGroup>
</When>
to
<Choose>
<When Condition="($(TargetFrameworkIdentifier) == 'WindowsPhoneApp') Or ($(TargetFrameworkIdentifier) == '.NETCore') Or ($(TargetFrameworkIdentifier) == '.NETStandard' And ($(TargetFrameworkVersion) == 'v1.1' Or $(TargetFrameworkVersion) == 'v1.2' Or $(TargetFrameworkVersion) == 'v1.3' Or $(TargetFrameworkVersion) == 'v1.4' Or $(TargetFrameworkVersion) == 'v1.5' Or $(TargetFrameworkVersion) == 'v1.6')) Or ($(TargetFrameworkIdentifier) == '.NETCoreApp' And $(TargetFrameworkVersion) == 'v1.0')
Or ($(TargetFrameworkIdentifier) == '.NETFramework'
And ($(TargetFrameworkVersion) == 'v4.5'
Or $(TargetFrameworkVersion) == 'v4.5.1'
Or $(TargetFrameworkVersion) == 'v4.5.2'
Or $(TargetFrameworkVersion) == 'v4.5.3'
Or $(TargetFrameworkVersion) == 'v4.6'
Or $(TargetFrameworkVersion) == 'v4.6.1'
Or $(TargetFrameworkVersion) == 'v4.6.2'
Or $(TargetFrameworkVersion) == 'v4.6.3')
And $(TargetFrameworkProfile) != '')
Or ($(TargetFrameworkIdentifier) == 'MonoAndroid')
Or ($(TargetFrameworkIdentifier) == 'MonoTouch')
Or ($(TargetFrameworkIdentifier) == 'Xamarin.iOS')
Or ($(TargetFrameworkIdentifier) == 'Xamarin.Mac')
Or ($(TargetFrameworkProfile) == 'Profile7') Or ($(TargetFrameworkProfile) == 'Profile44')">
<PropertyGroup>
<__paket__LibraryName_targets>portable-net45+win+MonoAndroid10+xamarinios10+MonoTouch10\FARO.Math</__paket__LibraryName_targets>
</PropertyGroup>
</When>
<Otherwise>
<PropertyGroup>
<__paket__LibraryName_targets>native\LibraryName</__paket__LibraryName_targets>
</PropertyGroup>
</Otherwise>
</Choose>
Here the at the beginning is replaced with a tag at the end of the Choose element. This will give the compiler the chance to verify the complex condition first.
Also, when testing for the .NETFramework identifies, I also check for an empty profile. I'm not sure if this is always as such, but in the case of the C++ project, (verified in the verbose build output) $(TargetFrameworkProfile) is an empty string.
I can create a repo, but first I just want of understand if my reasoning here is valid. Does the above make sense?
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Inspect the generated .csproj and .vcxproj Choose blocks, along with the native and framework-specific .targets imports. Reproduce the project generation with both native and framework targets, then verify that C# selects the framework targets while C++ selects the native targets without manual project edits.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cpp, csharp
- Domain
- build-system
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100