Skip to content

CoreCLR msbuild (xplat) support. Initial compilable version. #518

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

Merged
merged 12 commits into from
Sep 21, 2017

Conversation

dmitriyse
Copy link
Contributor

@dmitriyse dmitriyse commented Jul 28, 2017

What does this implement/fix? Explain your changes.

This is initial step in a long road to add "xplat" build tools support into python.net.
...

Does this close any currently open issues?

Not closes but will helps to solve those:
#96

...

Any other comments?

Or even do everything in the master, because this xplat support should be implemented as side-by-side to the current build system.
Later in the branch coreclr2 we can track master and also allow to build NetStandart 2.0 target.
...

Checklist

Check all those that are applicable and complete.

  • [] Make sure to include one or more tests for your change
  • [] If an enhancement PR, please create docs and at best an example
  • [] Add yourself to AUTHORS
  • [] Updated the CHANGELOG

@den-run-ai
Copy link
Contributor

@dmitriyse can you merge *.15.csproj and *.15.sln as options to Solution Configurations next to *Win* and *Mono* options in the regular pythonnet.sln and its projects?

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Jul 28, 2017

@dmitriyse can you merge *.15.csproj and *.15.sln as options to Solution Configurations next to Win and Mono options in the regular pythonnet.sln and its projects?
May be it is possible to use single .sln file (i will try). But it is definitely impossible to fit xplat and classic builds into one csproj file.
Take a look at the first lines of classic a *.csproj and a new *.csproj 2017.

2017:

<Project Sdk="Microsoft.NET.Sdk">

2000+:

<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">

Msbuild and VS uses totally different toolsets for those project types.

@dmitriyse
Copy link
Contributor Author

Also I think we need use only xplat in the future.
It can compile totally all targets, any runtime, any platform, any CLR version.

So current build system should become legacy. But some part of time (migration period) both build system should co-exits.

So current build system and xplat build system should have the same set of solution configurations.
Thus I also think usage of single .sln file is a bad idea (even if is possible).

@den-run-ai
Copy link
Contributor

@dmitriyse can you point to any Microsoft references for understanding about the migration of build systems?

Also have you read this document, which suggests that it is possible to support both runtimes from the same solution?

https://docs.microsoft.com/en-us/dotnet/core/porting/project-structure

@dmitriyse
Copy link
Contributor Author

P.S. Sorry, but I will create PR only for parts that I use in my commercial projects. I have no free time to support xplat build system for all pythonnet targets. But my contributions contain well-tested in the production solutions, and even if some PR is not complete, it can be merged into the main repo to move work forward.

@dmitriyse
Copy link
Contributor Author

https://docs.microsoft.com/en-us/dotnet/core/porting/project-structure

Thank you for pointing. I will review this article, probably there is some better solution than in this PR.

@dmitriyse
Copy link
Contributor Author

image
MS suggest the near the same solution that contained in this PR.
But, if we will do exactly like MS suggest, than current pythonnet build system will completely broken.
So this PR is still relevant.

@codecov
Copy link

codecov bot commented Jul 28, 2017

Codecov Report

Merging #518 into master will increase coverage by 0.87%.
The diff coverage is 94.04%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #518      +/-   ##
==========================================
+ Coverage   76.47%   77.34%   +0.87%     
==========================================
  Files          64       65       +1     
  Lines        5535     5611      +76     
  Branches      889      889              
==========================================
+ Hits         4233     4340     +107     
+ Misses       1014      983      -31     
  Partials      288      288
Flag Coverage Δ
#setup_linux 73.45% <73.17%> (?)
#setup_windows 76.49% <77.38%> (+0.01%) ⬆️
Impacted Files Coverage Δ
src/runtime/runtime.cs 90.98% <50%> (+0.39%) ⬆️
setup.py 89.73% <95.12%> (+18.52%) ⬆️
src/runtime/delegatemanager.cs 88.49% <0%> (-0.11%) ⬇️
src/tests/_compat.py 100% <0%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 4bac694...afc90d5. Read the comment docs.

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Jul 28, 2017

@dmitriyse can you point to any Microsoft references for understanding about the migration of build systems?

