Skip to content

Conversation

@gsmecher
Copy link
Contributor

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:

  • autotools only works on UNIX-like environments (including MSYS2/cygwin), but
  • on Windows, native Python .pyd modules are really only supported using MSVC
  • If we do that, the MacOS and Linux wheel builders should come along for the ride.

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).

@gsmecher
Copy link
Contributor Author

@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).

@gsmecher gsmecher force-pushed the python-cmake branch 4 times, most recently from 667f835 to ccccf8e Compare December 17, 2025 20:28
… 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.
dynamic = ["version"]

[tool.setuptools]
script-files = ["../../util/dirfile2ascii", "../../util/checkdirfile"]
Copy link
Collaborator

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.

Copy link
Contributor Author

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.

Copy link
Collaborator

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?

Copy link
Collaborator

Choose a reason for hiding this comment

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


/* Package information */
#define PACKAGE_NAME "GetData"
#define PACKAGE_VERSION "0.11.0"
Copy link
Collaborator

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?

Copy link
Contributor Author

@gsmecher gsmecher Dec 19, 2025

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_minimum_required(VERSION 2.6.4)
cmake_minimum_required(VERSION 3.15)

project(getdata)
Copy link
Collaborator

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.

Copy link
Contributor Author

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?

Copy link
Collaborator

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()

Copy link
Collaborator

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.

@gsmecher gsmecher force-pushed the python-cmake branch 11 times, most recently from b8e92dc to 5f66b02 Compare December 18, 2025 22:41
This is a little clunky but reduces the number of redundant places where
the version numbering must be updated.
Comment on lines -114 to -117
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}
Copy link
Collaborator

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
Copy link
Collaborator

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}")
Copy link
Collaborator

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?

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.

2 participants