4.2. Extending the python27 and rh-python35 Software Collections

This section describes extending the python27 and rh-python35 Software Collections by creating a dependent Software Collection.
In Red Hat Software Collections 3.7, the scl tool is extended to support a macro %scl_package_override(), which allows for easier packaging of your own dependent Software Collection.

4.2.1. The vt191 Software Collection

Below is a commented example of building a dependent Software Collection. The Software Collection is named vt191 and contains the versiontools Python package version 1.9.1.
Note the following in the vt191 Software Collection metapackage:
  • The vt191 Software Collection metapackage has the following build dependency set:
    BuildRequires: %{scl_prefix_python}scldevel
    This expands to, for example, python27-scldevel.
    The python27-scldevel subpackage ships two important macros, %scl_python and %scl_prefix_python. Note that these macros are defined at the top of the metapackage spec file. Although the definitions are not required, they provide a visual hint that the vt191 Software Collection has been designed to be built on top of the python27 Software Collection. They also serve as a fallback value.
  • To have a site-packages directory set up properly, use the value of the %python27python_sitelib macro and replace python27 with vt191. Note that if you are building the Software Collection with a different provider (for example, /opt/myorganization/ instead of /opt/rh/), you will need to change these, too.

    Important

    Because the /opt/rh/ provider is used to install Software Collections provided by Red Hat, it is strongly recommended to use a different provider to avoid possible conflicts. See Section 2.3, “The Software Collection Root Directory” for more information.
  • The vt191-build subpackage has the following dependency set:
    Requires: %{scl_prefix_python}scldevel
    This expands to, for example, python27-scldevel. The purpose of this dependency is to ensure that the macros are always present when building packages for the vt191 Software Collection.
  • The enable scriptlet for the vt191 Software Collection uses the following line:
    . scl_source enable %{scl_python}
    Note the dot at the beginning of the line. This line makes the Python Software Collection start implicitly when the vt191 Software Collection is started so that the user can only type scl enable vt191 command instead of scl enable python27 vt191 command to run command in the Software Collection environment.
  • The macro file macros.vt191-config calls the %scl_package_override function to properly override %__os_install_post, Python dependency generators, and certain Python-specific macros used in other packages' spec files.
# define name of the scl
%global scl vt191
%scl_package %scl

# Defaults for the values for the python27/rh-python35 Software Collection. These
# will be used when python27-scldevel (or rh-python35-scldevel) is not in the
# build root
%{!?scl_python:%global scl_python python27}
%{!?scl_no_vendor:%global scl_no_vendor python27}
%{!?scl_prefix_python:%global scl_prefix_python %{scl_python}-}

# Only for this build, you need to override default __os_install_post,
# because the default one would find /opt/.../lib/python2.7/ and try
# to bytecompile with the system /usr/bin/python2.7
%global __os_install_post %{%{scl_no_vendor}_os_install_post}
# Similarly, override __python_requires for automatic dependency generator
%global __python_requires %{%{scl_no_vendor}_python_requires}

# The directory for site packages for this Software Collection
%global vt191_sitelib %(echo %{python27python_sitelib} | sed 's|%{scl_python}|%{scl}|')

Summary: Package that installs %scl
Name: %scl_name
Version: 1
Release: 1%{?dist}
License: GPLv2+
BuildRequires: scl-utils-build
# Always make sure that there is the python27-sclbuild (or rh-python35-sclbuild)
# package in the build root
BuildRequires: %{scl_prefix_python}scldevel
# Require python27-python-devel, you will need macros from that package
BuildRequires: %{scl_prefix_python}python-devel
Requires: %{scl_prefix}python-versiontools

%description
This is the main package for %scl Software Collection.

%package runtime
Summary: Package that handles %scl Software Collection.
Requires: scl-utils
Requires: %{scl_prefix_python}runtime

%description runtime
Package shipping essential scripts to work with %scl Software Collection.

%package build
Summary: Package shipping basic build configuration
Requires: scl-utils-build
# Require python27-scldevel (or rh-python35-scldevel) so that there is always access
# to the %%scl_python and %%scl_prefix_python macros in builds for this Software
# Collection
Requires: %{scl_prefix_python}scldevel

%description build
Package shipping essential configuration macros to build %scl Software Collection.

%prep
%setup -c -T

%install
%scl_install

