Skip to content

Commit 40c035f

Browse files
committed
Added infrastructure to compile numpy.
1 parent 6b5a0b4 commit 40c035f

File tree

4 files changed

+203
-1
lines changed

4 files changed

+203
-1
lines changed

Makefile

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -330,7 +330,7 @@ XZ_FRAMEWORK-$1=build/$1/Support/XZ
330330
PYTHON_FRAMEWORK-$1=build/$1/Support/Python
331331
PYTHON_RESOURCES-$1=$$(PYTHON_FRAMEWORK-$1)/Resources
332332

333-
$1: dist/Python-$(PYTHON_VER)-$1-support.b$(BUILD_NUMBER).tar.gz
333+
$1: dist/Python-$(PYTHON_VER)-$1-support.b$(BUILD_NUMBER).tar.gz packages-$1
334334

335335
clean-$1:
336336
rm -rf build/$1
@@ -448,6 +448,39 @@ build/$1/libpython$(PYTHON_VER)m.a: $$(foreach target,$$(TARGETS-$1),$$(PYTHON_D
448448
# Create a fat binary for the libPython library
449449
mkdir -p build/$1
450450
xcrun lipo -create -output $$@ $$^
451+
452+
vars-$1: $$(foreach target,$$(TARGETS-$1),vars-$$(target))
453+
451454
endef
452455

453456
$(foreach os,$(OS),$(eval $(call build,$(os))))
457+
458+
###########################################################################
459+
# Compiling Python Libraries with binary components
460+
###########################################################################
461+
462+
HOST_PYTHON=$(CURDIR)/build/macOS/python/bin/python3
463+
HOST_PIP=$(CURDIR)/build/macOS/python/bin/pip3
464+
465+
# Ensure pip and setuptools are available
466+
pip: Python-macOS
467+
$(HOST_PYTHON) -m ensurepip
468+
469+
# Create the directory that will contain installed packages
470+
dist/app_packages:
471+
mkdir -p dist/app_packages
472+
473+
# Makefiles for individual binary packages that are supported.
474+
include patch/numpy/Makefile.numpy
475+
476+
define build-app-packages
477+
packages-$1: numpy-$1
478+
endef
479+
480+
$(foreach os,$(OS),$(eval $(call build-app-packages,$(os))))
481+
482+
app_packages: numpy
483+
484+
# Dump vars (for test)
485+
vars: $(foreach os,$(OS),vars-$(os))
486+
@echo "APP_PACKAGES: $(APP_PACKAGES)"

README.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,40 @@ This should:
4949
The build products will be in the `build` directory; the compiled frameworks
5050
will be in the `dist` directory.
5151

52+
Binary packages
53+
---------------
54+
55+
These tools are also able to compile the following packages that have binary
56+
components:
57+
58+
* numpy
59+
60+
These binary components are not compiled by default. However, the build
61+
infrastructure of this project can compile them on request. You can run::
62+
63+
make <name of package>
64+
65+
to build a specific package; or, to build all supported packages::
66+
67+
make app_packages
68+
69+
This will produce:
70+
71+
* a folder named `dist/app_packages`, containing the python code required by
72+
the package
73+
* a folder for each supported mobile platform (iOS, tvOS and watchOS)
74+
containing the static fat binary libraries needed to support the Python
75+
code.
76+
77+
Once these artefacts have been compiled:
78+
79+
* Copy the contents of `dist/app_packages` into your project's `site_packages`
80+
or `app_packages` directory. This will make the Python library available to
81+
your project; and
82+
* Add the static binary libraries in the platform directory (e.g., the contents
83+
of `dist/iOS`) as static libraries in your project.
84+
85+
5286
.. _for macOS: https://s3-us-west-2.amazonaws.com/pybee-briefcase-support/Python-Apple-support/3.6/macOS/Python-3.6-macOS-support.b6.tar.gz
5387
.. _for iOS: https://s3-us-west-2.amazonaws.com/pybee-briefcase-support/Python-Apple-support/3.6/iOS/Python-3.6-iOS-support.b6.tar.gz
5488
.. _for tvOS: https://s3-us-west-2.amazonaws.com/pybee-briefcase-support/Python-Apple-support/3.6/tvOS/Python-3.6-tvOS-support.b6.tar.gz

patch/numpy/Makefile.numpy

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
###########################################################################
2+
# NumPy
3+
###########################################################################
4+
5+
NUMPY_VERSION=1.9.1
6+
NUMPY_CONFIG=BLAS=None LAPACK=None ATLAS=None
7+
8+
# Download original numpy source code archive.
9+
downloads/numpy-$(NUMPY_VERSION).tgz:
10+
mkdir -p downloads
11+
# if [ ! -e downloads/numpy-$(NUMPY_VERSION).tgz ]; then curl --fail -L https://github.com/numpy/numpy/releases/download/v$(NUMPY_VERSION)/numpy-$(NUMPY_VERSION).tar.gz -o downloads/numpy-$(NUMPY_VERSION).tgz; fi
12+
if [ ! -e downloads/numpy-$(NUMPY_VERSION).tgz ]; then curl --fail -L https://github.com/numpy/numpy/archive/v$(NUMPY_VERSION).tar.gz -o downloads/numpy-$(NUMPY_VERSION).tgz; fi
13+
14+
define build-numpy-target
15+
NUMPY-CFLAGS-$1=$$(CFLAGS-$2)
16+
NUMPY-CC-$1=xcrun --sdk $$(SDK-$1) clang \
17+
-arch $$(ARCH-$1) \
18+
--sysroot=$$(SDK_ROOT-$1) \
19+
$$(NUMPY_CFLAGS-$1)
20+
21+
build/$2/packages/numpy/build/temp.$1-$(PYTHON_VER)/libpymath.a: build/$2/packages/numpy
22+
cd build/$2/packages/numpy && \
23+
CC="$$(NUMPY-CC-$1)" \
24+
CFLAGS="$$(NUMPY-CFLAGS-$1)" \
25+
$(NUMPY_CONFIG) \
26+
_PYTHON_HOST_PLATFORM=$1 \
27+
$(HOST_PYTHON) setup.py build_ext
28+
29+
build/$2/packages/numpy/build/temp.$1-$(PYTHON_VER)/libnumpy.a: build/$2/packages/numpy/build/temp.$1-$(PYTHON_VER)/libpymath.a
30+
cd build/$2/packages/numpy/build/temp.$1-$(PYTHON_VER) && \
31+
xcrun --sdk $$(SDK-$1) ar -q libnumpy.a `find . -name "*.o"`
32+
33+
numpy-$1: build/$2/packages/numpy/build/temp.$1-$(PYTHON_VER)/libnumpy.a
34+
35+
endef
36+
37+
define build-numpy
38+
$$(foreach target,$$(TARGETS-$1),$$(eval $$(call build-numpy-target,$$(target),$1)))
39+
40+
build/$1/packages/numpy: downloads/numpy-$(NUMPY_VERSION).tgz
41+
# Unpack numpy sources
42+
mkdir -p build/$1/packages/numpy
43+
tar zxf downloads/numpy-$(NUMPY_VERSION).tgz --strip-components 1 -C build/$1/packages/numpy
44+
# Apply patch
45+
cd build/$1/packages/numpy && patch -p1 -i $(PROJECT_DIR)/patch/numpy/numpy.patch
46+
# Install requirements for compiling Numpy
47+
$(HOST_PIP) install cython
48+
49+
ifeq ($1,macOS)
50+
# Use the macOS build as a reference installation
51+
# Just install the source as-is into the dist/app_packages directory
52+
# Then clean out all the binary artefacts
53+
54+
dist/app_packages/numpy: dist/app_packages build/$1/packages/numpy
55+
cd build/$1/packages/numpy && \
56+
$(NUMPY_CONFIG) $(HOST_PIP) install --target $(PROJECT_DIR)/dist/app_packages .
57+
find build/$1/packages/numpy -name "*.so" -exec rm {} \;
58+
59+
numpy-$1: dist/app_packages/numpy
60+
61+
else
62+
# For all other platforms, run the numpy build for each target architecture
63+
64+
dist/$1/libnumpy.a: $(foreach target,$(TARGETS-$1),numpy-$(target))
65+
mkdir -p dist/$1
66+
xcrun lipo -create -output dist/$1/libnpymath.a $(foreach target,$(TARGETS-$1),build/$1/packages/numpy/build/temp.$(target)-$(PYTHON_VER)/libnpymath.a)
67+
xcrun lipo -create -output dist/$1/libnpysort.a $(foreach target,$(TARGETS-$1),build/$1/packages/numpy/build/temp.$(target)-$(PYTHON_VER)/libnpysort.a)
68+
xcrun lipo -create -output dist/$1/libnumpy.a $(foreach target,$(TARGETS-$1),build/$1/packages/numpy/build/temp.$(target)-$(PYTHON_VER)/libnumpy.a)
69+
70+
numpy-$1: dist/$1/libnumpy.a
71+
72+
endif
73+
endef
74+
75+
# Call build-numpy for each packaged OS target
76+
$(foreach os,$(OS),$(eval $(call build-numpy,$(os))))
77+
78+
# Main entry point
79+
numpy: pip $(foreach os,$(OS),numpy-$(os))

patch/numpy/numpy.patch

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
diff -Naur numpy-1.9.1.orig/numpy/core/include/numpy/npy_endian.h numpy-1.9.1.ios/numpy/core/include/numpy/npy_endian.h
2+
--- numpy-1.9.1.orig/numpy/core/include/numpy/npy_endian.h 2014-10-26 15:36:14.000000000 +0100
3+
+++ numpy-1.9.1.ios/numpy/core/include/numpy/npy_endian.h 2014-11-24 01:59:52.000000000 +0100
4+
@@ -6,7 +6,10 @@
5+
* endian.h
6+
*/
7+
8+
-#ifdef NPY_HAVE_ENDIAN_H
9+
+
10+
+//#ifdef NPY_HAVE_ENDIAN_H
11+
+//XXX iOS fix, it detects endian.h, but weird detection happen during the compilation
12+
+#if 0
13+
/* Use endian.h if available */
14+
#include <endian.h>
15+
16+
diff -Naur numpy-1.9.1.orig/numpy/core/setup.py numpy-1.9.1.ios/numpy/core/setup.py
17+
--- numpy-1.9.1.orig/numpy/core/setup.py 2014-10-26 17:22:33.000000000 +0100
18+
+++ numpy-1.9.1.ios/numpy/core/setup.py 2014-11-24 01:58:43.000000000 +0100
19+
@@ -951,6 +951,9 @@
20+
blas_info = get_info('blas_opt', 0)
21+
#blas_info = {}
22+
def get_dotblas_sources(ext, build_dir):
23+
+ # XXX no blas for iOS, maybe it's not needed anymore as our recipe do
24+
+ # BLAS=None
25+
+ return None
26+
if blas_info:
27+
if ('NO_ATLAS_INFO', 1) in blas_info.get('define_macros', []):
28+
return None # dotblas needs ATLAS, Fortran compiled blas will not be sufficient.
29+
diff -Naur numpy-1.9.1.orig/numpy/linalg/setup.py numpy-1.9.1.ios/numpy/linalg/setup.py
30+
--- numpy-1.9.1.orig/numpy/linalg/setup.py 2014-10-26 15:36:15.000000000 +0100
31+
+++ numpy-1.9.1.ios/numpy/linalg/setup.py 2014-11-24 01:57:48.000000000 +0100
32+
@@ -34,8 +34,14 @@
33+
return ext.depends[:1]
34+
return ext.depends[:2]
35+
36+
+ def get_lapack_lite_sources_ios(ext, build_dir):
37+
+ return ext.depends[:-1]
38+
+
39+
+ def get_umath_linalg_ios(ext, build_dir):
40+
+ return ext.depends[:1]
41+
+
42+
config.add_extension('lapack_lite',
43+
- sources = [get_lapack_lite_sources],
44+
+ sources = [get_lapack_lite_sources_ios],
45+
depends = ['lapack_litemodule.c'] + lapack_lite_src,
46+
extra_info = lapack_info
47+
)
48+
@@ -43,7 +49,7 @@
49+
# umath_linalg module
50+
51+
config.add_extension('_umath_linalg',
52+
- sources = [get_lapack_lite_sources],
53+
+ sources = [get_umath_linalg_ios],
54+
depends = ['umath_linalg.c.src'] + lapack_lite_src,
55+
extra_info = lapack_info,
56+
libraries = ['npymath'],

0 commit comments

Comments
 (0)