Before reading, please note: doing software packaging is a difficult task, and what follows might not follow the best practice (even if it seems to work reasonably well). Asking some experienced packaging person and/or taking examples from existing packages usually pays off. And if there's a better way to do what follows, please drop me an email.
As everybody knows, the setup.py
script allows to define a collection of
"entry points" for your program, that is commands to install in the PATH
(typically /usr/bin/
).
Short example, this will install /usr/bin/foo
, and have it to execute the
main
method defined in the bar.bin.foo
module:
from setuptools import setup
setup(
...
entry_points={
'console_scripts' : [
'foo=bar.bin.foo:main',
]
}
)
A good thing to know is that setuptools
allows to specify an alternate
path for the entry points, which comes in handy when, for example, one wants
to place those binaries in /usr/libexec.
su -c "python setup.py --install-scripts /usr/libexec"
My use case is actually slightly different: I want to do so from a RPM spec
file, where the typical pattern is to use py3_build
macro. The
macro is currently defined as follows (provided by
python3-rpm-macros-3-23.el7.noarch
):
%py3_install() %{expand:\\\
CFLAGS="%{optflags}" %{__python3} %{py_setup} %{?py_setup_args} install
-O1 --skip-build --root %{buildroot} %{?*}
}
The %{?*}
syntax is expanding parameters, so I basically want something
like this:
%py3_install --install-scripts %{_libexecdir}/%{name}/
But rpm won't really like this thing, as it will try to interpret --
as
-
(option delimiter) -
(option), ending up with this error:
<mock-chroot> sh-4.2# rpm --eval '%py3_install --install-scripts %{_libexecdir}/%{name}/'
py3_install: invalid option -- '-'
error: Unknown option - in py3_install()
\
CFLAGS="-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches
-m64 -mtune=generic" /usr/bin/python3.6 setup.py install -O1 --skip-build
--root /builddir/build/BUILDROOT/%{name}-%{version}-%{release}.x86_64
Thanks to the good people in #fedora-devel
(Freenode), I could find the
right answer, which afterwards looks so obvious…:
<mock-chroot> sh-4.2# rpm --eval '%py3_install -- --install-scripts %{_libexecdir}/%{name}/'
\
CFLAGS="-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches
-m64 -mtune=generic" /usr/bin/python3.6 setup.py install -O1
--skip-build --root
/builddir/build/BUILDROOT/%{name}-%{version}-%{release}.x86_64
--install-scripts /usr/libexec/%{name}/
Uh, and heads up for this pitfall (driven by inexperience, really): do not
use macro with curly brackets %{...}
, as this will prevent options from
being expanded:
<mock-chroot> sh-4.2# rpm --eval '%{py3_install} -- --install-scripts %{_libexecdir}/%{name}/'
\
CFLAGS="-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions
-fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches
-m64 -mtune=generic" /usr/bin/python3.6 setup.py install -O1
--skip-build --root
/builddir/build/BUILDROOT/%{name}-%{version}-%{release}.x86_64
-- --install-scripts /usr/libexec/%{name}/