-
Notifications
You must be signed in to change notification settings - Fork 61
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
Update build system to allow for building Python wheels #614
Conversation
…and installable Python wheels.
…lation size) and replace it with a module that raises a deprecation warning.
…d be generated AFTER the generated message files.
… not find the system-installed one.
…ctly by CMake on Conan 1.60.
… reset (by `InitializeSimulation()` and the data is cleared, causing a silent failure in some scenarios (reproduced in some environments on `scenarioDeployingPanel.py`).
@patkenneally I heard you were interested in build system related changes, so tagging you here. My apologies if I'm mistaken! |
Hi Dan @dpad , thank you for your clearly hard work and impressive result here. And yes, thank you for tagging me I'm very interested in build changes. It's ripe for improvement at the moment. We all forward to working through a review of it. With that in mind my, and in keeping with our process for submitting and reviewing PRs (I admit not always the clearest) my proposal is that we break up this very large PR into many separate ones (where appropriate) that can be reviewed on a per issue change. You are likely already familiar with the project's information regarding contribution, but if not it's available here at the contributions page. In particular the three articles linked a the bottom of that page really capture what is being pursued. In short, our goal is for PRs to address a single scoped change. This allows for more thorough and manageable reviews. For each change we will no doubt want to discuss the approach taken, the use cases which the proposed changes support, and their ultimate appropriateness to the project. I have no doubt you've given it all great thought and so I'm happy to help break the pieces up, account for other changes possibly needed to support, and eager to read through over the coming weeks. |
Howdy @dpad , thanks for sharing this PR. As Patrick says, a lot of work went into this, creating a rather complex PR. You state yourself this PR still is causing some crashes and issues. I second his request to break down this large PR into discrete chunks that can be put on individual branches and associated PRs. This way we can iterate on each PR to ensure we are all happy with that step and no issues have come up. |
Regarding making pip wheels, how did you get around the issue that the wheel is compiled against a particular version of python? You mention yourself that not all co-workers were able to use |
@patkenneally @schaubh Thanks very much for your comments and your support! Building Python wheelsFor your reference, CI run is available here: https://github.com/dpad/basilisk/actions/runs/7967368431 Basically, I am building wheels for each platform + Python version combination. There are 12 such combinations as per the CI above. This is a pretty standard thing to do for similar packages, for example if you look at To be clear, my CI setup is testing Linux, Mac (x86_64), and Windows (2019) for Python 3.8~3.11. Seemingly randomly, it seems the Python 3.8 MacOS build sometimes fails a single testcase (out of ~2700 testcases) due to some weird stack overflow issue that I mentioned above. In addition, Python 3.12 builds seem to run into a couple of segfaults on a very small subset of testcases (I suspect this is a deeper issue or possibly bugs in Basilisk and/or SWIG), and therefore I do not build for 3.12 in CI. Similarly, the "windows-latest" image also runs into similar segfaults on a very small subset testcases -- so I am building on "windows-2019" instead, which is what the current Basilisk CI does. For comparison, the current Basilisk CI only runs a Python 3.9 build on Linux and Windows, with lots of additional environment set-up necessary, and doesn't run every Python test (only the "not scenarioTest" ones). Building wheels in the futureBy the way, I am also working on a separate branch which leverages the new SWIG 4.2 support (many thanks @schaubh !) to build using the "Python Limited API". This would basically allow us to build a single wheel for each platform, which would then theoretically work for any Python 3 version (at least from Python 3.8+). The main benefit is reducing the total amount of CI resources spent building wheels, and most users using the same single built artifact. I believe we can get this to work, but I'm currently running into some issues mainly on the Windows side. Issues with installing Python wheels (MacOS)Regarding the issue of different versions not being installable by my colleagues, basically this is only an issue I've observed with Mac. I myself have zero experience with Macs in general or building anything for them, but what I've learned is that you need to first set some deployment target version to 10.13 in order to build Basilisk correctly (that seems to be the minimum which I can get to build). This ends up building a Python wheel which is tagged with a deployment version, for example for Python 3.8 it is tagged like But in any case, regardless of not being able to install these pre-built wheels, those users can still build and install Basilisk manually themselves by just calling Summary of changes for reviewOf course, I understand the need for smaller changesets to help ease the burden of reviewing. Instead, I can provide a summary of the changes below to aid your review:
|
hahaha this would explain what nuked our git-lfs quota in the last week. Building for multiple wheels won't be feasible unless we remove git-lfs contents. I have also wanted to matrix the CI across python versions but using git-lfs makes this cost prohibitive. But a clear solution is to remove spice kernels from the repo. I've been a fan of removing kernels from the repo for a while and we can provide download via other means. I appreciate the integrated nature of some of these changes, however, I can spot a number of places where changes can be broken out and will take a look at doing so. I'm hesitant to approve such a large change set and so will look to chunk it up. I appreciate the write up above. |
@patkenneally Oops, I'm not sure if that was due to me but if so, my apologies! I would not have expected any changes I made to my own fork to affect any quotas set on the main repository :/ Regarding having a CI matrix with Git LFS, I have a branch that's still WIP over on dpad to build Basilisk using the Python limited API: https://github.com/dpad/basilisk/tree/basilisk/build-python-limited-api And yes please, if you are willing to extract some changes out please do feel free to take over. I won't be making any further changes on this branch (going to use it as is for our internal purposes for now), but I'm happy to answer any questions if you run into any problems. |
Sounds good. I will pick out chunks and check in with you as we go. I appreciate you sharing this work back to the community. There are a number of features in your branch that I've been poking at in the scraps of free time. So this is great. Any time you clone a fork of a repo, the git-lfs contents are pulled from the root repository and count against the root repo's git-lfs bandwidth quota. So any CI running on forks count against the root repo's quota. No worries though. I think the appropriate solution is to remove the kernels from git-lfs and have them downloaded by conan or cmake from other source/storage locations. |
@patkenneally I thought I'd check in on this to see whether there are any updates or progress from Basilisk side? For your reference, I have been using this proposed system, with only minor modifications, successfully across several different Linux machines with Python 3.8~3.11. I think we can maybe split up this work to make it a bit easier to merge into individual pieces like this:
|
Howdy @dpad , thanks for the follow up and good news that your approach has been running successfully on a range of Python systems on Linux. Patrick's focus has been his on fork of Basilisk and I'm not aware of any work on your PR. I did take a look at your PR a few weeks ago to see how this could be integrated. I agree with you that this PR needs to be broken up into smaller PRs where we can test and review each update across all platforms, build versions, etc. You mentioned in the original post that there some issues with some scripts. I'm glad to offer to work with you on testing and reviewing these branches to integrate these features into Basilisk. Doing these on public branches will allow other stake holders to review each step. Regarding the order of proposed your branches, I will follow your lead as you know what upgrades are required by subsequent upgrades. Getting conan 2.0 compatibility is nice, but I'm very excited about the prospect of building BSK wheels that can be installed readily by users just looking to use BSK, not develop for it. This will open up drastically access to BSK to students in classes I teach, researchers trying out BSK to evaluate it, and many more. Thanks for working on these improvements. Let me know if you are ok to take the lead breaking up your earlier PR into individual branches and associated PRs. |
@dpad Like Dr Schaub's mentioned, this development is very important and it would be great to split this into multiple PRs. I will be happy to help out, especially with Basilisk-specific errors, since it seems you have a very good handle of the build system itself. I normally use a windows machine, and Dr Schaub uses MacOS, so we can help you debug those. Also, feel free to add me as reviewer to these PRs (and ping me, if needed). Very excited for this! |
I would like to close this in favour of #737 . There are some additional bits of work in here, but they can and should be done later in separate merge requests. |
pip
as a subprocess from the Conanfile)pip install Basilisk
Description
This change modifies the build system to address several short-comings and bring it up to speed with some more modern Python packaging standards. The results are summarised below:
pip install Basilisk
. I'm leaving this for the maintainers to setup.pip
now callsconan
, instead of the opposite):pip
) -- thanks to newpyproject.toml
file.setup.py
takes care of all dynamic information, including calling the underlying Conan build system.pip
, everything is built automatically within isolated temporary build environments.opNav
) and tests are now done in CI for 64-bit Linux, Mac, and Windows.Verification
Basilisk is now built by CI on three platforms (Linux, Mac, Windows) and with all supported Python versions (3.8~3.11). In addition, I have personally tested building Basilisk on Windows and Linux, as well as downloading and installing the wheels built by the CI runners. I have also had colleagues test building on Mac.
It all seems to work, but I of course would love it if the maintainers could try building it themselves to iron out any remaining issues. I'm sure there are probably some weird incompatibilities, but I tried to keep the dependencies as close to the old ones as possible. I did remove some old workarounds (mainly in the Conanfile) that I felt were no longer necessary, but I might have missed some special cases where they're still necessary, so might be worth checking that. In any case, being able to build wheels means that we can avoid users having to compile Basilisk at all (so long as their platform matches one of the wheels we build).
I also tested running the build manually using an old Conan (1.60) version, and it works, although I would recommend deprecating this and not supporting it at all going forward. By default,
pip
will download and use Conan 2.0+ for the build.Documentation
Need to update the installation instructions for all platforms. I haven't updated the documentation and will leave it for the maintainers for now. The biggest differences are described below:
pip install .
orpip install -e .
(editable)EXTERNAL_MODULES
.EXTERNAL_MODULES=/path/to/my/modules pip install .
CONAN_ARGS
.CONAN_ARGS="-o opNav=True" pip install .
setup.py
.)conan
1.60+ or 2.0.5+ manually (e.g. you can just callconan build . --build=missing
), but you can't easily pip install the built artifacts (at least in any easy way that I know). Might need to generate a fakedist3/Basilisk/pyproject.toml
file to support this.setuptools
,parse
, and SWIG are now all build-time dependencies installed automatically by pippip>=22.3
is required to initiate the build (see the check insetup.py
for reasons why)supportData
folder to be insidesrc
(this is to match the recommendations given by the Python packaging tools), and I updated all relevant breaking tests but maybe you also need to update some documentation about this.Future work
Bugs
test_orb_elem_convert.py
tests.pythonVariableLogger.__getattr__
? Tests seem to pass if I add a simple debug print of theself._variables
at the top of that method, and fail if I remove the debug print.windows-latest
.windows-2019
as per the existing Basilisk CI.Further Improvements
twine
) -- should be prepared by the maintainers.CMAKE_OSX_DEPLOYMENT_TARGET = 10.13
to get things to compile, but the wheels get built withmacos_11_0
platform tags, which for some of my colleagues don't work (their Python listsmacos_10_9
and complains of the wheel being incompatible). Someone with a Mac should look into this more.distutils
plugin (and associated CLI script) to Basilisk which would let a user compile their custom module from their ownpyproject.toml
, something like this:cibuildwheel
plus the Python limited API to build a single wheel for each platform (Mac, Windows, Linux) that can be used across any supported Python version.