-
Notifications
You must be signed in to change notification settings - Fork 7
cmake: modernize CMake infrastructure; adds modules, bindings; build Windows wheels #21
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
base: master
Are you sure you want to change the base?
Conversation
|
@ketiltrout and @arahlin, sorry to drop this on you before the holidays. This is a follow-up to #20 (and includes both series of commits). |
667f835 to
ccccf8e
Compare
… iterating Without this poison, the following tests segfault: 1426 - test_trunc (SEGFAULT) 1427 - test_trunc_dir (SEGFAULT) 1429 - test_trunc_truncsub (SEGFAULT)
…arch() This has no impact on the current codebase, but in a future commit we'll be adding Windows support (which means backslashes, which need to be escaped.)
We now have two Python packaging/backend combinations: - setup.py: setuptools, invoked explicitly by the autotools build, and - pyproject.toml: scikit-build-core, invoked by the cmake build It's slightly awkward having these two coexist side-by-side, but the two build systems already do that.
…n warnings Since cmake on Windows unconditionally defines GD_C89_API, Windows otherwise gives us warnings like: \path\to\alter_crecip89.c(22,9): warning C4005: 'GD_C89_API': macro redefinition
This works within GCC but not within MSVC, and the c++ preprocessor documentation (see 16.3.4 in N4594) seems to disavow this behaviour.
Now that CMake generates gd_config.h (consistent with the automake flow), this macro was redundant and can be safely removed.
Squashes the warning: Warning: cibuildwheel: Invalid skip selector: 'cp36*'. cibuildwheel 3.x no longer supports Python < 3.8. Please use the 2.x series or update `skip`. This selector will have no effect. Warning: cibuildwheel: Invalid skip selector: 'cp37*'. cibuildwheel 3.x no longer supports Python < 3.8. Please use the 2.x series or update `skip`. This selector will have no effect.
ccccf8e to
1da0110
Compare
| dynamic = ["version"] | ||
|
|
||
| [tool.setuptools] | ||
| script-files = ["../../util/dirfile2ascii", "../../util/checkdirfile"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These utilities are actually quite useful to include in the wheels if possible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, halfway there. The wheels now
- produce a python module that's dynamically linked,
- include the corresponding .so/.dll, and
- include whichever of these two utilities can be compiled on the platform.
Unfortunately, two limitations
- dirfile2ascii uses getopt_long, which is unavailable on Windows, and
- pyproject.toml only allows Python scripts to be installed (via [project.scripts]), so for these binaries to be visible in PATH, we'd need to create Python wrappers for them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am losing all steam on making the windows build work, to be honest. I'd just turn the utils off on the windows build altogether. For the linux/osx builds, I think you can tell cmake to install binary files in the top level bin directory (something like install(<target> DESTINATION bin)) inside the wheel package, without any additional content in [project.scripts]. Does that work?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps ${SKBUILD_SCRIPTS_DIR} is what you want? https://scikit-build-core.readthedocs.io/en/latest/guide/cmakelists.html#install-directories
cmake/gd_config.h.in
Outdated
|
|
||
| /* Package information */ | ||
| #define PACKAGE_NAME "GetData" | ||
| #define PACKAGE_VERSION "0.11.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be able to pick this up from the PROJECT_VERSION cmake variable I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup - see d626c9. This parses version strings from m4/version.m4 - which is pretty clunky, but functional.
cmake/CMakeLists.txt
Outdated
| cmake_minimum_required(VERSION 2.6.4) | ||
| cmake_minimum_required(VERSION 3.15) | ||
|
|
||
| project(getdata) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should include a version here. Perhaps also some logic for whether this is run by scikit-build or manually.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Similarly, d626c9. For the scikit-build vs. manual thing - what do you have in mind?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scikit-build-core uses setuptools-scm to get the version number. I think you probably want to use that package name and version in the CMakeLists file if you're triggering it from the pyproject file, and otherwise fall back to the m4 parsing. Perhaps something like this:
if (SKBUILD_PROJECT_NAME)
project(${SKBUILD_PROJECT_NAME} VERSION ${SKBUILD_PROJECT_VERSION})
else()
<parse m4/version.m4 here...>
project(getdata VERSION ${GETDATA_VERSION})
endif()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This way you can use a single PROJECT_VERSION cmake variable everywhere else, which is set by the above project() call.
b8e92dc to
5f66b02
Compare
5f66b02 to
f7099e1
Compare
This is a little clunky but reduces the number of redundant places where the version numbering must be updated.
| CIBW_REPAIR_WHEEL_COMMAND_LINUX: > | ||
| LD_LIBRARY_PATH=$PWD/src/.libs auditwheel repair -w {dest_dir} {wheel} | ||
| CIBW_REPAIR_WHEEL_COMMAND_MACOS: > | ||
| DYLD_LIBRARY_PATH=$PWD/src/.libs delocate-wheel --require-archs {delocate_archs} -w {dest_dir} -v {wheel} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure these repair wheel command tweaks are not needed for linux and osx? IIRC I've had to set the library paths by hand like this for the repair tools to find the shared libraries and set RPATH correctly.
| yum install -y bzip2-devel flac-devel xz-devel pcre-devel zziplib-devel && | ||
| .github/workflows/bootstrap.sh --disable-python && | ||
| make | ||
| yum install -y cmake bzip2-devel flac-devel xz-devel pcre-devel zziplib-devel |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are all of these plugin libraries being found correctly by cmake? IIRC, I had to give hints to autotools with the bootstrap command to make sure that all of the. compression plugins built properly.
| else() | ||
| math(EXPR GETDATA_INT_VERSION "${PROJECT_VERSION_MAJOR} * 10000 + ${PROJECT_VERSION_MINOR} * 100 + ${PROJECT_VERSION_PATCH}") | ||
| endif() | ||
| set(DEFINE_GD_GETDATA_INT_VERSION "#define GD_GETDATA_INT_VERSION ${GETDATA_INT_VERSION}") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This variable doesn't seem to be used anywhere?
This PR builds on the previous one (#20), so while it's a big change, it's not as sprawling as it seems.
My primary motivation is getting Windows wheels built for pygetdata. This created a fair cascade of tasks because:
Practically speaking, native Windows support needs CMake instead of autotools, and switching the MacOS/Linux wheel builders at the same time makes sense. The autotools flow remains in place (and the github regression tests still pass against it.)
This PR contains a mix of "omnibus commits" (an incremental modernization of the CMake infrastructure does not make sense) and "drive-by commits" for individual bug fixes or improvements.
Note that we have definitely left Python 2.x behind (Numpy 2.x never supported it anyways).