Skip to content

Commit

Permalink
numpy: add new recipe
Browse files Browse the repository at this point in the history
  • Loading branch information
valgur committed Mar 21, 2024
1 parent c8aa3f2 commit a2d26a0
Show file tree
Hide file tree
Showing 7 changed files with 292 additions and 0 deletions.
9 changes: 9 additions & 0 deletions recipes/numpy/all/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
sources:
"1.26.0":
url: "https://github.com/numpy/numpy/releases/download/v1.26.0/numpy-1.26.0.tar.gz"
sha256: "f93fc78fe8bf15afe2b8d6b6499f1c73953169fad1e9a8dd086cdff3190e7fdf"
patches:
"1.26.0":
- patch_file: "patches/1.26.0-patch-meson.patch"
patch_description: ""
patch_type: "conan"
93 changes: 93 additions & 0 deletions recipes/numpy/all/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
import os

from conan import ConanFile
from conan.tools.apple import fix_apple_shared_install_name
from conan.tools.env import Environment
from conan.tools.files import copy, export_conandata_patches, get, apply_conandata_patches, rmdir, move_folder_contents, mkdir
from conan.tools.gnu import PkgConfigDeps
from conan.tools.layout import basic_layout
from conan.tools.meson import Meson, MesonToolchain
from conan.tools.scm import Version

required_conan_version = ">=1.53.0"


class PackageConan(ConanFile):
name = "numpy"
description = "NumPy is the fundamental package for scientific computing with Python."
license = "BSD 3-Clause"
url = "https://github.com/conan-io/conan-center-index"
homepage = "https://numpy.org/doc/stable/reference/c-api/coremath.html"
topics = ("ndarray", "array", "linear algebra", "npymath", "npyrandom")

package_type = "static-library"
settings = "os", "arch", "compiler", "build_type"
options = {
"fPIC": [True, False],
}
default_options = {
"fPIC": True,
}

def export_sources(self):
export_conandata_patches(self)

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def configure(self):
self.settings.rm_safe("compiler.libcxx")
self.settings.rm_safe("compiler.cppstd")

def layout(self):
basic_layout(self, src_folder="src")

def requirements(self):
self.requires("openblas/0.3.20")
self.requires("cpython/3.10.0", transitive_headers=True, transitive_libs=True)

def build_requirements(self):
if not self.conf.get("tools.gnu:pkg_config", default=False, check_type=str):
self.tool_requires("pkgconf/2.0.3")

def source(self):
get(self, **self.conan_data["sources"][self.version], strip_root=True)

def generate(self):
# NumPy can only be built with its vendored Meson
env = Environment()
env.prepend_path("PATH", os.path.join(self.source_folder, "vendored-meson", "entrypoint"))
env.vars(self).save_script("conanbuild_meson")
tc = MesonToolchain(self)
tc.generate()
tc = PkgConfigDeps(self)
tc.generate()

def build(self):
apply_conandata_patches(self)
meson = Meson(self)
meson.configure()
meson.build()

def package(self):
copy(self, "LICENSE*.txt", dst=os.path.join(self.package_folder, "licenses"), src=self.source_folder)
meson = Meson(self)
meson.install()
python_minor = Version(self.dependencies["cpython"].ref.version).minor
pkg_root = os.path.join(self.package_folder, "lib", f"python3.{python_minor}", "site-packages", "numpy")
copy(self, "*.a", pkg_root, dst=os.path.join(self.package_folder, "lib"), keep_path=False)
mkdir(self, os.path.join(self.package_folder, "include"))
move_folder_contents(self, os.path.join(pkg_root, "core", "include"), os.path.join(self.package_folder, "include"))
rmdir(self, os.path.join(self.package_folder, "lib", f"python3.{python_minor}"))
fix_apple_shared_install_name(self)

def package_info(self):
self.cpp_info.components["npymath"].set_property("pkg_config_name", "npymath")
self.cpp_info.components["npymath"].libs = ["npymath", "npyrandom"]
self.cpp_info.components["npymath"].requires = [
"openblas::openblas",
"cpython::cpython"
]
if self.settings.os in ["Linux", "FreeBSD"]:
self.cpp_info.components["npymath"].system_libs = ["m"]
131 changes: 131 additions & 0 deletions recipes/numpy/all/patches/1.26.0-patch-meson.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
--- meson.build
+++ meson.build
@@ -22,7 +22,6 @@

cc = meson.get_compiler('c')
cpp = meson.get_compiler('cpp')
-cy = meson.get_compiler('cython')

# Check compiler is recent enough (see the SciPy Toolchain Roadmap for details)
if cc.get_id() == 'gcc'
@@ -34,9 +33,6 @@
error('NumPy requires at least vc142 (default with Visual Studio 2019) ' + \
'when building with MSVC')
endif
-endif
-if not cy.version().version_compare('>=0.29.34')
- error('NumPy requires Cython >= 0.29.34')
endif

py = import('python').find_installation(pure: false)
--- numpy/meson.build
+++ numpy/meson.build
@@ -265,18 +265,11 @@
'py.typed'
]