Unfortunately, no. I wasn't faced with any one.
I am just sitting on the bleeding edge tools and know what they are really can (or cannot) now.

@den-run-ai
Copy link
Contributor

@dmitriyse
Copy link
Contributor Author

@dmitriyse note that you skipped the first option suggested in that article :)
https://docs.microsoft.com/en-us/dotnet/core/porting/project-structure#replace-existing-projects-with-a-multi-targeted-net-core-project

This is the revolution way. xbuild and old msbuild (prior to 15.x) will fail to build anything.
This would be a huge breaking change for python.net users, and will stress contributors to solve big number of problems at once.
IMO this way is a worst one.

@vmuriart
Copy link
Contributor

I agree w @denfromufa that I'd rather combine the solution files into a single solution. If this means that contributors will need to use VS2017 to build but otherwise it outputs the same, I'm ok with this. Most windows users likely install from pypi anyways.

If combining them creates issues for mono, then I'd hold off altogether. My main concern for it is based on the clean-up I did earlier in the year in which we had 3 or 4 different solution files because of multiple upgrades of VS and then those files lingered around for a long time.
Second problem is that these changes are not being tested at all as part of the CI. If a breaking change is introduced somewhere in the code, we will be oblivious to it for a while.

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Jul 30, 2017

If combining them creates issues for mono, then I'd hold off altogether.

What do you mean ?

If combining them creates issues for mono, then I'd hold off altogether. My main concern for it is based on the clean-up I did earlier in the year in which we had 3 or 4 different solution files because of multiple upgrades of VS and then those files lingered around for a long time.

We can contain one set of csproj files and one sln file only if we totally move to VS 2017/Xplat build system. (And MonoDevelop users should migrate to JetBrains Project Rider. )
This work is too long, thus even in this revolutionary case python.net project should have
two set of csproj files and two sln files, for new and old build system, but in different git branches.

So the choice is between

  1. Avoid NetCoreApp 2.0 target and use workarounds(see later)
  2. use two sets of csproj files in the same branch
  3. some period of time maintain two branches with old and new build systems.

I prefer option 2) - use two sets of csproj files, because option 3) is a different type of hell with merging with even more required efforts to maintain two sln files (and csproj files).

@dmitriyse
Copy link
Contributor Author

NetCoreApp 2.0 offer ability to reference binaries that targets framework 4.6.1 and earlier. I did not try this ability. But in this case existing pythonnet binaries can be referenced to Linux CoreCLR 2.0 projects as is.

But even if this magic is really exists, we needs to duplicate all CI builds for CoreCLR 2.0 hosts.

@dmitriyse
Copy link
Contributor Author

