Including wxWidgets headers in windows and macOS builds

I have been using wxPython for ~8 years on a project that we’ve only supported on Linux but now want to also support macOS.

We started out with our own build of wxPython (and all of it’s deps) but switched to using conda in 2015 and have successfully been using the conda-forge or defaults build of wxPython since then.

Our project includes Cython code that needs to have the wxWidgets headers and link against the wxWidgets libraries and we also utilize the wx-config helper program to get the correct flags and paths for our builds. All of that has been fine on Linux because the headers and wx-config are included in the pip install (which conda-forge uses).

On macOS, it looks like the wxWidgets dynlibs get put next to the python modules in site-packages (to aid in locatability) and the wxWidgets headers and wx-config aren’t included.

I’d like to tweak the conda-forge recipe so that it installs the wxWidgets headers and wx-config and also locates the dynlibs at the root of $PREFIX/lib where any respectable c++ build will look for them.

I’m planning to dive into your build.py and figure this out. However, if you have any tips or suggestions, I’d really appreciate them.

Thanks!

BTW, the conda-forge recipe issue related to this is at https://github.com/conda-forge/wxpython-feedstock/issues/28. Feel free to reply here in your Discourse. I’m just cross-referencing. :slight_smile:

The wxWidgets source tree is located in the wxPython source at ./ext/wxWidgets. After the wxPython build on OSX you can find the results of running the wxWidgets configure script (as well as the compiled object files and libs) is located in ./build/wxbld. The stuff you’ll want to grab from there includes the wx-config script, some supporting scripts and the configure-built setup.h file. Look at ./build/wxbld/lib.

On Windows the wxWidgets build takes place inside the wxWidgets folder, so you can fetch the headers from ./ext/wxWidgets/include.

Thanks Robin. I’ll let you know how it goes.

Robin, I realized that he conda-forge recipe has been using --no_magic when building for linux. I’ve been able to get the same behavior on macOS by also using --no_magic there.

However, if we want to include the wxWidgets libraries and headers on Windows, build.py has explicit use of magic on Windows and also refuses to install_wx on Windows.

Can you help me understand why build.py won’t install_wx with --no_magic on Windows? If I’m able to make changes to build.py for my usecase, would you consider taking a PR upstream?

The main thing is that there is no equivalent standard concept of installing a library and headers on Windows as there is on posix platforms. There is no standard location for libs and headers that any random other application or library can expect to be able to look at to find the libs and headers. In the case of wxWidgets the typical use is to build it in-place, (in the wxWidgets source dir) and then the application developers will add those locations within the wxWidgets folder to their own projects so their build can find them there.

So for wxPython the only generally useful option is to copy the wxWidgets DLLs into the wxPython package folder. That is basically what the default “magic” option is for the other platforms, except on WIndows it’s not so much “magic” as it is “normal”. Since there isn’t an equivalent to doing a system install, then the use_syswx option is also ignored on Windows. If the wx DLLs are installed somewhere else then that location would need to be on the PATH, but putting them in the same folder as the .pyd extension files means that the PATH does not need to be modified.

My expectation for including the wx headers in the wxPython wheel would be that they are put into the include folder alongside the wxPython folder already put there. If something else needs to happen for conda compliance on Windows then I’ll happily review a PR for build.py modifications.

Thanks Robin. Your explanation makes a lot of sense. Can you tell that I don’t develop on Windows? :slight_smile:

NOTE: I’m going to post this reply without any hyperlinks because the site is giving me “you cannot post a link to that host” dialogs when I try to submit my post. I’ll submit it without any links and then go through and add them one by one.

If you would like to review and/or comment on the changes I’m proposing for the conda-forge recipe for wxpython and wxWidgets, the GitHub PR is https://github.com/conda-forge/wxpython-feedstock/pull/46

Conda’s current approach for shared libraries in packages is to put them into a directory structure under $PREFIX/Library as explained in the conda-build documentation. The DLLs go into $PREFIX\Library\bin and that is added to PATH when the conda environment is activated.

I looked at modifying the wxpython or wxWidgets build scripts but ended up deciding to create a standalone install_wxwidgets.bat script that will be used to install wxWidgets on Windows. It could be possible to create configure options for the different artifacts that need to go to different locations in the conda package but I’m not an autotools nor nmake expert and install_wxwidgets.bat seems like a reasonably robust way to install the wxWidgets artifacts where conda users would like them to be.

I’m also remembering that I have added [a patch that allows --no-magic to be used on Windows](look for recipe/patches/0004-enable-use-of-nomagic… in my PR) but that might be able to be removed or at least modified to not have the changes to the install_wx command because it will not run correctly on Windows with the changes I made.

Update: looking more at the wxpython build.py, I still want to be able to specify --no_magic or --use-syswx so that copyWxDlls() will early-exit and not create a duplicate copy of the DLLs in the wxpython directory. I am going to remove the change to install_wx though.

I’ve also uploaded copies of the new packages for Python 3.7 on Windows and MacOS to my personal anaconda channel at: MY CHANNEL URL. If you would like to install the example packages, you create a ‘wxpython_tsnyder’ environment by running:

conda create --strict-channel-priority -n wxwidgets_tsnyder -c tsnyder -c conda-forge wxpython

Of course, running that conda command assumes that you already have conda installed. The easiest way to do that is with [miniconda3 installer](just google search for miniconda)

Now I’m hitting “new users can only add two links” to a post. I’m going to pick the most important two and leave it at that. :slight_smile:

Discourse automatically flags messages as needing moderation when various criteria are met, in order to try to block spam. In this case it appears to be “new user” and “too many links to same domain”. I’ll check if we can white-list some domains… Also, the messages are put into a moderation queue where I can allow them through if they’re okay.

I completely understand and there’s no hard feelings on my end. Just wanted to explain what I was running into so that you understand the many notifications regarding my single post. Thanks again for your help tweaking the conda-forge package.