Skip to content
Snippets Groups Projects
Commit d623a3eb authored by Marcel Loose's avatar Marcel Loose :sunglasses:
Browse files

RAP-370: Build with scikit-build-core

parent 1945fba2
No related branches found
No related tags found
1 merge request!323RAP-370: Build with scikit-build-core
Pipeline #68363 passed with warnings
......@@ -40,10 +40,13 @@ cibuild-python-wheels:
- wget -qO - https://get.docker.com/ | sh
- pip install cibuildwheel
- cibuildwheel --output-dir wheelhouse
# rules:
# # Only run cibuildwheel when building the default branch or a tag.
# - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
# - if: '$CI_COMMIT_TAG'
rules:
# Run cibuildwheel for merge requests, or when building a tag or the default branch
- if: $CI_PIPELINE_SOURCE == 'merge_request_event'
- if: $CI_COMMIT_TAG
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
tags:
- das6
artifacts:
paths:
- wheelhouse/*.whl
......
......@@ -292,16 +292,6 @@ deploy-image-2204:
# For testing this job on a branch, set the DEPLOY_IMAGE variable to true.
- if: '$DEPLOY_IMAGE'
python-wheel-2204:
extends: .needs-base-2204
stage: deploy
image: $BASE_IMAGE_2204
variables:
GIT_SUBMODULE_STRATEGY: normal
script:
- python3 setup.py bdist_wheel
- pip install --user dist/*.whl
- python3 -c "import everybeam"
artifacts:
paths:
- dist/*.whl
- dist/everybeam*.whl
# - Install Python source files.
# python_install(source1..sourceN DESTINATION install_dir)
# Install Python source files and byte-compile them in the directory
# ${PYTHON_INSTALL_DIR}/${install_dir}.
# Copyright (C) 2020 ASTRON (Netherlands Institute for Radio Astronomy)
# SPDX-License-Identifier: GPL-3.0-or-later
# Search for the Python interpreter.
find_package(PythonInterp)
# Derive the Python site-packages installation directory and build directory.
if(PYTHON_EXECUTABLE)
set(_cmd
"from distutils.sysconfig import get_python_lib"
"from os.path import join"
"print(join(
get_python_lib(plat_specific=True, standard_lib=True, prefix=''),
'site-packages'))"
)
execute_process(
COMMAND "${PYTHON_EXECUTABLE}" "-c" "${_cmd}"
OUTPUT_VARIABLE _pydir
ERROR_VARIABLE _pyerr
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(_pyerr)
message(FATAL_ERROR "Python command failed:\n${_pyerr}")
endif(_pyerr)
if(NOT DEFINED PYTHON_BUILD_DIR)
set(_PRINT_PYTHON_DIRS TRUE)
endif()
set(PYTHON_BUILD_DIR "${CMAKE_BINARY_DIR}/${_pydir}" CACHE PATH
"Build directory for Python extensions" FORCE)
set(PYTHON_INSTALL_DIR "${CMAKE_INSTALL_PREFIX}/${_pydir}" CACHE PATH
"Installation directory for Python extensions" FORCE)
if(_PRINT_PYTHON_DIRS)
message(STATUS "Build directory for Python extensions: ${PYTHON_BUILD_DIR}")
message(STATUS "Installation directory for Python extensions: ${PYTHON_INSTALL_DIR}")
endif()
endif(PYTHON_EXECUTABLE)
#
# macro python_install
#
macro(python_install)
# Precondition check.
if(NOT PYTHON_EXECUTABLE)
message(FATAL_ERROR "python_install: Python interpreter not available")
endif(NOT PYTHON_EXECUTABLE)
# Parse arguments.
# apart from the python files list, there are two additional arguments
# DESTINATION (required), where to put the py files (relative to python lib dir)
# EXECUTABLE (optional), makes the py files executable
string(REGEX REPLACE ";?DESTINATION.*" "" _py_files "${ARGN}")
string(REGEX REPLACE ";?EXECUTABLE.*" "" _py_files "${_py_files}")
string(REGEX MATCH "DESTINATION;.*" _dest_dir "${ARGN}")
string(REGEX REPLACE "^DESTINATION;" "" _dest_dir "${_dest_dir}")
string(REGEX REPLACE ";?EXECUTABLE.*" "" _dest_dir "${_dest_dir}")
string(REGEX MATCH "EXECUTABLE;" _executable "${ARGN}")
#check if optional argument EXECUTABLE is set
#if so, then install the _py_files as EXECUTABLE type (executable)
#else as normal files (not executable)
if("${_executable}" STRGREATER "")
set(INSTALL_TYPE PROGRAMS)
else()
set(INSTALL_TYPE FILES)
endif("${_executable}" STRGREATER "")
if(_py_files MATCHES "^$")
message(FATAL_ERROR "python_install: no sources files specified")
endif(_py_files MATCHES "^$")
if(_dest_dir MATCHES "^$" OR _dest_dir MATCHES ";")
message(FATAL_ERROR "python_install: destination directory invalid")
endif(_dest_dir MATCHES "^$" OR _dest_dir MATCHES ";")
# Set python package build/install directory.
set(_inst_dir "${PYTHON_INSTALL_DIR}/${_dest_dir}")
set(_build_dir "${PYTHON_BUILD_DIR}/${_dest_dir}")
# Install and byte-compile each Python file.
foreach(_py ${_py_files})
get_filename_component(_py_path ${_py} PATH)
get_filename_component(_py_abs ${_py} ABSOLUTE)
# check if _py is a path in CMAKE_BINARY_DIR. If so, then it is most likely a configured_file.
# then strip the CMAKE_CURRENT_BINARY_DIR prefix.
if(${_py} MATCHES "^(${CMAKE_CURRENT_BINARY_DIR})")
string(REGEX REPLACE "^(${CMAKE_CURRENT_BINARY_DIR}/)" "" _py "${_py}")
get_filename_component(_py_path ${_py} PATH)
endif()
# Create a symlink to each Python file; needed to mimic install tree.
file(MAKE_DIRECTORY ${_build_dir}/${_py_path})
execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
${_py_abs} ${_build_dir}/${_py})
install(${INSTALL_TYPE} ${_py_abs} DESTINATION ${_inst_dir}/${_py_path})
if(USE_PYTHON_COMPILATION)
set(_py_code
"import py_compile, os"
"destdir = os.environ.get('DESTDIR','')"
"print('-- Byte-compiling: %s${_inst_dir}/${_py}' % destdir)"
"py_compile.compile('%s${DESTDIR}${_inst_dir}/${_py}' % destdir, doraise=True)")
install(CODE
"execute_process(COMMAND ${PYTHON_EXECUTABLE} -c \"${_py_code}\"
RESULT_VARIABLE _result)
if(NOT _result EQUAL 0)
message(FATAL_ERROR \"Byte-compilation FAILED: \$ENV{DESTDIR}${_inst_dir}/${_py}\")
endif(NOT _result EQUAL 0)")
endif(USE_PYTHON_COMPILATION)
endforeach(_py ${_py_files})
# Make sure that there's a __init__.py file in each build/install directory.
string(REGEX REPLACE "/" ";" _dir_list ${_dest_dir})
set(_init_dir)
foreach(_dir ${_dir_list})
set(_init_dir "${_init_dir}/${_dir}")
execute_process(COMMAND ${CMAKE_COMMAND} -E touch
"${PYTHON_BUILD_DIR}${_init_dir}/__init__.py")
install(CODE
"execute_process(COMMAND ${CMAKE_COMMAND} -E touch
\"\$ENV{DESTDIR}${PYTHON_INSTALL_DIR}${_init_dir}/__init__.py\")")
endforeach(_dir ${_dir_list})
endmacro(python_install)
......@@ -5,7 +5,7 @@
#define EVERYBEAM_CONFIG_H_
#define EVERYBEAM_DATADIR "@EVERYBEAM_DATADIR@"
#define EVERYBEAM_FULL_DATADIR "@EVERYBEAM_FULL_DATADIR@"
#define EVERYBEAM_ABSOLUTE_DATADIR "@EVERYBEAM_ABSOLUTE_DATADIR@"
#define TEST_MEASUREMENTSET "@TEST_MEASUREMENTSET@"
#define LOFAR_HBA_MOCK_MS "@LOFAR_HBA_MOCK_MS@"
#define LOFAR_LBA_MOCK_MS "@LOFAR_LBA_MOCK_MS@"
......
......@@ -7,7 +7,7 @@ cmake_minimum_required(VERSION 3.15)
#------------------------------------------------------------------------------
# Set version name and project number
set(EVERYBEAM_VERSION 0.5.3)
set(EVERYBEAM_VERSION 0.5.3) # Keep in sync with `pyproject.toml` file
if(EVERYBEAM_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)")
set(EVERYBEAM_VERSION_MAJOR "${CMAKE_MATCH_1}")
set(EVERYBEAM_VERSION_MINOR "${CMAKE_MATCH_2}")
......@@ -53,6 +53,16 @@ option(DOWNLOAD_LWA "Download and install OVRO-LWA coefficient file" OFF)
string(TOLOWER ${CMAKE_PROJECT_NAME} projectname)
# When the software is built with, e.g., `pip` or `build`, `scikit-build-core`
# controls the build, and software will be installed in `site-packages`. In
# this case we do not want to install libraries in `lib`, but instead follow
# the convention of installing libraries in a directory `<package>.libs`.
if(SKBUILD)
set(INSTALL_LIBDIR everybeam.libs)
else()
set(INSTALL_LIBDIR lib)
endif()
# Set the path to CMake modules
set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/CMake)
......@@ -85,6 +95,9 @@ else()
set(FIND_CUDA
OFF
CACHE INTERNAL "")
# Ensure that the ska-sdp-func library is installed in the same directory as
# the other everybeam libraries.
set(SDP_FUNC_LIB_INSTALL_DIR "${INSTALL_LIBDIR}")
FetchContent_Declare(
ska-sdp-func
GIT_REPOSITORY ${ska-sdp-func_GIT_REPOSITORY}
......@@ -106,11 +119,23 @@ set(EVERYBEAM_DATADIR
"share/${projectname}"
CACHE STRING "EveryBeam data directory")
if(IS_ABSOLUTE ${EVERYBEAM_DATADIR})
set(EVERYBEAM_FULL_DATADIR "${EVERYBEAM_DATADIR}")
set(EVERYBEAM_ABSOLUTE_DATADIR "${EVERYBEAM_DATADIR}")
else()
set(EVERYBEAM_FULL_DATADIR "${CMAKE_INSTALL_PREFIX}/${EVERYBEAM_DATADIR}")
set(EVERYBEAM_ABSOLUTE_DATADIR "${CMAKE_INSTALL_PREFIX}/${EVERYBEAM_DATADIR}")
endif()
message("Storing data in: " ${EVERYBEAM_FULL_DATADIR})
# When the software is built with, e.g., `pip` or `build`, `scikit-build-core`
# controls the build. In this case we need to follow the naming convention in
# PEP-491 for the data directory, otherwise the data files will not be
# installed in the right directory when the python wheel is unpacked.
if(SKBUILD)
# Following naming convention of data directory in PEP 491
set(EVERYBEAM_INSTALL_DATADIR
"${projectname}-${EVERYBEAM_VERSION}.data/data/share/${projectname}")
else()
set(EVERYBEAM_INSTALL_DATADIR ${EVERYBEAM_DATADIR})
endif()
message("Installing data files in: ${EVERYBEAM_INSTALL_DATADIR}")
# Find and include git submodules
find_package(Git QUIET)
......@@ -234,16 +259,15 @@ set(CMAKE_SKIP_BUILD_RPATH FALSE)
# when building, don't use the install RPATH already
# (but later on when installing)
set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE)
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
# add the automatically determined parts of the RPATH
# which point to directories outside the build tree to the install RPATH
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
# the RPATH to be used when installing, but only if it's not a system directory
list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES
"${CMAKE_INSTALL_PREFIX}/lib" isSystemDir)
"${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}" isSystemDir)
if("${isSystemDir}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib")
endif("${isSystemDir}" STREQUAL "-1")
set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/${INSTALL_LIBDIR}")
endif()
#------------------------------------------------------------------------------
# Set up a test_data directory in the build directory.
......
......@@ -26,11 +26,12 @@ function download_and_build_fftw
/bin/echo -e "\n==> Building and installing FFTW ${FFTW_VERSION} ...\n"
cd "${WORKDIR}/fftw-${FFTW_VERSION}"
./configure \
--quiet \
--prefix /usr/local \
--enable-threads \
--enable-shared \
--enable-float
make -j"${nproc}" install
make --jobs="${nproc}" --quiet install
}
......@@ -46,11 +47,12 @@ function download_and_build_hdf5
/bin/echo -e "\n==> Building and installing HDF5 ${HDF5_VERSION} ...\n"
cd "${WORKDIR}/hdf5-${HDF5_VERSION}"
./configure \
--quiet \
--prefix /usr/local \
--enable-build-mode=production \
--with-szlib \
--enable-cxx
make -j"${nproc}" install
make --jobs="${nproc}" --quiet install
}
......
......@@ -103,10 +103,15 @@ target_link_libraries(
target_link_libraries(everybeam PRIVATE schaapcommon Threads::Threads xtensor
${BLAS_LIBRARIES} ${LAPACK_LIBRARIES})
if(SKBUILD)
set_target_properties(everybeam PROPERTIES INSTALL_RPATH "$ORIGIN")
endif()
install(
TARGETS everybeam everybeam-core
COMPONENT libraries
EXPORT EveryBeamTargets
DESTINATION lib)
DESTINATION ${INSTALL_LIBDIR})
install(
FILES antenna.h
......
......@@ -10,16 +10,21 @@ target_link_libraries(hamaker PUBLIC ${HDF5_CXX_LIBRARIES} everybeam-core)
string(TOLOWER ${CMAKE_PROJECT_NAME} projectname)
set_target_properties(hamaker PROPERTIES LIBRARY_OUTPUT_NAME
"${projectname}-hamaker")
if(SKBUILD)
set_target_properties(hamaker PROPERTIES INSTALL_RPATH "$ORIGIN")
endif()
# install libhamaker.so
install(
TARGETS hamaker
COMPONENT libraries
EXPORT EveryBeamTargets
DESTINATION lib)
DESTINATION ${INSTALL_LIBDIR})
# install coefficients
message("install hamaker in: " ${EVERYBEAM_FULL_DATADIR})
install(FILES "${CMAKE_SOURCE_DIR}/coeffs/HamakerHBACoeff.h5"
DESTINATION ${EVERYBEAM_DATADIR})
install(FILES "${CMAKE_SOURCE_DIR}/coeffs/HamakerLBACoeff.h5"
DESTINATION ${EVERYBEAM_DATADIR})
message("Install Hamaker coefficients in: ${EVERYBEAM_INSTALL_DATADIR}")
install(
FILES "${CMAKE_SOURCE_DIR}/coeffs/HamakerHBACoeff.h5"
"${CMAKE_SOURCE_DIR}/coeffs/HamakerLBACoeff.h5"
COMPONENT data-files
DESTINATION ${EVERYBEAM_INSTALL_DATADIR})
......@@ -17,10 +17,11 @@ if(DOWNLOAD_LOBES OR BUILD_TESTING)
endif()
# install coefficients
message("install lobes coefficients in: " ${EVERYBEAM_FULL_DATADIR}/lobes)
message("Install LOBES coefficients in: ${EVERYBEAM_INSTALL_DATADIR}/lobes")
install(
DIRECTORY "${CMAKE_BINARY_DIR}/coeffs/lobes"
DESTINATION ${EVERYBEAM_DATADIR}
COMPONENT data-files
DESTINATION ${EVERYBEAM_INSTALL_DATADIR}
FILES_MATCHING
PATTERN "LOBES_*")
......
......@@ -16,8 +16,8 @@ if(DOWNLOAD_LWA OR BUILD_TESTING)
add_dependencies(everybeam download_lwa_coefficients)
# install coefficients
message("install LWA coefficients in: " ${EVERYBEAM_FULL_DATADIR}/lwa)
message("Install LWA coefficients in: ${EVERYBEAM_INSTALL_DATADIR}/lwa")
install(FILES "${CMAKE_BINARY_DIR}/coeffs/lwa/LWA_OVRO.h5"
DESTINATION "${EVERYBEAM_DATADIR}/lwa")
DESTINATION "${EVERYBEAM_INSTALL_DATADIR}/lwa")
endif()
......@@ -13,7 +13,7 @@ namespace everybeam {
// TODO(RAP-260) Improve this path lookup.
std::filesystem::path GetDataDirectory() {
const char* envvar;
if (std::strcmp(EVERYBEAM_DATADIR, EVERYBEAM_FULL_DATADIR) == 0)
if (std::strcmp(EVERYBEAM_DATADIR, EVERYBEAM_ABSOLUTE_DATADIR) == 0)
return std::filesystem::path(EVERYBEAM_DATADIR);
if ((envvar = std::getenv("EVERYBEAM_DATADIR")))
return std::filesystem::path(envvar);
......@@ -21,6 +21,6 @@ std::filesystem::path GetDataDirectory() {
return std::filesystem::path(envvar) / EVERYBEAM_DATADIR;
if ((envvar = std::getenv("VIRTUAL_ENV")))
return std::filesystem::path(envvar) / EVERYBEAM_DATADIR;
return std::filesystem::path(EVERYBEAM_FULL_DATADIR);
return std::filesystem::path(EVERYBEAM_ABSOLUTE_DATADIR);
}
} // namespace everybeam
......@@ -13,7 +13,9 @@ add_library(oskar SHARED oskarelementresponse.cc oskardatafile.cc
string(TOLOWER ${CMAKE_PROJECT_NAME} projectname)
set_target_properties(oskar PROPERTIES LIBRARY_OUTPUT_NAME
"${projectname}-oskar")
if(SKBUILD)
set_target_properties(oskar PROPERTIES INSTALL_RPATH "$ORIGIN")
endif()
# Make sure that when other targets within this project link against the oskar target,
# they can find the include files.
target_include_directories(
......@@ -29,9 +31,12 @@ target_link_libraries(oskar PRIVATE ska-sdp-func::ska-sdp-func)
# install libeverybeam-oskar.so
install(
TARGETS oskar
COMPONENT libraries
EXPORT EveryBeamTargets
DESTINATION lib)
DESTINATION ${INSTALL_LIBDIR})
#install oskar coefficients
install(FILES "${CMAKE_SOURCE_DIR}/coeffs/oskar.h5"
DESTINATION ${EVERYBEAM_DATADIR})
install(
FILES "${CMAKE_SOURCE_DIR}/coeffs/oskar.h5"
COMPONENT data-files
DESTINATION ${EVERYBEAM_INSTALL_DATADIR})
......@@ -18,5 +18,6 @@ target_include_directories(
# install libeverybeam-skamidbeam.so
install(
TARGETS skamidbeam
COMPONENT libraries
EXPORT EveryBeamTargets
DESTINATION lib)
DESTINATION ${INSTALL_LIBDIR})
#########################
# build-system settings #
#########################
[build-system]
requires = [
"build",
"cmake>=3.18",
"oldest-supported-numpy",
"setuptools",
"wheel",
"scikit-build-core",
]
build-backend = "scikit_build_core.build"
####################
# project settings #
####################
[project]
name = "everybeam"
version = "0.5.3" # Keep in sync with top-level `CMakeLists.txt` file
description = "EveryBeam"
readme = {file = "README.md", content-type = "text/markdown"}
requires-python = ">=3.7"
license = {text = "GPLv3+"}
authors = [
{name = "Bram Veenboer", email = "veenboer@astron.nl"},
{name = "André Offringa", email = "offringa@astron.nl"},
{name = "Sebastiaan van der Tol", email = "tol@astron.nl"},
{name = "Tammo Jan Dijkema", email = "dijkema@astron.nl"},
{name = "Jakob Maljaars", email = "jakob.maljaars@stcorp.nl"},
{name = "Maik Nijhuis", email = "maik.nijhuis@triopsys.nl"},
]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Programming Language :: C++",
"Programming Language :: Python :: 3",
"Topic :: Scientific/Engineering :: Astronomy",
]
dependencies = [
"numpy",
]
[project.urls]
Homepage = "https://git.astron.nl/RD/EveryBeam/"
Documentation = "https://everybeam.readthedocs.io/"
Repository = "https://git.astron.nl/RD/EveryBeam.git"
#########################
# cibuildwheel settings #
#########################
[tool.cibuildwheel]
## Build
before-all = "cibuildwheel/before_all.sh"
before-build = "cibuildwheel/before_build.sh"
build = "cp3{7,8,9,10,11}-*_x86_64"
build-verbosity = 1
environment = """ \
WORKDIR="/tmp" \
FFTW_VERSION="3.3.8" \
HDF5_VERSION="1.12.2" \
"""
# test-command = "cd {package}/python/test && pytest"
## Test
before-test = [
"scripts/download_ms.sh lba.MS.tar.bz2 LOFAR_LBA_MOCK.ms",
"scripts/download_ms.sh L258627-one-timestep.tar.bz2 LOFAR_HBA_MOCK.ms",
]
test-command = [
"export DATA_DIR={project}",
"export EVERYBEAM_DATADIR=$(dirname $(which python))/../share/everybeam",
"pytest -v {package}/python/test/test_pybindings.py"
]
test-requires = "pytest-lazy-fixture"
[tool.cibuildwheel.macos]
repair-wheel-command = """\
......@@ -47,3 +100,17 @@ manylinux-x86_64-image = "quay.io/casacore/casacore:master_wheel310"
[[tool.cibuildwheel.overrides]]
select="cp311-*"
manylinux-x86_64-image = "quay.io/casacore/casacore:master_wheel311"
#########################
# scikit-build settings #
#########################
[tool.scikit-build]
cmake.minimum-version = "3.15"
ninja.minimum-version = "1.5"
install.components = ["data-files", "libraries"]
logging.level = "INFO"
[tool.scikit-build.cmake.define]
BUILD_WITH_PYTHON = "ON"
......@@ -36,16 +36,25 @@ target_include_directories(pyeverybeam
PUBLIC "$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/cpp>")
target_link_libraries(pyeverybeam PUBLIC everybeam)
set_target_properties(pyeverybeam PROPERTIES OUTPUT_NAME everybeam)
if(SKBUILD)
set_target_properties(pyeverybeam PROPERTIES INSTALL_RPATH
"$ORIGIN/${INSTALL_LIBDIR}")
endif()
# If the PYTHON_LIBRARY_DIR is not specified, install in lib dir
if(NOT DEFINED ${PYTHON_LIBRARY_DIR})
# Define where the python module will be installed. When using scikit-build,
# it must be the current directory; otherwise, use site-packages directory.
if(NOT DEFINED PYTHON_LIBRARY_DIR)
if(DEFINED SKBUILD)
set(PYTHON_LIBRARY_DIR .)
else()
execute_process(
COMMAND ${PYTHON_EXECUTABLE} -c
"import site; print(site.getsitepackages()[0])"
OUTPUT_VARIABLE PYTHON_DIST_PATH
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(PYTHON_DIST_PATH MATCHES
if(PYTHON_DIST_PATH
MATCHES
"\\/(lib.*\\/python${PYTHON_VERSION_MAJOR}\\.${PYTHON_VERSION_MINOR}\\/.*)"
)
set(PYTHON_LIBRARY_DIR ${CMAKE_MATCH_1})
......@@ -54,9 +63,10 @@ if(NOT DEFINED ${PYTHON_LIBRARY_DIR})
FATAL_ERROR "Failed to parse PYTHON_DIST_PATH='${PYTHON_DIST_PATH}'")
endif()
endif()
endif()
# Install pyeverybeam in site-packages directory
install(
TARGETS pyeverybeam
COMPONENT python
COMPONENT libraries
LIBRARY DESTINATION ${PYTHON_LIBRARY_DIR})
#!/usr/bin/env python
# coding: utf-8
# Copyright (c) 2016 The Pybind Development Team, All rights reserved.
# Setup.py that calls CMake. Largely taken from https://github.com/pybind/cmake_example/
import os
import re
import subprocess
import sys
from setuptools import Extension, setup
from setuptools.command.build_ext import build_ext
# Set the location where data files are to be installed
EVERYBEAM_DATADIR = os.path.join("share", "everybeam")
# A CMakeExtension needs a sourcedir instead of a file list.
# The name must be the _single_ output extension from the CMake build.
# If you need multiple extensions, see scikit-build.
class CMakeExtension(Extension):
def __init__(self, name, sourcedir=""):
Extension.__init__(self, name, sources=[])
self.sourcedir = os.path.abspath(sourcedir)
class CMakeBuild(build_ext):
def build_extension(self, ext):
extdir = os.path.abspath(
os.path.dirname(self.get_ext_fullpath(ext.name))
)
# required for auto-detection & inclusion of auxiliary "native" libs
if not extdir.endswith(os.path.sep):
extdir += os.path.sep
debug = (
int(os.environ.get("DEBUG", 0))
if self.debug is None
else self.debug
)
cfg = "Debug" if debug else "Release"
# CMake lets you override the generator - we need to check this.
# Can be set with Conda-Build, for example.
cmake_generator = os.environ.get("CMAKE_GENERATOR", "")
# Set Python_EXECUTABLE instead if you use PYBIND11_FINDPYTHON
cmake_args = [
f"-DCMAKE_LIBRARY_OUTPUT_DIRECTORY={extdir}",
f"-DPYTHON_EXECUTABLE={sys.executable}",
f"-DCMAKE_BUILD_TYPE={cfg}", # not used on MSVC, but no harm
]
build_args = []
# Adding CMake arguments set as environment variable
# (needed e.g. to build for ARM OSx on conda-forge)
if "CMAKE_ARGS" in os.environ:
cmake_args += [
item for item in os.environ["CMAKE_ARGS"].split(" ") if item
]
# Adding CMake arguments specific to building EveryBeam
cmake_args += [
"-DBUILD_WITH_PYTHON=On",
f"-DEVERYBEAM_DATADIR={EVERYBEAM_DATADIR}",
]
# Using Ninja-build since it a) is available as a wheel and b)
# multithreads automatically. MSVC would require all variables be
# exported for Ninja to pick it up, which is a little tricky to do.
# Users can override the generator with CMAKE_GENERATOR in CMake
# 3.15+.
if not cmake_generator or cmake_generator == "Ninja":
try:
import ninja # noqa: F401
ninja_executable_path = os.path.join(ninja.BIN_DIR, "ninja")
cmake_args += [
"-GNinja",
f"-DCMAKE_MAKE_PROGRAM:FILEPATH={ninja_executable_path}",
]
except ImportError:
pass
if sys.platform.startswith("darwin"):
# Cross-compile support for macOS - respect ARCHFLAGS if set
archs = re.findall(r"-arch (\S+)", os.environ.get("ARCHFLAGS", ""))
if archs:
cmake_args += [
"-DCMAKE_OSX_ARCHITECTURES={}".format(";".join(archs))
]
# Set CMAKE_BUILD_PARALLEL_LEVEL to control the parallel build level
# across all generators.
if "CMAKE_BUILD_PARALLEL_LEVEL" not in os.environ:
# self.parallel is a Python 3 only way to set parallel jobs by hand
# using -j in the build_ext call, not supported by pip or PyPA-build.
if hasattr(self, "parallel") and self.parallel:
# CMake 3.12+ only.
build_args += [f"-j{self.parallel}"]
build_temp = os.path.join(self.build_temp, ext.name)
if not os.path.exists(build_temp):
os.makedirs(build_temp)
subprocess.check_call(["which", "g++"])
subprocess.check_call(
["cmake", ext.sourcedir] + cmake_args, cwd=build_temp
)
subprocess.check_call(
["cmake", "--build", "."] + build_args, cwd=build_temp
)
# Install the coefficient files in a location outside the python package --
# <prefix>/share/everbeam, where <prefix> is the python install prefix --
# which makes them easier to find for other programs.
data_files = []
for root, _, files in os.walk("coeffs"):
data_files.append(
(
EVERYBEAM_DATADIR,
[os.path.join(root, f) for f in files],
)
)
# The information here can also be placed in setup.cfg - better separation of
# logic and declaration, and simpler if you include description/version in a file.
setup(
name="everybeam",
version="0.5.1",
author="André Offringa",
author_email="offringa@astron.nl",
description="EveryBeam",
long_description=open("README.md", "rt").read(),
long_description_content_type="text/markdown",
ext_modules=[CMakeExtension("everybeam")],
cmdclass={"build_ext": CMakeBuild},
zip_safe=False,
python_requires=">=3.6",
install_requires=["numpy"],
url="https://everybeam.readthedocs.io/",
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Programming Language :: C++",
"Programming Language :: Python :: 3",
"Topic :: Scientific/Engineering :: Astronomy",
],
data_files=data_files,
)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment