Providing pre-compiled binaries
karimbahgat opened this issue · comments
One of the recurring issues I've seen in the past among users of aggdraw has been with the lack of precompiled binaries and the difficulties and errors relating to compiling.
With this as the new aggdraw for the future, it would be a very good thing for usability to provide precompiled binaries in the form of wheels on the PyPI site so that it can easily be installed via pip install aggdraw
without requiring the user to have a compiler and all the errors that can arise from that.
While I am not against wheels, my typical route for getting prebuilt binaries is to use conda. aggdraw
is available on the conda-forge
channel and due to the way conda works these are all pre-built binaries for all Windows, OSX, and Linux.
If this project was to add wheels I would like it to happen on the CI side (travis and appeveyor) however when I looked at linux wheels for another project I had trouble understanding how to get it to work on travis as a "manylinux" wheel. Any help would be much appreciated.
Good to hear aggdraw is precompiled for Conda. I'm not familiar with Conda, but my impression is it's one of several frameworks, and used by a specific type of users. For those users not using Conda I think it would be worth adding as wheels.
As for building the wheels automatically via Travis, that sounds perfect. I have recently been getting more into Travis CI, but didn't know it could do that. Given that they provide this feature, it seems that it should at least be feasible. I may try to look at it at some point down the road, unless someone with more experience jumps in first.
Conda is by design all binary. It is heavily used in the scientific python community. You can easily get a python environment on Windows, Mac, and Linux. And anything that isn't available can be installed with pip. I highly recommend looking in to conda and the conda-forge channel, especially to reduce the amount of pre-compiled bundling of third-party packages.
The hard part, if I remember the last time I looked at wheels on travis, was configuring whatever special stuff had to be set for manylinux wheels to be made.
Just commenting to note that I have a vested interest in seeing pre-compiled aggdraw wheels up on PyPi as well: at present, installing aggdraw on Windows requires a working C compiler, which requires users to install a special Python compiler from MS for 2.7 and some form of Visual Studio for 3.x, both of which make supporting software that uses aggdraw on Windows machines significantly more difficult. It also requires the install of Xcode CLI tools on macOS, which isn't a problem for most programmers or Homebrew users but adds an extra hurdle for many end users.
While you're still figuring manylinux wheels out, would it be possible to get Windows/Mac wheels building with Travis CI in the meantime? I unfortunately don't know much about CI environments, but I'm willing to put some work into researching the manylinux process and finding examples of how others have done it if that'll help things along!
Yes I am open to releasing the binaries for Windows/OSX before manylinux gets figured out. If anyone is willing to look in to how to do OSX wheels on travis and appveyor I'm willing to accept PRs or try them out on a separate branch for testing. Just give me ideas. Actually OSX might work out of the box on travis just have to limit the deploy so it doesn't try to build/upload the wheel for linux.
Have you taken a look at cibuildwheel before? It looks like it makes building wheels for all platform/arch/version combos easy and takes care of uploading to PyPi for you.
EDIT: It looks like it needs Appveyor to do Windows builds, only macOS and linux (with the manylinux docker machine) worth with it and Travis CI. Still, might be a useful starting point.
I had not heard of that before. My main concern would be that it seems to assume our environments are using the system python that travis/appveyor may be providing. That is not the case for aggdraw since we use astropy's ci-helpers.
Okay, so I had some free time over the past two days and tried my hand at getting this working. I've only just started on the Appveyor side of things (Windows cmd/PowerShell isn't my forte as a UNIX guy), but based on some other projects I've managed to modify the travis-ci.yml such that it runs (and successfully builds/tests) both the cibuildwheel and astropy ci-helpers builds, meaning we get binary wheels for macOS, 32-bit manylinux, and 64-bit manylinux for 2.7, 3.4, 3.5, 3.6, and 3.7 for PyPi and the macOS/Linux Conda-based 2.7 and 3.7 builds that were there before: https://github.com/a-hurst/aggdraw
I've ignored the automatic deployment/uploading stuff for now, since I didn't want to accidentally upload any files from my testing attempts anywhere, but from the look of the cibuildwheel README it seems like it supports automated uploading of all wheels is easy with a bit of configuration.
Also, just for my own understanding: is the astropy ci-helpers script uploading the built binaries to Anaconda Cloud? There doesn't seem to be any 'deploy' code expressly related to it so I'm not entirely sure how it's supposed to work. If it does handle that itself, I think that makes things easier on the cibuildwheel/pypi front.
Very cool. I have a couple questions, but first I'll answer yours: ci-helpers is only for creating a conda environment for running tests. It doesn't do anything for building the package distribution or uploading it. As for uploading accidentally while you test, I don't think it will since you don't have permission to do the upload. Now my questions:
- Is it possible to limit when the build environments are run to only tagged environments on the main repository? You can see this in the current master branch using travis's deploy logic (tags: true, repo: pytroll/aggdraw).
- If 1 above can't be done then what about only uploading in these situations?
- It looks like
cibuildwheel
requiresTWINE_PASSWORD
to be the unencrypted password in the travis settings (pypa/cibuildwheel#20). This is not ok with me. This repository and its CI environments are shared by all pytroll maintainers. To upload as my user would require showing my password to everyone that is a maintainer of the project. - Related to 3, it looks like I might be able to use the encrypted password directly in travis but I would have to do this after you make your PR. https://docs.travis-ci.com/user/encryption-keys/#usage
- How do you handle installing freetype? We would want freetype included in the wheels right?
1/2. Based on the example of cibuildwheel auto-uploading I found, it looks like it's set to upload only when a new tagged release is uploaded. If you added a new git tag for every version number you wanted to auto-upload, it would only do it for those ones and just test the rest.
3/4. The example suggests doing the latter (putting the password as a Travis/Appveyor variable), which probably makes the most sense here too. Given that it won't auto-upload anything anywhere until a release with a new tag is pushed, it should be fine to just leave the password until after the PR since it won't try and do one right away.
- No clue how this is handled on the Windows/Appveyor side of things, but to my understanding for macOS/manylinux, library dependencies are included when necessary automatically using delocate (Mac) and auditwheel (linux). In the build logs on TravisCI it shows it linking/including FreeType somehow during the build process.
Okay, I have cibuildwheel working beautifully with Appveyor now but the conda builds aren't working for some reason (looks like a problem with the environment not loading right: it complains numpy isn't installed even though it clearly is from earlier in the logs). Anyway, since you're doing the uploading of those manually, would it be possible to just use cibuildwheel for the time being and get auto-uploading of conda builds working at a later date?
Also, regarding FreeType inclusion on Windows, it looks like it's currently being built without FreeType support. Since there doesn't seem to be any equivalent of delocate or auditwheel for windows that automatically copies any used libraries a wheel depends on inside it and fixes the links, I think we would either have to include the .dll in the wheel somehow or just require users to build from source if they want FreeType support. The latter is easiest, but the former is certainly ideal, so I guess we'll have to look into that further.
@a-hurst I think there's been a misunderstanding. The conda environments that existed before are for testing only. The conda packages built and made available on conda-forge are all handled by conda-forge here: https://github.com/conda-forge/aggdraw-feedstock
There are no conda recipes for building a conda package in this (pytroll/aggdraw) repository.
Make your PR and we'll see how it goes.
Although there’s not much i can contribute atm, good work and very excited about the efforts/activity on this! My only two cents would be on the freetype: def agree freetype needs to be included. If everything else is figured out i would say push ahead with the general automated build system first to get it started, and rather try adding freetype later on.
Just made a pull request (#39) with ci-helpers and cibuildwheel finally coexisting peacefully for both TravisCI and Appveyor, including the twine code for auto-uploading all wheels to PyPi when a successful cibuildwheel build is made for a commit pushed with a git tag (see full instructions here)
Freetype is still missing on Windows, unfortunately, but I'm in agreement with you both that it's something best tackled as a separate issue.
@a-hurst I merged your PR and tagged a rebuild of 1.3.7. There are now wheels on PyPI!
However, I don't think freetype is linked in the linux builds. My OSX system seems like it finds at least some version of freetype:
$ otool -L aggdraw.cpython-36m-darwin.so
aggdraw.cpython-36m-darwin.so:
/opt/X11/lib/libfreetype.6.dylib (compatibility version 19.0.0, current version 19.6.0)
/usr/lib/libstdc++.6.dylib (compatibility version 7.0.0, current version 104.1.0)
/usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.0.0)
But on linux (CentOS 7):
$ ldd aggdraw.cpython-36m-x86_64-linux-gnu.so
linux-vdso.so.1 => (0x00007fff099f3000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f77ba0a8000)
libm.so.6 => /lib64/libm.so.6 (0x00007f77b9da6000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f77b9b8f000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f77b9973000)
libc.so.6 => /lib64/libc.so.6 (0x00007f77b95a6000)
/lib64/ld-linux-x86-64.so.2 (0x00007f77ba5ea000)
Any ideas?
Hmm, my guess is that the official manylinux Docker image (CentOS 5) that cibuildwheel uses doesn't have a version of freetype preinstalled, so setup.py doesn't find it and thus doesn't include it in the build.
Based on my quick search the latest FreeType version for CentOS 5 is 2.2.0, so if aggdraw requires a newer version it'll need to be installed from source prior to the build with a shell script or something.
I don't think there is any minimum freetype version. Just looks like it wasn't present in the docker image. Aggdraw likely requires the -dev
package/headers though. Any idea what we would have to do to get those available in the build process? Should we post to a mailing list and ask someone else for help?
I mean, it’s probably worth a shot just trying to install the old packaged version and seeing if it works. Adding ‘yum install -y freetype-devel’ under the TravisCI environment variable “CIBW_BEFORE_BUILD_LINUX“ should make it install freetype before trying to build the wheels.
@a-hurst I did as you suggested, made a PR, merged it, and it seems like the wheels for the 1.3.8 release of aggdraw now has wheels for all platforms and linux and OSX wheels include freetype. Thanks for all your work on this. I'll try to announce it on various platforms later.
@djhoese Glad to hear it worked! And you're very welcome, thanks for being so responsive as a maintainer. Having PyPi wheels means I can officially support Python 3 under Windows now, and brings me one step closer to being external-dependency-free on all OSes.