# Create the enable scriptlet that:
# - Adds an additional load path for the Python interpreter.
# - Runs scl_source so that you can run:
#     scl enable vt191 "bash"
#   instead of:
#     scl enable python27 vt191 "bash"

cat >> %{buildroot}%{_scl_scripts}/enable << EOF
. scl_source enable %{scl_python}
export PYTHONPATH="%{vt191_sitelib}\${PYTHONPATH:+:\${PYTHONPATH}}"
EOF

mkdir -p %{buildroot}%{vt191_sitelib}

# - Enable Software Collection-specific bytecompilation macros from
#   the python27-python-devel package.
# - Also override the %%python_sitelib macro to point to the vt191 Software
#   Collection.
# - If you have architecture-dependent packages, you will also need to override
#   the %%python_sitearch macro.

cat >> %{buildroot}%{_root_sysconfdir}/rpm/macros.%{scl}-config << EOF
%%scl_package_override() %%{expand:%{?python27_os_install_post:%%global __os_install_post %%python27_os_install_post}
%%global __python_requires %%python27_python_requires
%%global __python_provides %%python27_python_provides
%%global __python %python27__python
%%global python_sitelib %vt191_sitelib
%%global python2_sitelib %vt191_sitelib
}
EOF

%files

%files runtime -f filelist
%scl_files
%vt191_sitelib

%files build
%{_root_sysconfdir}/rpm/macros.%{scl}-config

%changelog
* Wed Jan 22 2014 John Doe <jdoe@example.com> - 1-1
- Initial package.

4.2.2. The python-versiontools Package

Below is a commented example of the python-versiontools package spec file. Note the following in the spec file:
  • The BuildRequires tags are prefixed with %{?scl_prefix_python} instead of %{scl_prefix}.
  • The %install section explictly specifies --install-purelib.
%{?scl:%scl_package python-versiontools}
%{!?scl:%global pkg_name %{name}}

%global pypi_name versiontools

Name:           %{?scl_prefix}python-versiontools
Version:        1.9.1
Release:        1%{?dist}
Summary:        Smart replacement for plain tuple used in __version__

License:        LGPLv3
URL:            https://launchpad.net/versiontools
Source0:        http://pypi.python.org/packages/source/v/versiontools/versiontools-1.9.1.tar.gz

BuildArch:      noarch
BuildRequires:  %{?scl_prefix_python}python-devel
BuildRequires:  %{?scl_prefix_python}python-setuptools
%{?scl:BuildRequires: %{scl}-build %{scl}-runtime}
%{?scl:Requires: %{scl}-runtime}

%description
Smart replacement for plain tuple used in __version__

%prep
%setup -q -n %{pypi_name}-%{version}

%build
%{?scl:scl enable %{scl} "}
%{__python} setup.py build
%{?scl:"}

%install
# Explicitly specify --install-purelib %{python_sitelib}, which is now overriden
# to point to vt191, otherwise Python will try to install into the python27
# Software Collection site-packages directory
%{?scl:scl enable %{scl} "}
%{__python} setup.py install -O1 --skip-build --root %{buildroot} --install-purelib %{python_sitelib}
%{?scl:"}

%files
%{python_sitelib}/%{pypi_name}*

%changelog
* Wed Jan 22 2014 John Doe <jdoe@example.com> - 1.9.1-1
- Built for vt191 SCL.

4.2.3. Building the vt191 Software Collection

To build the vt191 Software Collection:
  1. Install the python27-scldevel and python27-python-devel subpackages that are part of the python27 Software Collection.
  2. Build vt191.spec and install the vt191-runtime and vt191-build packages.
  3. Install the python27-python-setuptools package, which is a build requirement for versiontools.
  4. Build python-versiontools.spec.

4.2.4. Testing the vt191 Software Collection

To test the vt191 Software Collection:
  1. Install the vt191-python-versiontools package.
  2. Run the following command:
    $ scl enable vt191 "python -c 'import versiontools; print(versiontools.__file__)'"
  3. Verify that the output contains the following line:
    /opt/rh/vt191/root/usr/lib/python2.7/site-packages/versiontools/__init__.pyc
    Note that the provider rh in the path may vary depending on your redefinition of the %_scl_prefix macro. See Section 2.3, “The Software Collection Root Directory” for more information.