Off topic. I have a bunch of stability&performance fixes for pythonnet/CoreCLR from the high-load production project (Currently they are contained here https://github.com/dmitriyse/pythonnet/tree/pythonnet-plus).

Lacks of official support of CoreCLR stops me from creating pull requests.

@den-run-ai
Copy link
Contributor

@dmitriyse even if we decide together to split into 2 projects/solutions, still this pull request does not include testing for new set of .NET Core DLLs. Can you please add this?

After some more thinking, I might actually incline towards two solutions. The reason is that the current setup.py assumes .NET Framework for Windows, and Mono for other platforms.

But we need a new setup.py that uses .NET Core on all platforms.
Of course we could also add a flag to setup.py to be able to use .NET Core as a non-default option like described here:

https://stackoverflow.com/questions/677577/distutils-how-to-pass-a-user-defined-parameter-to-setup-py

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Jul 31, 2017

Yes, I will try to inject some option in the setup.py to allow build the same output but with xplat build tools and new *.15.csproj + *.15.sln files.
Finally we needs to have 3 times more CI build configurations:

  1. net40 + Current Tools (msbuild < 15.0, mono)
  2. net40 + xplat build tools
  3. NetStandard20 + xplat build tools

Only with this set of CI builds we can ensure that codebase have no regression.

Current PR relates only for new build system. NetStandard 2.0 target should be added by this PR #519

@vmuriart
Copy link
Contributor

@dmitriyse what I meant earlier is due to the fact that Linux users will be building the project alot more often than windows users, so if there's any regressions introduced there because of having a single solution on then I'd rather keep the current solution file.

I'm ok with having the dual solutions as long as we add the CI for them and open an issue to eventually merge them back into one but leave a transition period in which we'll have both solution files in existence.

On the CI, I'm ok tripling the build time for now so that we test out all configurations. After the PR is merged in, I'll rewrite the CI config to test all PY version on one configuration, and then limit the other configuration to subset of them.

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Jul 31, 2017

Eventually we can totally move from mono/msbuild < 15.0 to xplat/msbuild >15,0 and keep all users onboard. Eventually even MonoDevelop/XamarinStudio will obtain xplat/NetCoreApp 2.0 support (The work is in progress http://lastexitcode.com/blog/2016/06/05/AspNetCoreRC2SupportInXamarinStudio).

Thank you for acceptance. I will try to find a time soon to improve setup.py as a part of this PR.

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Aug 8, 2017

Now it's not the same pull requests :).
As I already say, this PR covers only injection of the new build system (xplat).
So we can build just the same output (net40 assemblies) under linux and under windows but with CoreCLR tooling.

New tooling requires completely different .sln and csproj files.

Netcoreapp 2.0 target covered by anther PR.

We needs to ensure that with the same sources and the same build targets new build system works good.
So "step by step".

This is prerequisite step before Netcoreapp 2.0. Because Netcoreapp2.0 can be build only with CoreCLR tooling.

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Aug 8, 2017

On the CI, I'm ok tripling the build time for now so that we test out all configurations. After the PR is merged in, I'll rewrite the CI config to test all PY version on one configuration, and then limit the other configuration to subset of them.

@vmuriart, you can create new CI configs with setup.py build_ext --inplace --xplat build command and CoreCLR 2.0 Preview 2.0+ installed.
(see https://www.microsoft.com/net/core/preview#linuxubuntu
and https://www.microsoft.com/net/core/preview#windowscmd)

Currently --xplat option implementation is just in very beginning, but it passes package restore and build.
(setup.py, *15.csproj , pythonnet.15.sln should be improved, to create the same output as mono and msbuild)

@den-run-ai
Copy link
Contributor

den-run-ai commented Aug 8, 2017

@dmitriyse i don't see --xplat being passed to setup.py in appveyor.yml and travis.yml.

@den-run-ai
Copy link
Contributor

looks like hitting this issue with python 3.6:

pypa/setuptools#1101

@dmitriyse
Copy link
Contributor Author

dmitriyse commented Aug 8, 2017

@dmitriyse i don't see --xplat being passed to setup.py in appveyor.yml and travis.yml.

I did not figure out that I can change build options just in the PR to perform tests, until it's merged to the master.
After some improvements it will be reasonable to perform CI tests.

P.S.
Just before merging to the master we needs to find a way to multiply build configurations (with --xplat and without --xplat).

DEBUG;TRACE fix for the case VS + non empty PYTHONNET_DEFINE_CONSTANTS
…troduced. + Fix for building mono versions under windows.
"""Return full path to one of the Microsoft build tools"""
try:
basePathes = subprocess.check_output(
["vswhere", "-latest",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmitriyse can you change this to tools\vswhere\vswhere.exe like I did in my pull request #540?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added tools\vswhere\vswhere.exe file into the repository instead of chocolatey installation.
See PR #546

_custom_define_constants = False
elif DEVTOOLS == "dotnet":
_xbuild = 'dotnet msbuild'
_config = "{0}Mono".format(CONFIG)
Copy link
Contributor

@den-run-ai den-run-ai Sep 13, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dmitriyse why dotnet DEVTOOLS corresponds to Mono _config?

Copy link
Contributor Author

@dmitriyse dmitriyse Sep 21, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first problem:
DebugMonoPY3, ReleaseMono, etc. build configuration is a historically names from times where nothing than mono had exists for the linux.
Now it is more correctly to name DebugLinuxPY3, ReleaseLinux, etc.

But we "cannot just rename" build configurations without affecting users.
We should introduce new build configurations (DebugLinuxPY3, ReleaseLinux), give a time to users to migrate to new names, and than remove old names DebugMonoPY3, ReleaseMono, etc.

The second problem:
We cannot use dotnet build command under windows due to DllExport project msbuild targets. We needs to use msbuild >=15 under windows

The result:

DEVTOOLS=dotnet ==> linux (--xplat) === ReleaseLinuxPY3 <== ReleaseMonoPY3

So currently we have DOVTOOLS=dotnet <===> ReleaseMonoPY3

If I am wrong in somewhere in my conclusions, lets improve something.

@den-run-ai
Copy link
Contributor

den-run-ai commented Sep 13, 2017

@dmitriyse you mentioned that you are not using MonoDevelop, how are you testing these 2 solutions on Linux and OSX? Are you using Rider IDE on these platforms?

I tested and both solutions look good on Windows in VS 2017, just don't try to open both solutions at the same time :)

@den-run-ai
Copy link
Contributor

@dmitriyse can you please avoid a lot of duplication in travis.yml in the matrix by using excludes?

https://docs.travis-ci.com/user/customizing-the-build/#Excluding-Jobs

Copy link
Member

@filmor filmor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This works for me, denfromufa is right about the matrix thing, but that can easily be added in a new PR. Let's go ahead and merge this first.

@filmor filmor merged commit 4b381bf into pythonnet:master Sep 21, 2017
@den-run-ai
Copy link
Contributor

@filmor @dmitriyse note that some comments are still not addressed:

#518 (comment)
#518 (comment)
#518 (comment)

@dmitriyse
Copy link
Contributor Author

I will "address" those today. Please sorry for delay.

@dmitriyse
Copy link
Contributor Author

Answering to the #518 (comment)
Unfortunately travis-ci currently does not supports conditional "addons" section.
See travis-ci/travis-ci#3618
So exclude solution is totally impossible now and in near future.

But fortunately we have a little yaml reference sugar, I will try to apply it.

@dmitriyse
Copy link
Contributor Author

I was managed to solve copy-past .travis.yaml problem with help of yaml references Solution is included into #546

@dmitriyse
Copy link
Contributor Author

@dmitriyse you mentioned that you are not using MonoDevelop, how are you testing these 2 solutions on Linux and OSX? Are you using Rider IDE on these platforms?
I tested and both solutions look good on Windows in VS 2017, just don't try to open both solutions at the same time :)

I tried Project rider 2017.1.2 for the pythonnet.15.sln and...
It's unbelievable:

  1. I am successfully build, run, debug, and run/debug unit tests for .Net 4.0
  2. I am successfully build and run CoreApp 2.0 target, but unable to debug it and unable to run/debug NUnit tests

Probably full support will be added soon.
image

But in general Project rider works great and looks like a very mature tool.
RIP MonoDevelop. (Nothing personal, this product played big role)

P.S. some fix for better usability inside IDEs are added to #546

@dmitriyse
Copy link
Contributor Author

We can advertise full migration to --xplat in the 2.5 release. IDEs already can handle development in any OS.

testrunner123 pushed a commit to testrunner123/pythonnet that referenced this pull request Sep 22, 2017
…et#518)

* Full featured xplat build.

* .Net 45 TargetingPack System.XML.dll naming fix. (For xplat linux build).

* Setup.py --xplat option refactored. Travis-ci build matrix extended.

* AppVeyor matrix extended, xplat build added.

* appveyor.yml yaml syntax fix.

* NUnit dependency upgraded to 3.7. Changelog improved.

* Build order improvement.

* Mono builds now can be build on Windows.
DEBUG;TRACE fix for the case VS + non empty PYTHONNET_DEFINE_CONSTANTS

* PYTHONNET_PY3_VERSION, PYTHONNET_PY2_VERSION build related environment vars introduced.

* Small compile fixes.

* PYTHONNET_WIN_DEFINE_CONSTANTS and PYTHONNET_MONO_DEFINE_CONSTANTS introduced. + Fix for building mono versions under windows.
dmitriyse pushed a commit that referenced this pull request Nov 16, 2017
dmitriyse pushed a commit that referenced this pull request Nov 16, 2017
dmitriyse added a commit that referenced this pull request Nov 16, 2017
@dmitriyse dmitriyse deleted the xplat branch November 17, 2017 07:36
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.

4 participants