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

Sample projects fail to properly build on Windows #1037

Closed
pgrawehr opened this issue Apr 4, 2020 · 6 comments
Closed

Sample projects fail to properly build on Windows #1037

pgrawehr opened this issue Apr 4, 2020 · 6 comments
Labels
area-infrastructure bug Something isn't working

Comments

@pgrawehr
Copy link
Contributor

pgrawehr commented Apr 4, 2020

Describe the bug
Attempting to execute a sample on Windows (within Visual Studio) results in build errors.

This is irespective of the fact that many bindings don't work on Windows, just because the hardware is not there. This is about an ordinary Windows 10 x64 installation on a desktop computer.

Steps to reproduce

  • Perform a clean checkout and do a "build" from the console.
  • Open src/devices/Dhtxx/DhtSensor.csproj
  • Add src/devices/Dhtxx/samples/DhtSensor.sample.csproj
  • Building now basically works, but execution fails with an error from UnixI2cDevice, which shouldn't even be there and definitelly shouldn't be used. So aparently, the linux library is being used. Also, Intellisense / Resharper is not happy and marking all references to System.Device types in red.
  • So add a reference to System.Device.Gpio.csproj
  • This now adds new solution configurations. Choosing "Debug" behaves as before. So we choose "Windows-Debug"
    The build now fails:
1>------ Erstellen gestartet: Projekt: System.Device.Gpio, Konfiguration: Windows-Debug Any CPU ------
1>System.Device.Gpio -> C:\projects\iot4\artifacts\bin\System.Device.Gpio\Windows-Debug\netstandard2.0\win\System.Device.Gpio.dll
2>------ Erstellen gestartet: Projekt: Dhtxx, Konfiguration: Debug Any CPU ------
2>CSC : error CS0006: Metadatendatei "C:\projects\iot4\artifacts\bin\System.Device.Gpio\Windows-Debug\netstandard2.0\ref\System.Device.Gpio.dll" wurde nicht gefunden.
2>Die Erstellung des Projekts "Dhtxx.csproj" ist abgeschlossen -- FEHLER.
3>------ Erstellen gestartet: Projekt: DhtSensor.sample, Konfiguration: Debug Any CPU ------
3>CSC : error CS0006: Metadatendatei "C:\projects\iot4\artifacts\bin\System.Device.Gpio\Windows-Debug\netstandard2.0\ref\System.Device.Gpio.dll" wurde nicht gefunden.
3>Die Erstellung des Projekts "DhtSensor.sample.csproj" ist abgeschlossen -- FEHLER.
========== Erstellen: 1 erfolgreich, 2 fehlerhaft, 0 aktuell, 0 übersprungen ==========

The file "C:\projects\iot4\artifacts\bin\System.Device.Gpio\Windows-Debug\netstandard2.0\ref\System.Device.Gpio.dll" does not exist.

Expected behavior
The above works and correctly builds the sample for windows.

Actual behavior

See above. An error happens.

Versions used
Latest master

Possible solutions
Workaround
The following works:
Replace the lines that include "System.Device.Gpio" in the project files (both the sample project and the binding project) with the following:

<!--Cases used when running in VS, with the solution config either Windows-Debug or Linux-Debug (or -Release) -->
    <ProjectReference Condition="$(Configuration.Contains('Win'))" Include="$(MainLibraryPath)System.Device.Gpio.csproj">
      <AdditionalProperties>$(AdditionalProperties);RuntimeIdentifier=win</AdditionalProperties>
  </ProjectReference>
    <ProjectReference Condition="$(Configuration.Contains('Linux'))" Include="$(MainLibraryPath)System.Device.Gpio.csproj">
      <AdditionalProperties>$(AdditionalProperties);RuntimeIdentifier=linux</AdditionalProperties>
    </ProjectReference>
    <!--Cases used when running build script in other cases. Just pick one -->
    <ProjectReference Condition="'$(Configuration)' == 'Debug' or '$(Configuration)' == 'Release'" Include="$(MainLibraryPath)System.Device.Gpio.csproj">
      <AdditionalProperties>$(AdditionalProperties);RuntimeIdentifier=linux</AdditionalProperties>
    </ProjectReference>

and add the following line (near the top):

<Configurations>Windows-Debug;Linux-Debug;Linux-Release;Windows-Release;Debug;Release</Configurations>

This basically makes sure that, depending on the solution configuration, the correct reference is taken. Make sure the solution configuration now says "Windows-Debug" for all projects when the solution configuration is "Windows-Debug".

Better solution
The better solution would probably be to get rid of the different build configurations and just build one version of System.Device.GPIO that does all its operating-system dependent choices at runtime. (I belive there's a ticket for that already.)

@pgrawehr pgrawehr added the bug Something isn't working label Apr 4, 2020
@pgrawehr
Copy link
Contributor Author

pgrawehr commented Apr 4, 2020

This is the extensive version of my comment here: #1024 (comment)

@pgrawehr
Copy link
Contributor Author

pgrawehr commented Apr 4, 2020

Here's a patch file for the changes needed (with the example above).

0001-Proof-of-concept-to-get-the-sample-to-build-on-windo.patch.txt

@joperezr
Copy link
Member

joperezr commented Apr 9, 2020

Just to give you a bit more background as to why we always pass Linux as the runtime identifier instead of Windows: If you are familiar with reference assemblies, you would know that they are the ones that get passed in to the compiler when building a project but not necessarily the ones that will be present at runtime. The runtime assembly, may have some changes in it as long as they are considered compatible with that reference assembly according to .NET Core's runtime, for example, it is fine to add a base class in the runtime specific assembly, even if the reference assembly didn't have it, this is accepted by the runtime. The reason why all of this is relevant, is because our "reference assembly" needs to be our Linux implementation, because if you have that as the reference assembly, the windows implementation does have some differences but all of them are compatible to the Linux one. The other way around is not true. So this means that if you compile against the windows implementation, and then try to run with the linux implementation, you will hit a bunch of runtime errors because the linux implementation is not API Compatible to the windows implementation. That is why across the repo, we have the ProjectReference to always be linux, so that we build against the linux implementation always, and so that at runtime we won't hit exceptions no matter if you run in Windows.

All that said, this will all go away after we merge your great contribution of removing rid specific configurations, as we won't need to pass in rid as a property any longer.

@pgrawehr
Copy link
Contributor Author

pgrawehr commented Apr 9, 2020

@joperezr Thanks for the clarification, I did not know that concept. The mixing of the different runtimes is something I'm not so familiar with. I assume the above is about our specific library, not about the .NET core runtime. Or would that mean, that even after we remove the specific configurations, the built assembly will be different based on which platform it was compiled on?
Scratch that, stupid question. Apparently you mean that our library has that behavior.

@joperezr
Copy link
Member

joperezr commented Apr 9, 2020

No questions are stupid :) it's better to ask them to understand better 👍

Given .NET Core basically builds into IL, IL is platform independent. The only way .NET Core would behave differently or compile differently for different platforms is if you intentionally make 2 assemblies that will do so, which is what we were doing in this repo. Also, this is not supported by MSBuild, since they only support cross-Framework targeting but not cross-RID targeting, so we had to add a bunch of logic directly here to suport that which is why a lot of things don't work as they should. Hopefully this will be over very soon 😄 when we merge your change.

@pgrawehr
Copy link
Contributor Author

Closing this, as it is obsolete after #1038 has been merged.

@ghost ghost locked as resolved and limited conversation to collaborators Oct 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-infrastructure bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants