Skip to content

Use CMake for Build System #47380

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

Closed
wants to merge 75 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
75 commits
Select commit Hold shift + click to select a range
67e0d51
initial cmake setup
WillAyd Jun 15, 2022
08ae817
easy conversions
WillAyd Jun 15, 2022
b483dc6
tslibs
WillAyd Jun 15, 2022
5f36730
full build
WillAyd Jun 15, 2022
8408b07
build json
WillAyd Jun 15, 2022
3a949d9
ignore cmake generated files
WillAyd Jun 16, 2022
b697755
public linkage
WillAyd Jun 16, 2022
ad43a31
remove unneeded library links
WillAyd Jun 16, 2022
d41af1e
PUBLIC cmake linkage
WillAyd Jun 16, 2022
3c6dd10
Merge branch 'main' into cmake-build
WillAyd Jun 16, 2022
4eab4a2
build system
WillAyd Jun 16, 2022
02b48fe
cleaned up setup
WillAyd Jun 16, 2022
b447b86
restored pandas makefile
WillAyd Jun 16, 2022
64a9cbf
inline cythonization
WillAyd Jun 16, 2022
a2dfd3e
python suffix
WillAyd Jun 16, 2022
40d18f9
correct min version
WillAyd Jun 17, 2022
d1c2aef
some progress
WillAyd Jun 17, 2022
9753009
better dependencies
WillAyd Jun 17, 2022
42e9b6d
optimize template generation
WillAyd Jun 17, 2022
9d2f250
generation script
WillAyd Jun 17, 2022
8f2a49a
checkpoint
WillAyd Jun 17, 2022
933d5b0
renamed json to ujson to avoid stdlib conflicts
WillAyd Jun 17, 2022
fa25fe1
added missing join build
WillAyd Jun 17, 2022
496c015
Working build
WillAyd Jun 17, 2022
27fbd0a
used detected python executable
WillAyd Jun 17, 2022
abdd163
cmake-format usage
WillAyd Jun 17, 2022
3e714e1
CI updates
WillAyd Jun 17, 2022
0dec991
spaces not tabs
WillAyd Jun 17, 2022
40973fc
removed setup completely
WillAyd Jun 17, 2022
2881bbc
remove pep-517 exclusion
WillAyd Jun 17, 2022
5181d99
added python link options
WillAyd Jun 18, 2022
73162a0
removed public linkage
WillAyd Jun 18, 2022
9f0dc3a
LINK_LIBRARIES for macOS
WillAyd Jun 18, 2022
0983ef7
apple compat
WillAyd Jun 18, 2022
3328dd6
fixed sas import
WillAyd Jun 18, 2022
3e973bb
fixed macOS / linux lib names
WillAyd Jun 18, 2022
a1f41fc
implemented project version
WillAyd Jun 18, 2022
06ed345
removed failing build element
WillAyd Jun 18, 2022
dd319b8
windows builds
WillAyd Jun 18, 2022
46848ff
code checks
WillAyd Jun 19, 2022
739f2cb
script import fixes
WillAyd Jun 19, 2022
659016a
isort fixup
WillAyd Jun 19, 2022
94342e6
Merge remote-tracking branch 'upstream/main' into cmake-build
WillAyd Jun 19, 2022
c8ac167
docker fixups
WillAyd Jun 19, 2022
ca4d6a0
more docker
WillAyd Jun 19, 2022
dc5ff2d
Use Python_add_library
WillAyd Jun 20, 2022
73b0962
fix 32bit docker image
WillAyd Jun 20, 2022
421657f
reimplemented windows settings
WillAyd Jun 20, 2022
0ccf5bc
try version fix for dev Docker env
WillAyd Jun 20, 2022
9cf9d8d
windows / docker fixes
WillAyd Jun 20, 2022
acdccf9
VERBOSE build
WillAyd Jun 20, 2022
7310bf0
windows support
WillAyd Jun 20, 2022
64a2bf1
test fixes / compat
WillAyd Jun 20, 2022
357fe17
cmake via pip
WillAyd Jun 21, 2022
fdc54c4
added back setuptools for sdist and bdist_wheel creation
WillAyd Jun 21, 2022
3bd83d1
removed verbose build
WillAyd Jun 21, 2022
f095255
documentation cleanups
WillAyd Jun 21, 2022
dee3e6f
isort setup.py
WillAyd Jun 21, 2022
55a0a3f
comment cleanup
WillAyd Jun 21, 2022
ffb1f3d
cmake-format all files
WillAyd Jun 21, 2022
d27fe22
sdist test fix
WillAyd Jun 21, 2022
c1c463b
updated MANFIEST
WillAyd Jun 21, 2022
73f2e94
config updates
WillAyd Jun 21, 2022
fde002a
remove cmake from install_requires
WillAyd Jun 21, 2022
d43a292
pep517 build backend
WillAyd Jun 22, 2022
59d0cf2
Merge remote-tracking branch 'upstream/main' into cmake-build
WillAyd Jun 22, 2022
b1e6be8
revert sdist ci changes
WillAyd Jun 22, 2022
75dfb3d
Merge remote-tracking branch 'upstream/main' into cmake-build
WillAyd Aug 4, 2022
d6592dc
removed errant global-exclude of sos
WillAyd Aug 4, 2022
1155787
code check
WillAyd Aug 4, 2022
c57200c
reverted Dockerfile hacks
WillAyd Aug 4, 2022
d62f894
renamed typestub
WillAyd Aug 4, 2022
3bba968
Merge remote-tracking branch 'upstream/main' into cmake-build
WillAyd Aug 14, 2022
107112e
Merge remote-tracking branch 'upstream/main' into cmake-build
WillAyd Aug 14, 2022
ecef747
Merge remote-tracking branch 'upstream/main' into cmake-build
WillAyd Aug 17, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .circleci/setup_env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,10 @@ if [ "$(conda list -f qt --json)" != [] ]; then
fi

echo "Build extensions"
python setup.py build_ext -q -j3
cmake .
cmake --build . --config Release --parallel

echo "Install pandas"
python -m pip install --no-build-isolation --no-use-pep517 -e .
python -m pip install --no-build-isolation -e .

echo "done"
5 changes: 3 additions & 2 deletions .github/actions/build_pandas/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ runs:

- name: Build Pandas
run: |
python setup.py build_ext -j $N_JOBS
python -m pip install -e . --no-build-isolation --no-use-pep517 --no-index
cmake .
cmake --build . --config Release --parallel
python -m pip install -e . --no-build-isolation --no-index
shell: bash -el {0}
env:
# Cannot use parallel compilation on Windows, see https://github.com/pandas-dev/pandas/issues/30873
Expand Down
9 changes: 5 additions & 4 deletions .github/workflows/32-bit-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,11 @@ jobs:
/opt/python/cp38-cp38/bin/python -m venv ~/virtualenvs/pandas-dev && \
. ~/virtualenvs/pandas-dev/bin/activate && \
python -m pip install --no-deps -U pip wheel 'setuptools<60.0.0' && \
pip install cython numpy python-dateutil pytz pytest pytest-xdist pytest-asyncio>=0.17 hypothesis && \
python setup.py build_ext -q -j1 && \
python -m pip install --no-build-isolation --no-use-pep517 -e . && \
python -m pip list && \
pip install cmake cython numpy python-dateutil pytz pytest pytest-xdist pytest-asyncio>=0.17 hypothesis && \
cmake . && \
cmake --build . --parallel && \
python -m pip install --no-build-isolation -e . && \
python -m pip list && \
export PANDAS_CI=1 && \
pytest -m 'not slow and not network and not clipboard and not single_cpu' pandas --junitxml=test-data.xml"

Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@
*.so
.build_cache_dir
MANIFEST
Makefile
CMakeCache.txt
CMakeFiles/
cmake_install.cmake

# Python files #
################
Expand Down
29 changes: 29 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
cmake_minimum_required(VERSION 3.18)

set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9")
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED True)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

project(pandas)

if(WIN32)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE
Release
CACHE STRING "Build type" FORCE)
endif()
find_package(Python3 REQUIRED COMPONENTS Interpreter Development NumPy)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE "")
link_directories(${Python3_LIBRARY_DIRS})
else()
# we only choose Development.Module to support virtual environments where
# libpython may not be available see
# https://github.com/pypa/manylinux/issues/484
find_package(Python3 REQUIRED COMPONENTS Interpreter Development.Module NumPy)
endif()

add_compile_definitions(NPY_NO_DEPRECATED_API=0)
add_subdirectory("pandas/_libs")
add_subdirectory("pandas/io/sas")
3 changes: 2 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -49,5 +49,6 @@ RUN . /opt/conda/etc/profile.d/conda.sh \
&& conda activate base \
&& cd "$pandas_home" \
&& export \
&& python setup.py build_ext -j 4 \
&& cmake . \
&& cmake --build . --parallel \
&& python -m pip install --no-build-isolation -e .
6 changes: 5 additions & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
include RELEASE.md
include versioneer.py
include CMakeLists.txt

graft doc
prune doc/build

graft LICENSES

graft pandas
graft build_support

global-exclude *.bz2
global-exclude *.csv
Expand All @@ -28,7 +30,6 @@ global-exclude *.odt
global-exclude *.orc
global-exclude *.sas7bdat
global-exclude *.sav
global-exclude *.so
global-exclude *.xls
global-exclude *.xlsb
global-exclude *.xlsm
Expand All @@ -42,6 +43,9 @@ global-exclude *~
global-exclude .DS_Store
global-exclude .git*
global-exclude \#*
recursive-exclude **/CMakeFiles *
global-exclude *.cmake
global-exclude CMakeCache.txt

global-exclude *.c
global-exclude *.cpp
Expand Down
30 changes: 0 additions & 30 deletions Makefile

This file was deleted.

21 changes: 21 additions & 0 deletions build_support/build_backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import pathlib
import subprocess

from setuptools import build_meta as _orig

prepare_metadata_for_build_wheel = _orig.prepare_metadata_for_build_wheel
build_sdist = _orig.build_sdist
get_requires_for_build_wheel = _orig.get_requires_for_build_wheel
get_requires_for_build_sdist = _orig.get_requires_for_build_sdist


def build_wheel(wheel_directory, config_settings=None, metadata_directory=None):
filedir = pathlib.Path(__file__).resolve().parent.parent
subprocess.run(["cmake", "."], cwd=filedir, check=True)
subprocess.run(
["cmake", "--build", ".", "--config", "Release", "--parallel"],
cwd=filedir,
check=True,
)

return _orig.build_wheel(wheel_directory, config_settings, metadata_directory)
15 changes: 10 additions & 5 deletions doc/source/development/contributing_environment.rst
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ Run Container::
If you bind your local repo for the first time, you have to build the C extensions afterwards.
Run the following command inside the container::

python setup.py build_ext -j 4
cmake .
cmake --build . --config Release --parallel

You need to rebuild the C extensions anytime the Cython code in ``pandas/_libs`` changes.
This most frequently occurs when changing or merging branches.
Expand Down Expand Up @@ -169,7 +170,8 @@ We'll now kick off a three-step process:
source activate pandas-dev

# Build and install pandas
python setup.py build_ext -j 4
cmake .
cmake --build . --config Release --parallel
python -m pip install -e . --no-build-isolation --no-use-pep517

At this point you should be able to import pandas from your locally built version::
Expand Down Expand Up @@ -216,7 +218,8 @@ You also need to have ``setuptools`` 51.0.0 or later to build pandas.
python -m pip install -r requirements-dev.txt

# Build and install pandas
python setup.py build_ext -j 4
cmake .
cmake --build . --config Release --parallel
python -m pip install -e . --no-build-isolation --no-use-pep517

**Unix**/**macOS with pyenv**
Expand All @@ -240,7 +243,8 @@ Consult the docs for setting up pyenv `here <https://github.com/pyenv/pyenv>`__.
python -m pip install -r requirements-dev.txt

# Build and install pandas
python setup.py build_ext -j 4
cmake .
cmake --build . --config Release --parallel
python -m pip install -e . --no-build-isolation --no-use-pep517

**Windows**
Expand All @@ -266,5 +270,6 @@ should already exist.
python -m pip install -r requirements-dev.txt

# Build and install pandas
python setup.py build_ext -j 4
cmake .
cmake --build . --config Release --parallel
python -m pip install -e . --no-build-isolation --no-use-pep517
5 changes: 3 additions & 2 deletions doc/source/development/debugging_extensions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@ Debugging C extensions

Pandas uses select C extensions for high performance IO operations. In case you need to debug segfaults or general issues with those extensions, the following steps may be helpful.

First, be sure to compile the extensions with the appropriate flags to generate debug symbols and remove optimizations. This can be achieved as follows:
First, be sure to compile the extensions with the appropriate flags to generate debug symbols and remove optimizations. This can be achieved on Unix-like systems as follows:

.. code-block:: sh

python setup.py build_ext --inplace -j4 --with-debugging-symbols
cmake . -DCMAKE_BUILD_TYPE=Debug
cmake --build . --parallel

Using a debugger
================
Expand Down
1 change: 1 addition & 0 deletions environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ dependencies:
- asv

# The compiler packages are meta-packages and install the correct compiler (activation) packages on the respective platforms.
- cmake>=3.18.0
- c-compiler
- cxx-compiler

Expand Down
3 changes: 2 additions & 1 deletion pandas/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
raise ImportError(
f"C extension: {_module} not built. If you want to import "
"pandas from the source directory, you may need to run "
"'python setup.py build_ext --force' to build the C extensions first."
"'cmake . && cmake --build . --config Release --parallel' "
"to build the C extensions first."
) from _err
else:
del _tslib, _lib, _hashtable
Expand Down
142 changes: 142 additions & 0 deletions pandas/_libs/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
add_custom_command(
OUTPUT algos_common_helper.pxi
algos_take_helper.pxi
hashtable_class_helper.pxi
hashtable_func_helper.pxi
index_class_helper.pxi
intervaltree.pxi
khash_for_primitive_helper.pxi
sparse_op_helper.pxi
COMMAND ${Python3_EXECUTABLE} generate_templates.py)

add_custom_command(
OUTPUT algos.c
COMMAND ${Python3_EXECUTABLE} -m cython -3 algos.pyx
DEPENDS algos_common_helper.pxi algos_take_helper.pxi)
python3_add_library(algos MODULE WITH_SOABI algos.c)
target_include_directories(
algos PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS} "src/klib")

# There is a khash header file in src/klib and a cython generated one in _libs.
# Depending on the build timing one of the other could get picked up, though
# unclear why we need both? If we stick to the non-generated version we can
# remove any DEPENDS khash.h
add_custom_command(
OUTPUT khash.h
COMMAND ${Python3_EXECUTABLE} -m cython -3 khash.pxd
DEPENDS hkash_for_primitive_helper.pxi)

add_custom_command(
OUTPUT hashtable.c
COMMAND ${Python3_EXECUTABLE} -m cython -3 hashtable.pyx
DEPENDS hashtable_class_helper.pxi hashtable_func_helper.pxi)

python3_add_library(hashtable MODULE WITH_SOABI hashtable.c)
target_include_directories(
hashtable PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS}
"src/klib" DEPENDS khash.h)

add_custom_command(
OUTPUT index.c
COMMAND ${Python3_EXECUTABLE} -m cython -3 index.pyx
DEPENDS index_class_helper.pxi)
python3_add_library(index MODULE WITH_SOABI index.c)
target_include_directories(
index PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS} "src/klib"
"./tslibs")

add_custom_command(
OUTPUT interval.c
COMMAND ${Python3_EXECUTABLE} -m cython -3 interval.pyx
DEPENDS intervaltree.pxi)
python3_add_library(interval MODULE WITH_SOABI interval.c)
target_include_directories(
interval PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS}
"src/klib" "./tslibs")

add_custom_command(
OUTPUT sparse.c
COMMAND ${Python3_EXECUTABLE} -m cython -3 sparse.pyx
DEPENDS sparse_op_helper.pxi)
python3_add_library(sparse MODULE WITH_SOABI sparse.c)
target_include_directories(
sparse PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS}
"src/klib")

set(BASIC_LIBRARIES
arrays
groupby
hashing
indexing
internals
reduction
ops
ops_dispatch
properties
reshape
testing
writers)
foreach(LIB ${BASIC_LIBRARIES})
add_custom_command(OUTPUT ${LIB}.c COMMAND ${Python3_EXECUTABLE} -m cython -3
${LIB}.pyx)
python3_add_library(${LIB} MODULE WITH_SOABI ${LIB}.c)
target_include_directories(${LIB} PUBLIC ${Python3_INCLUDE_DIRS}
${Python3_NumPy_INCLUDE_DIRS})
endforeach()

add_subdirectory("tslibs")

add_custom_command(OUTPUT tslib.c COMMAND ${Python3_EXECUTABLE} -m cython -3
tslib.pyx)
python3_add_library(tslib ${LIB} MODULE WITH_SOABI tslib.c
tslibs/src/datetime/np_datetime.c)
target_include_directories(
tslib PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS} "./tslibs")

add_custom_command(OUTPUT missing.c COMMAND ${Python3_EXECUTABLE} -m cython -3
missing.pyx)
python3_add_library(missing MODULE WITH_SOABI missing.c)
target_include_directories(
missing PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS}
"./tslibs")

add_custom_command(OUTPUT lib.c COMMAND ${Python3_EXECUTABLE} -m cython -3
lib.pyx)
python3_add_library(lib MODULE WITH_SOABI lib.c src/parser/tokenizer.c)
target_include_directories(
lib PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS} "src/klib"
"./tslibs")

add_custom_command(
OUTPUT join.c
COMMAND ${Python3_EXECUTABLE} -m cython -3 join.pyx
DEPENDS khash_for_primitive_helper.pxi)
python3_add_library(join MODULE WITH_SOABI join.c)
target_include_directories(join PUBLIC ${Python3_INCLUDE_DIRS}
${Python3_NumPy_INCLUDE_DIRS} "src/klib")

add_custom_command(OUTPUT parsers.c COMMAND ${Python3_EXECUTABLE} -m cython -3
parsers.pyx)
python3_add_library(parsers MODULE WITH_SOABI parsers.c src/parser/tokenizer.c
src/parser/io.c)
target_include_directories(
parsers PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS}
"src/klib" "src")

python3_add_library(
ujson
MODULE
WITH_SOABI
src/ujson/python/ujson.c
src/ujson/python/objToJSON.c
src/ujson/python/date_conversions.c
src/ujson/python/JSONtoObj.c
src/ujson/lib/ultrajsonenc.c
src/ujson/lib/ultrajsondec.c
tslibs/src/datetime/np_datetime.c
tslibs/src/datetime/np_datetime_strings.c)
target_include_directories(
ujson PUBLIC ${Python3_INCLUDE_DIRS} ${Python3_NumPy_INCLUDE_DIRS}
src/ujson/python src/ujson/lib src/datetime)

add_subdirectory("window")
Loading