APKBUILD examples:Python: Difference between revisions
(→Multiversion package without executables: do the install in package() and clean up py2 deps vs py3 deps) |
No edit summary |
||
Line 47: | Line 47: | ||
If the project supports only Python 3 (or 2), then the APKBUILD is very simple: | If the project supports only Python 3 (or 2), then the APKBUILD is very simple: | ||
< | <code> | ||
pkgname="py3-foo" | pkgname="py3-foo" | ||
_pyname="foo" | _pyname="foo" | ||
Line 69: | Line 69: | ||
python3 setup.py install --prefix=/usr --root="$pkgdir" | python3 setup.py install --prefix=/usr --root="$pkgdir" | ||
} | } | ||
</ | </code> | ||
Line 77: | Line 77: | ||
If the build modifies source code, e.g. using 2to3, read the last section! | If the build modifies source code, e.g. using 2to3, read the last section! | ||
< | <code> | ||
pkgname="py-foo" | pkgname="py-foo" | ||
_pyname="PyFoo" | _pyname="PyFoo" | ||
Line 123: | Line 123: | ||
_py python3 | _py python3 | ||
} | } | ||
</ | </code> | ||
=== Multiversion package with executables === | === Multiversion package with executables === | ||
Line 132: | Line 132: | ||
'''Note:''' This is just mere workaround that will not be needed in future once we add needed features to apk. | '''Note:''' This is just mere workaround that will not be needed in future once we add needed features to apk. | ||
< | <code> | ||
pkgname="py-foo" | pkgname="py-foo" | ||
_pyname="PyFoo" | _pyname="PyFoo" | ||
Line 182: | Line 182: | ||
done | done | ||
} | } | ||
</ | </code> | ||
Revision as of 14:59, 12 April 2019
A lot of Python packages use the setuptools or distutils framework. This mean that the build() and the package() section looks a bit different compared to an application which uses make.
Considerations
Python 2 vs. Python 3
Python 3 should be the default option. If the project support both Python 2 and Python 3, then the Alpine package may provide both variants as py2- and py3- subpackages. However, add py2 variant only when you really need it. Python 2 is legacy and will be deprecated soon. You may omit py2 variant, but never omit py3 variant if it's supported by the project.
pkgname
Package name for a Python library must be prefixed with py-, py2-, or py3-.
- py-
- Use if the project supports both Python 2 and Python 3, even if it does not support Python 3 yet, but may in future.
- py2-
- TODO
- py3-
- Use if the project does not support Python 2.
There’s no exact rule if the prefix should be used for tools and applications written in Python, it varies.
arch
- noarch
- Use for pure Python packages (i.e. without compiled code). Also add python2, or python3 to depends=.
- all (and others)
- Use for packages with native extensions (i.e. with compiled code). Do not add python2/python3 to depends= (it's auto-detected via dynamic linking to python library).
source
Basically all Python are published in PyPI (the Python Package Index). If the package has a source tarball available in PyPI (that’s true for most packages), you should reference it in source= as:
https://files.pythonhosted.org/packages/source/${_pyname%${_pyname#?}}/$_pyname/$_pyname-$pkgver.tar.gz
where _pyname is a real name of the Python package.
Examples
Comments marked with ## should not be copied into final APKBUILD!
Package for single Python version
If the project supports only Python 3 (or 2), then the APKBUILD is very simple:
pkgname="py3-foo"
_pyname="foo"
...
depends="python3"
makedepends="python3-dev"
...
build() {
cd "$builddir"
python3 setup.py build
}
check() {
cd "$builddir"
python3 setup.py test
}
package() {
cd "$builddir"
python3 setup.py install --prefix=/usr --root="$pkgdir"
}
Multiversion package without executables
Use this variant if the package does not install any files outside of /usr/lib/pythonX.Y/site-packages. If the build modifies source code, e.g. using 2to3, read the last section!
pkgname="py-foo"
_pyname="PyFoo"
...
_py2deps="python2 py2-bar py2-baz"
_py3deps="python3 py3-bar py3-baz"
makedepends="python2-dev python3-dev"
subpackages="py2-${pkgname#py-}:_py2 py3-${pkgname#py-}:_py3"
...
build() {
cd "$builddir"
python2 setup.py build
python3 setup.py build
}
check() {
cd "$builddir"
python2 setup.py test
python3 setup.py test
}
package() {
cd "$builddir"
python2 setup.py install --prefix=/usr --root="$pkgdir"
python3 setup.py install --prefix=/usr --root="$pkgdir"
}
_py() {
local python="$1"
pkgdesc="$pkgdesc (for $python)"
install_if="$pkgname=$pkgver-r$pkgrel $python"
mkdir -p "$subpkgdir"/usr/lib/
mv "$pkgdir"/usr/lib/$python* "$subpkgdir"
}
_py2() {
depends="$_py2deps"
_py python2
}
_py3() {
depends="$_py3deps"
_py python3
}
Multiversion package with executables
Use this variant if the packages installs some executables into /usr/bin. If the build modifies source code, e.g. using 2to3, read the last section!
Note: This is just mere workaround that will not be needed in future once we add needed features to apk.
pkgname="py-foo"
_pyname="PyFoo"
...
depends="py-bar py-baz"
makedepends="python2-dev python3-dev py-setuptools"
subpackages="py2-${pkgname#py-}:_py2 py3-${pkgname#py-}:_py3"
...
build() {
cd "$builddir"
python2 setup.py build
python3 setup.py build
}
package() {
mkdir -p "$pkgdir"/usr/bin
# Create unsuffixed symlinks for executables from py3 subpackage.
local name; for name in foo bar baz; do
ln -s $name-3 "$pkgdir"/usr/bin/$name
done
}
_py2() {
replaces="$pkgname" ## remove if you're writing a new aport (and always remove this comment!)
depends="${depends//py-/py2-}" ## remove if there are no common Python dependencies, i.e. above depends= is empty/undefined (and always remove this comment!)
_py python2
}
_py3() {
depends="${depends//py-/py3-}" ## remove if there are no common Python dependencies, i.e. above depends= is empty/undefined (and always remove this comment!)
_py python3
}
_py() {
local python="$1"
local pyver="${1:6:1}"
pkgdesc="$pkgdesc (for $python)"
depends="$depends $python" ## remove if arch isn't noarch (and always remove this comment!)
install_if="$pkgname=$pkgver-r$pkgrel $python"
cd "$builddir"
$python setup.py install --prefix=/usr --root="$subpkgdir"
# Add version suffix to executable files.
local path; for path in "$subpkgdir"/usr/bin/*; do
mv "$path" "$path-$pyver"
done
}
Multiversion package for project using 2to3
Some Python projects use 2to3 (or similar tools) during build phase to make the code-base compatible with Python 3. Since it modifies sources during build, you cannot run setup.py build with python2 and python3 one after another with the same source files. You must duplicate the buildir and run them separately.
prepare() { default_prepare # Soure files are modified during build with 2to3 tool, so we cannot # build it for both Python versions in the same location. local python; for python in python2 python3; do cp -r "$builddir" "$builddir-$python" done } build() { local python; for python in python2 python3; do cd "$builddir"-$python $python setup.py build done } _py() { ... cd "$builddir"-$python $python setup.py install --prefix=/usr --root="$subpkgdir" }
Generating documentation
To generate documentation:
makedepends="py-sphinx" subpackages="$pkgname-doc" package() { ... cd "$builddir"/doc install -d "$pkgdir"/usr/share/html/$pkgname "$pkgdir"/usr/share/man/man1 PYTHONPATH="$builddir/src:$PYTHONPATH" make html man install -t "$pkgdir"/usr/share/man/man1 build/man/* mv build/html/* "$pkgdir"/usr/share/html/$pkgname }