-py.install_sources(
- python_sources,
- subdir: 'numpy'
-)
-
src_file_cli = find_program('_build_utils/process_src_template.py')
src_file = generator(src_file_cli,
arguments : ['@INPUT@', '--outfile', '@OUTPUT@'],
output : '@BASENAME@'
)
-
-tempita_cli = find_program('_build_utils/tempita.py')

pure_subdirs = [
'_pyinstaller',
@@ -300,34 +293,6 @@

np_dir = py.get_install_dir() / 'numpy'

-# Generate version.py for sdist
-meson.add_dist_script(
- ['_build_utils/gitversion.py', '--meson-dist', '--write',
- 'numpy/version.py']
-)
-if not fs.exists('version.py')
- generate_version = custom_target(
- 'generate-version',
- install: true,
- build_always_stale: true,
- build_by_default: true,
- output: 'version.py',
- input: '_build_utils/gitversion.py',
- command: [py, '@INPUT@', '--write', '@OUTPUT@'],
- install_dir: np_dir
- )
-else
- # When building from sdist, version.py exists and should be included
- py.install_sources(
- ['version.py'],
- subdir : 'numpy'
- )
-endif
-
-foreach subdir: pure_subdirs
- install_subdir(subdir, install_dir: np_dir)
-endforeach
-
compilers = {
'C': cc,
'CPP': cpp,
@@ -401,14 +366,5 @@
endif
endforeach

-configure_file(
- input: '__config__.py.in',
- output: '__config__.py',
- configuration : conf_data,
- install_dir: np_dir,
-)
-
subdir('core')
-subdir('fft')
-subdir('linalg')
subdir('random')

--- numpy/random/meson.build
+++ numpy/random/meson.build
@@ -18,31 +18,6 @@
name_suffix: name_suffix_staticlib,
)

-# Build Cython extensions for numpy.random
-# ----------------------------------------
-# pyx -> c transpile output depends on copied __init__.py and pxd files
-_cython_tree_random = [
- fs.copyfile('__init__.py'),
- fs.copyfile('__init__.pxd'),
- fs.copyfile('_common.pxd'),
- fs.copyfile('bit_generator.pxd'),
- fs.copyfile('c_distributions.pxd'),
-]
-# Need to use `custom_target` because we need to install this .pxd file
-_cython_tree_random += custom_target('_bounded_integer_pxd',
- output: '_bounded_integers.pxd',
- input: '_bounded_integers.pxd.in',
- command: [tempita_cli, '@INPUT@', '-o', '@OUTPUT@'],
- install: true,
- install_dir: np_dir / 'random'
-)
-
-_bounded_integers_pyx = custom_target('_bounded_integer_pyx',
- output: '_bounded_integers.pyx',
- input: '_bounded_integers.pyx.in',
- command: [tempita_cli, '@INPUT@', '-o', '@OUTPUT@'],
-)
-
c_args_random = [
cflags_large_file_support,
'-DNPY_NO_DEPRECATED_API=0', # Cython still uses old NumPy C API
@@ -50,3 +25,4 @@
if host_machine.system() == 'cygwin'
c_args_random += ['-Wl,--export-all-symbols']
endif
+subdir_done()
32 changes: 32 additions & 0 deletions recipes/numpy/all/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
from conan import ConanFile
from conan.tools.build import can_run
from conan.tools.layout import basic_layout
from conan.tools.meson import Meson
import os


class TestPackageConan(ConanFile):
settings = "os", "arch", "compiler", "build_type"
generators = "PkgConfigDeps", "MesonToolchain", "VirtualRunEnv", "VirtualBuildEnv"
test_type = "explicit"

def layout(self):
basic_layout(self)

def requirements(self):
self.requires(self.tested_reference_str)

def build_requirements(self):
self.tool_requires("meson/1.2.1")
if not self.conf.get("tools.gnu:pkg_config", default=False, check_type=str):
self.tool_requires("pkgconf/2.0.3")

def build(self):
meson = Meson(self)
meson.configure()
meson.build()

def test(self):
if can_run(self):
bin_path = os.path.join(self.cpp.build.bindir, "test_package")
self.run(bin_path, env="conanrun")
5 changes: 5 additions & 0 deletions recipes/numpy/all/test_package/meson.build
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
project('test_package', 'c')
package_dep = dependency('npymath')
executable('test_package',
sources : ['test_package.c'],
dependencies : [package_dep])
19 changes: 19 additions & 0 deletions recipes/numpy/all/test_package/test_package.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Based on https://github.com/numpy/numpy/blob/v1.26.0/numpy/core/tests/examples/limited_api/limited_api.c

#define Py_LIMITED_API 0x03060000

#include <Python.h>
#include <numpy/arrayobject.h>
#include <numpy/ufuncobject.h>

static PyModuleDef moduledef = {
.m_base = PyModuleDef_HEAD_INIT,
.m_name = "limited_api"
};

PyMODINIT_FUNC PyInit_limited_api(void)
{
import_array();
import_umath();
return PyModule_Create(&moduledef);
}
3 changes: 3 additions & 0 deletions recipes/numpy/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"1.26.0":
folder: all

0 comments on commit a2d26a0

Please sign in to comment.