Egbert Eich
2576121e57
- Previous fix did not work, revert and use %global instead of %define. The %hpc_cmake and %hpc_ninja macros wrap the %cmake and %ninja macros. The wrapper needs to set all standard variables passed to cmake in these macros to the hpc values. With the mentioned macros this leads to an infinite recursion if using %define. So we use %global instead. OBS-URL: https://build.opensuse.org/request/show/1120761 OBS-URL: https://build.opensuse.org/package/show/science:HPC/suse-hpc?expand=0&rev=66
797 lines
31 KiB
Plaintext
797 lines
31 KiB
Plaintext
# If argument is non-empty print with a leading underscore
|
|
%_hpc_p %([ -n "%{?1}" ]&&echo -n _%{1})
|
|
%hpc_package_name_tail() %{?hpc_ext}%{_hpc_p}%{hpc_package_name_end}
|
|
%hpc_package_name() %{pname}%{?hpc_ext}%{_hpc_p}%{hpc_package_name_end}
|
|
|
|
# Paths
|
|
%hpc_base %{_prefix}/lib/hpc/
|
|
|
|
# For (non-mpi) libraries
|
|
%hpc_install_base %{hpc_base}%{?hpc_cf_dir}%{?hpc_mpi_dir}
|
|
%hpc_install_path_base %{hpc_install_base}%{pname}%{?hpc_ext}/
|
|
%hpc_install_path %{hpc_install_path_base}%{version}
|
|
|
|
# For compilers
|
|
%hpc_cf_install_base %{hpc_base}compiler/
|
|
%hpc_cf_install_path_base %{hpc_cf_install_base}%{hpc_compiler_family}/
|
|
%hpc_cf_install_path %{hpc_cf_install_path_base}%{hpc_cf_dep_version}
|
|
|
|
# For mpi libraries
|
|
%hpc_mpi_install_base %{hpc_base}%{?hpc_cf_dir}mpi/
|
|
%hpc_mpi_install_path_base %{hpc_mpi_install_base}%{hpc_mpi_family}%{?hpc_ext}/
|
|
%hpc_mpi_install_path %{hpc_mpi_install_path_base}%{version}
|
|
|
|
# Different paths - below HPC directory
|
|
%hpc_exec_prefix %{hpc_prefix}
|
|
%hpc_bindir %{hpc_prefix}/bin
|
|
%hpc_sbindir %{hpc_prefix}/sbin
|
|
%hpc_sysconfdir %{_sysconfdir}
|
|
%hpc_datadir %{hpc_prefix}/share
|
|
%hpc_includedir %{hpc_prefix}/include
|
|
%hpc_libdir %{hpc_prefix}/%{_lib}
|
|
%hpc_libexecdir %{hpc_prefix}/lib
|
|
%hpc_localstatedir %{_localstatedir}
|
|
%hpc_sharedstatedir %{_sharedstatedir}
|
|
# MANPATH
|
|
%hpc_mandir %{hpc_datadir}/man
|
|
%hpc_docdir %{hpc_datadir}/doc/packages
|
|
# INFOPATH
|
|
%hpc_infodir %{hpc_datadir}/info
|
|
# PKG_CONFIG_PATH
|
|
%hpc_pkgconfigdir %{hpc_libdir}/pkgconfig
|
|
%hpc_cmake_dir %{hpc_datadir}/cmake
|
|
%hpc_cmake_moddir %{hpc_cmake_dir}/Modules
|
|
|
|
# pkgconfig
|
|
# %hpc_write_pkgconfig [-l <libname>][-n <pkgfile_name>]
|
|
# -l <libname>: <libname> with -l option: -l <libname>. default: none
|
|
# -n <pkgfile_name>: name of pkgconf file (without the trailing .pc)
|
|
# default: %pname
|
|
%_hpc_write_pkgconfig(l:n:) \
|
|
%{!?_hpc_init_done: %{error: "%%_hpc_write_pkgconfig: Call %%hpc_init first!"}} \
|
|
%{__mkdir_p} %{buildroot}/%{hpc_pkgconfigdir} \
|
|
echo "writing %{buildroot}%{hpc_pkgconfigdir}/%{!-n:%{pname}}%{-n:%{-n*}}.pc" \
|
|
%{__cat} << "EOF" > %{buildroot}%{hpc_pkgconfigdir}/%{!-n:%{pname}}%{-n:%{-n*}}.pc \
|
|
prefix=%{hpc_prefix} \
|
|
exec_prefix=%{hpc_exec_prefix} \
|
|
libdir=%{hpc_libdir} \
|
|
includedir=%{hpc_includedir} \
|
|
sysconfdir=%{hpc_sysconfdir} \
|
|
\
|
|
Name: %pname \
|
|
Description: %{SUMMARY} \
|
|
Version: %version \
|
|
Libs: -L${libdir} %{?-l:-l%{-l*}} \
|
|
Cflags: -I${includedir} \
|
|
EOF\
|
|
%{nil}
|
|
|
|
%hpc_write_pkgconfig(n:l:) %{expand:%%_hpc_write_pkgconfig %{**}}
|
|
|
|
# %hpc_pkgconfig_file [-n <name_of_file>][-N]
|
|
# -n <name_of_file>: pkgconfig file name (without trailing .pc)
|
|
# -N: don't list pkgconfig directory (used when this macro is used
|
|
# more than once per file).
|
|
%hpc_pkgconfig_file(n:N) \
|
|
%{!-N:%dir %{hpc_pkgconfigdir}} \
|
|
%{hpc_pkgconfigdir}/%{!-n:%{pname}}%{-n:%{-n*}}.pc
|
|
|
|
%hpc_modulefile_add_pkgconfig_path prepend-path PKG_CONFIG_PATH %{hpc_pkgconfigdir}
|
|
|
|
#
|
|
# Requires:
|
|
#
|
|
|
|
# Compiler
|
|
%hpc_cf_requires %{expand:%{hpc_%{hpc_compiler_family}_requires}}
|
|
# Compiler devel packages
|
|
%hpc_cf_requires_devel %{expand:%{hpc_%{hpc_compiler_family}_requires_devel}}
|
|
|
|
# MPI
|
|
%hpc_mpi_requires %{expand:%{hpc_%{hpc_mpi_family}_requires}}
|
|
# MPI devel packages
|
|
%hpc_mpi_requires_devel %{expand:%{hpc_%{hpc_mpi_family}_requires_devel}}
|
|
|
|
# Base
|
|
%hpc_requires Requires: lua-lmod \
|
|
%{?hpc_compiler_family:%{!?_hpc_build_compiler:%hpc_cf_requires}}\
|
|
%{?hpc_mpi_family:%{!?_hpc_build_mpi:%hpc_mpi_requires}}
|
|
|
|
# Devel
|
|
%hpc_requires_devel %{?hpc_compiler_family:%{!?_hpc_build_compiler:%hpc_cf_requires_devel}}\
|
|
%{?hpc_mpi_family:%{!?_hpc_build_mpi:%hpc_mpi_requires_devel}}
|
|
|
|
#
|
|
# General settings depending in compiler and mpi family
|
|
#
|
|
|
|
# Init
|
|
#
|
|
# HCP init: Call everywhere where this framework is used.
|
|
# %hpc_init [-C|-M] -c <compiler_family> [-v <compiler_version>] -m <mpi_family> [-V <mpi_version>]
|
|
# -C: build a compiler.
|
|
# -c <arg>: set compiler family to <arg> (mandatory)
|
|
# -v <arg>: set compiler version to <arg> (optional - default: base version)
|
|
# -M: build an MPI library: -C and -M are mutually exclusive!
|
|
# -m: <arg>: set MPI family to <arg>
|
|
# -V: <arg>: set MPI version to <arg> (optional - default:)
|
|
# -e: <arg>: program name extension
|
|
%_hpc_init(Cc:Mm:v:V:e:)\
|
|
%global hpc_base %{expand:%hpc_base} \
|
|
%{-m:%{!-c:%{error: Cannot est MPI family without compiler}}} \
|
|
%{-c:%{expand: %%global hpc_compiler_family %{-c*}}} \
|
|
%{-m: %{expand: %%global hpc_mpi_family %{-m*}}} \
|
|
%{!-m:%{-V:%{error: MPI version sepecified but no MPI family}}} \
|
|
%{-C:%{-M:%{error: Don't build both compiler and MPI!}}} \
|
|
%{-c:%{echo: Building for %hpc_compiler_family %{-v:version %{-v*}}}} \
|
|
%{!?pname:%{error: No package name given! Set %%pname before calling %%hpc_init }} \
|
|
%{-e:%{expand: %%global hpc_ext -%{-e*}}} \
|
|
%if %{defined hpc_compiler_family} \
|
|
%if %{defined hpc_%{expand:%{hpc_compiler_family}}_init} \
|
|
# -v passed onto here \
|
|
%{expand:%%{hpc_%{expand:%{hpc_compiler_family}}_init %{-v}}} \
|
|
%endif \
|
|
%endif \
|
|
%if %{defined hpc_mpi_family} \
|
|
%if %{defined hpc_%{expand:%{hpc_mpi_family}}_init} \
|
|
# -V passed onto here \
|
|
%{expand:%%{hpc_%{expand:%{hpc_mpi_family}}_init %{-V}}} \
|
|
%endif \
|
|
%endif \
|
|
# No further expansion needed, thus no %%{expand:..} \
|
|
%{-C:%global _hpc_build_compiler 1} \
|
|
%{-M:%global _hpc_build_mpi 1} \
|
|
# \
|
|
# Compiler \
|
|
%{?hpc_compiler_family: \
|
|
%{expand: %%global hpc_cf_full_version %%{hpc_%{hpc_compiler_family}_full_version}} \
|
|
# Version for module directories \
|
|
%{expand: %%global hpc_cf_dep_version %%{hpc_%{hpc_compiler_family}_dep_version}} \
|
|
# Version extension on binaries \
|
|
%{expand: %%global hpc_cf_bin_version %%{hpc_%{hpc_compiler_family}_bin_version}} \
|
|
# Version number on package \
|
|
%{expand: %%global hpc_cf_pack_version %%{hpc_%{hpc_compiler_family}_pack_version}} \
|
|
%{expand: %%global hpc_cf_dir %{?hpc_compiler_family:%%{hpc_%{hpc_compiler_family}_dir}/}} \
|
|
} \
|
|
# \
|
|
# MPI \
|
|
%{?hpc_mpi_family: \
|
|
%global hpc_mpi_dep_version %{?hpc_mpi_family:%%{hpc_%{hpc_mpi_family}_dep_version}} \
|
|
%global hpc_mpi_dir %{?hpc_mpi_family:%%{hpc_%{hpc_mpi_family}_dir}/} \
|
|
%global hpc_mpi_pack_version %{?hpc_mpi_family:%%{hpc_%{hpc_mpi_family}_pack_version}} \
|
|
} \
|
|
# Preexpanded macros \
|
|
%{expand: %%global hpc_prefix %{-M:%hpc_mpi_install_path}%{-C:%hpc_cf_install_path}%{!-M:%{!-C:%{hpc_install_path}}}} \
|
|
%{?_hpc_build_mpi:%global _hpc_build_xx 1} \
|
|
%{?_hpc_build_compiler:%global _hpc_build_xx 1} \
|
|
%{!?hpc_compiler_family:%global _hpc_build_xx 1} \
|
|
%define _hpc_package_name_compiler %{?hpc_compiler_family:-%{hpc_compiler_family}%{?hpc_cf_pack_version}} \
|
|
%define _hpc_package_name_mpi %{?hpc_mpi_family:%{!?_hpc_build_mpi:-%{hpc_mpi_family}%{?hpc_mpi_pack_version}}} \
|
|
%global hpc_package_name_end %{_hpc_package_name_compiler}%{_hpc_package_name_mpi}-hpc \
|
|
# Dependency Generator \
|
|
%global tmp %__elf_exclude_path \
|
|
%global __elf_exclude_path (%tmp)|(^%hpc_base) \
|
|
%undefine tmp \
|
|
%{?__elflib_exclude_path: \
|
|
%global tmp %{__elflib_exclude_path}} \
|
|
%global __elflib_exclude_path %{?tmp:(%{tmp})|}(^%hpc_base) \
|
|
%undefine tmp \
|
|
%{expand:%([ 0%{?sle_version} -ge 150000 -o 0%{?suse_version} -gt 1500 ] && echo %%global _hpc_python3 1)} \
|
|
%global _hpc_init_done 1
|
|
|
|
%hpc_init(Cc:Mm:v:V:e:) %{expand:%%_hpc_init %{**}}
|
|
|
|
#
|
|
# Environment Modules
|
|
#
|
|
%hpc_mpi_family_path %{?hpc_mpi_family:-%{hpc_mpi_family}%([ -n "%{hpc_mpi_dep_version}" ] && \
|
|
echo -n "-%{hpc_mpi_dep_version}")}
|
|
|
|
%hpc_compiler_family_path %{?hpc_compiler_family:%{hpc_compiler_family}-%{hpc_cf_dep_version}}
|
|
|
|
# Used for MPI library build to create the module install directory for MPI dependent libs.
|
|
%hpc_module_dep_install %{lua_lmod_moduledeps}/%{hpc_compiler_family_path}%{?hpc_mpi_family_path}
|
|
|
|
# Install path base for the module file of the current package
|
|
%_hpc_module_base %{!?compiler_family:%{lua_lmod_modulesdir}}%{?compiler_family:%{?_hpc_build_compiler:%{lua_lmod_modulesdir}}%{!?_hpc_build_compiler:%{lua_lmod_moduledeps}}/}
|
|
%hpc_module_dep_path %{_hpc_module_base}%{hpc_compiler_family_path}%{!?_hpc_build_mpi:%{?hpc_mpi_family_path}}
|
|
|
|
# install the module file here. If the default path (according to
|
|
# hpc_cf_family and hpc_mpi_family should not be used, pass trailing path
|
|
# element as argument. Do not use for compiler!
|
|
%hpc_module_dep_base %{hpc_module_dep_path}/%{hpc_module_pname}%{?hpc_ext}/
|
|
|
|
# This can be overridden in the spec file.
|
|
%hpc_module_pname %pname
|
|
|
|
# Modules init: Set up modules required for building
|
|
# %hpc_modules_init <module_list>
|
|
# <module_list>: list of modules (exclude compiler and MPI library).
|
|
# May be empty if only compiler and MPI library are needed.
|
|
%hpc_modules_init() \
|
|
%{!?_hpc_init_done: %{error: "%%hpc_setup_compiler: Call %%hpc_init first!"}} \
|
|
%{?*:%global _hpc_modules_other %{**}} \
|
|
%global _hpc_modules %{?hpc_compiler_family:%{expand:%%{?%{expand:_hpc_%{hpc_compiler_family}_module}}}} %{?hpc_mpi_family:%{expand:%%{?%{expand:_hpc_%{hpc_mpi_family}_module}}}} %{?_hpc_modules_other}
|
|
|
|
%hpc_setup_compiler \
|
|
%{!?_hpc_init_done: %{error: "%%hpc_setup_compiler: Call %%hpc_init first!"}} \
|
|
module purge \
|
|
%{?hpc_compiler_family:%{expand:%{hpc_setup_%{hpc_compiler_family}}}}
|
|
|
|
%hpc_setup_mpi \
|
|
%{?hpc_mpi_family:%{expand:%{hpc_setup_%{hpc_mpi_family}}}}
|
|
|
|
%hpc_setup \
|
|
%hpc_setup_compiler \
|
|
%{!?_hpc_build_mpi:%hpc_setup_mpi} \
|
|
%{?_hpc_modules_other:[ -n "%{?_hpc_modules_other}" ] && module load %_hpc_modules_other}
|
|
|
|
# delete default in %postun
|
|
%hpc_module_delete_if_default \
|
|
_tmp=$(readlink -f %{hpc_module_dep_base}.version) && \\\
|
|
test "$_tmp" = "$(readlink -f %{hpc_module_dep_base}.version.%{version})" \\\
|
|
-o "x" = "x$(readlink -e %{hpc_module_dep_base}.version)" && \\\
|
|
rm -f %{hpc_module_dep_base}.version || exit 0
|
|
|
|
#
|
|
%hpc_write_modules_version_file \
|
|
echo "Writing %{buildroot}%{hpc_module_dep_base}.version.%{version}" \
|
|
%{__cat} << EOF > %{buildroot}%{hpc_module_dep_base}.version.%{version} \
|
|
#%%Module1.0#####################################################################\
|
|
##\
|
|
## version file for %{pname}-%{version}\
|
|
##\
|
|
set ModulesVersion "%{version}"\
|
|
EOF\
|
|
%nil
|
|
|
|
#
|
|
%hpc_make_modules_dir mkdir -p %{buildroot}%{hpc_module_dep_base}
|
|
|
|
# Write modules files
|
|
# %hpc_make_modules_extra can be defined by domain specific macros such as %hpc_python_master_package
|
|
# or in the specfile in order to provide a hook for creating extra module files.
|
|
%hpc_write_modules_files \
|
|
%{?_hpc_build_mpi:mkdir -p %{buildroot}%{hpc_install_base}} \
|
|
%hpc_make_modules_dir \
|
|
%{?hpc_make_modules_extra} \
|
|
%{?_hpc_build_xx:mkdir -p %{buildroot}%{hpc_module_dep_install}} \
|
|
%hpc_write_modules_version_file \
|
|
echo "Writing %{buildroot}%{hpc_module_dep_base}%{version}"; \
|
|
sed -e '/#%%Module1.0.*/b 1;1s/\(.*\)/#%%Module1.0\n\1/;:1' << EOF\\\
|
|
> %{buildroot}%{hpc_module_dep_base}%{version}
|
|
|
|
%hpc_modulepath %{?_hpc_build_xx:%{hpc_module_dep_install}}%{!?_hpc_build_xx:%{hpc_module_dep_path}}
|
|
|
|
# For files section:
|
|
## Modules Files
|
|
# %hpc_module_extra can be defined by domain specific macros such as %hpc_python_master_package or in
|
|
# the specfile in order to provide a hook for registering extra files made by %hpc_make_modules_extra
|
|
%hpc_modules_files \
|
|
%{?_hpc_build_xx:%{hpc_module_dep_install}} \
|
|
%dir %{hpc_module_dep_base} \
|
|
%{hpc_module_dep_base}/.version.%{version} \
|
|
%{hpc_module_dep_base}/%{version} \
|
|
%{?hpc_module_extra}
|
|
|
|
# Compilers - use in library package when building compilers
|
|
%hpc_cf_dirs \
|
|
%dir %hpc_cf_install_base \
|
|
%dir %hpc_cf_install_path_base \
|
|
%dir %hpc_cf_install_path
|
|
|
|
# mpi libraries - use in library package when building mpi libraries
|
|
%hpc_mpi_dirs \
|
|
%dir %{hpc_install_base} \
|
|
%dir %hpc_mpi_install_base \
|
|
%dir %hpc_mpi_install_path_base \
|
|
%dir %hpc_mpi_install_path
|
|
|
|
# base dir path only
|
|
%hpc_base_dirs \
|
|
%{!?hpc_compiler_family:%dir %{hpc_install_base}} \
|
|
%dir %{hpc_install_path_base} \
|
|
%dir %{hpc_install_path}
|
|
|
|
# serial and parallel libraries - use in library package
|
|
%hpc_dirs \
|
|
%{hpc_base_dirs} \
|
|
%dir %{hpc_libdir}
|
|
|
|
#
|
|
# Autotools
|
|
#
|
|
|
|
%hpc_configure \
|
|
%{!?_hpc_init_done: %{error: "%%hpc_configure: Call %%hpc_init first!"}} \
|
|
CFLAGS="${CFLAGS:-%optflags}" ; export CFLAGS ; \
|
|
CXXFLAGS="${CXXFLAGS:-%optflags}" ; export CXXFLAGS ; \
|
|
FFLAGS="${FFLAGS:-%optflags}" ; export FFLAGS ; \
|
|
%{_configure} --host=%{_host} --build=%{_build} \\\
|
|
%{?_program_prefix:--program-prefix=%{_program_prefix}} \\\
|
|
--disable-dependency-tracking \\\
|
|
--prefix=%{hpc_prefix} \\\
|
|
--exec-prefix=%{hpc_exec_prefix} \\\
|
|
--bindir=%{hpc_bindir} \\\
|
|
--sbindir=%{hpc_sbindir} \\\
|
|
--sysconfdir=%{hpc_sysconfdir} \\\
|
|
--datadir=%{hpc_datadir} \\\
|
|
--includedir=%{hpc_includedir} \\\
|
|
--libdir=%{hpc_libdir} \\\
|
|
--libexecdir=%{hpc_libexecdir} \\\
|
|
--localstatedir=%{hpc_localstatedir} \\\
|
|
--sharedstatedir=%{hpc_sharedstatedir} \\\
|
|
--mandir=%{hpc_mandir} \\\
|
|
--infodir=%{hpc_infodir}
|
|
|
|
#
|
|
# Debugging
|
|
#
|
|
|
|
# %hpc_debug [-x]
|
|
# -x: exit with a non-zero exit code. This will stop the build and keep the
|
|
# generated script file around.
|
|
#
|
|
%hpc_debug(x) \
|
|
echo "Package name %{name} for %{pname} %{?hpc_ext: ext: %{hpc_ext}}" \
|
|
%{?_hpc_build_compiler: echo "Building Compiler"} \
|
|
%{?_hpc_build_mpi: echo "Building MPI lib"} \
|
|
echo %nil \
|
|
%if %{defined hpc_compiler_family} \
|
|
echo Building for compiler family: %{hpc_compiler_family} \
|
|
echo cf_full_version: %{hpc_cf_full_version} \
|
|
echo cf_dep_version: %{hpc_cf_dep_version} \
|
|
echo cf_bin_version: %{hpc_cf_bin_version} \
|
|
echo cf_pack_version: %{hpc_cf_pack_version} \
|
|
echo cf_dir: %{hpc_cf_dir} \
|
|
echo cf_install_path: %{hpc_cf_install_path} \
|
|
echo cf_install_path_base: %{hpc_cf_install_path_base} \
|
|
echo %nil \
|
|
%endif \
|
|
%if %{defined hpc_mpi_family} \
|
|
echo "Building with MPI family support for %{hpc_mpi_family}" \
|
|
echo hpc_mpi_dep_version: %hpc_mpi_dep_version \
|
|
%{?hpc_mpi_pack_version: echo hpc_mpi_pack_version: %hpc_mpi_pack_version} \
|
|
echo hpc_mpi_family_path: %hpc_mpi_family_path \
|
|
echo hpc_mpi_dir: %{hpc_mpi_dir} \
|
|
echo %nil \
|
|
%endif \
|
|
echo hpc_prefix: %{hpc_prefix} \
|
|
echo hpc_module_dep_path: %{hpc_module_dep_path} \
|
|
echo %nil \
|
|
%{-x:exit 1}
|
|
|
|
#
|
|
# Create 'master' package: packages which have the built package as
|
|
# dependency. This way, the latest version of a library can be installed
|
|
# without knowing its version number.
|
|
# The dependent library package will be kept around when an update to
|
|
# this package pulls in a new version of the dependent library, because
|
|
# these libraries also carry the version number of their names and
|
|
# don't conflict with an earlier version.
|
|
# %hpc_master_package [-n <full_package_name>][-g <group>][-s# <.so-version>][-l][-L][-N <pname>][-O <fullname>][-P <prefix][-q] <package_ext>
|
|
# -n <full_package_name>: specify the full package name. This may not be used in conjunction with
|
|
# the package name extension <package_ext>.
|
|
# -g <group>: Specify the group to use.
|
|
# -s <.so-version>: If this is a dependency for a library package, specify the
|
|
# .so version. This will cause the package name to be prepended with
|
|
# `lib`. This should not be used together with -l.
|
|
# -l: mark a library package, prepend the package name with a `lib` (like -s
|
|
# but without an explicite so version. Do not use -l and -s together.
|
|
# -L: Create a link from the .version.<version_no> file to the .version file
|
|
# to mark the default version. To undo, add %hpc_module_delete_if_default
|
|
# to the package the master is created for.
|
|
# -a: Use native arch even if no library package.
|
|
# -N <pname>: Specify if a sub-package has different basename (pname)
|
|
# -q: For internal use only!
|
|
# -M: use specified name in place of %%name
|
|
# -O <fullname>: Add Provides/Obsoletes for package <fullname> with
|
|
# version %version, multiple names may be separated by ":"
|
|
# -P <prefix>: Add Provides/Obsoletes with %version-%release for package
|
|
# names derived from the master package name, replacing <prefix> with
|
|
# the contents of %<prefix>_provides. Used for python packages in order
|
|
# to provide the extra python3 flavor by the package for the current
|
|
# primary interpreter. The argument can be used in general as well:
|
|
# If your package is called 'foo-bar' with version and release 0.1-2, you
|
|
# `%define foo_provides fooA abc123`, and call
|
|
# `%hpc_master_package -P foo`, then the package will have
|
|
# 'Provides: fooA-bar = 0.1-2', 'Provides: abc123-bar = 0.1-2', and the
|
|
# respective 'Obsoletes:' tags.
|
|
# -E: create an 'empty' master package with no requires. This allows to
|
|
# keep the macro package around for compatibility even if the underlying
|
|
# package has been removed.
|
|
#
|
|
%hpc_master_package(n:g:s:lLaqN:M:O:P:E) \
|
|
%define _mylib %{-s:lib}%{!-s:%{-l:lib}} \
|
|
%define _p_ext %(test -n "%{*}" && echo -%{*}) \
|
|
%{-M: \ %define name %{-M*}} \
|
|
%{!-N:\
|
|
%define _pname %{pname} \
|
|
%define _name %{name} \
|
|
} \
|
|
%{-N:\
|
|
%define _pname %{-N*} \
|
|
%define _name %(echo %{name} | sed -e "s/%{pname}/%{_pname}/") \
|
|
} \
|
|
%{-n:%define _lname %{-n*}} \
|
|
%{!-n:\
|
|
%define _lname_cf %{?compiler_family:-%{hpc_compiler_family}%{?hpc_cf_pack_version}} \
|
|
%define _lname_mpi %{!?_hpc_build_mpi:%{?hpc_mpi_family:-%{hpc_mpi_family}%{?hpc_mpi_pack_version}}} \
|
|
%define _lname_build_mpi_name %{?_hpc_build_mpi:%{hpc_mpi_family}%{?hpc_ext}%{?hpc_mpi_pack_version}} \
|
|
%define _lname_name %{!?_hpc_build_mpi:%{_pname}%{?hpc_ext}%{-s*}} \
|
|
%define _lname_header %{_mylib}%{_lname_build_mpi_name}%{_lname_name} \
|
|
%define _lname %{_lname_header}%{_lname_cf}%{_lname_mpi}-hpc%{_p_ext} \
|
|
}\
|
|
%{-q:%(echo -n %{_lname}; true %{_mylib} %{_p_ext})} \
|
|
%{!-q:\
|
|
%{-g:%define _group %{-g*}} \
|
|
%{!-g: \
|
|
%define _group %(lname=%_lname; \
|
|
case $lname in \
|
|
(*-devel|*-devel-static) \
|
|
echo -n "Development/Libraries/%{?hpc_mpi_family:Parallel}%{!?hpc_mpi_family:C and C++}" ;; \
|
|
(*) \
|
|
if [ -n "%_mylib" ] \
|
|
then \
|
|
echo -n System/Libraries \
|
|
else \
|
|
echo -n Productivity/Scientific/Other \
|
|
fi ;; esac)\
|
|
} \
|
|
%{!-s:%define n_name %_name} \
|
|
%{-s:%define n_name %(a=%{_name};echo -n ${a/%{_pname}/%{_pname}%{-s*}})} \
|
|
%{!-s:%define s_name %{_mylib}%{n_name}%{_p_ext}} \
|
|
%{-s:%define s_name %(echo -n %{_mylib}%{_name}%{_p_ext} | sed -e "s/\\\\(.*%{_pname}\\\\)\\\\(.*\\\\)/\\\\1%{-s*}\\\\2/")} \
|
|
%package -n %_lname \
|
|
Summary: Dependency package for %{s_name} \
|
|
Group: %_group \
|
|
Obsoletes: %_lname < %version \
|
|
%{-O:%(\
|
|
v=%{-O*}; \
|
|
for i in ${v//:/ }; \
|
|
do echo "Obsoletes: $i < %version"; \
|
|
echo "Provides: $i = %version"; \
|
|
done)\
|
|
} \
|
|
%{-P:%(\
|
|
prefix=%{-P*}; \
|
|
lname=%{_lname}; \
|
|
for extra in %{expand:%%{?%{-P*}_provides}}; do \
|
|
provided_extra=${lname/$prefix/$extra}; \
|
|
echo "Provides: ${provided_extra} = %{version}-%{release}"; \
|
|
echo "Obsoletes: ${provided_extra} < %{version}-%{release}"; \
|
|
done)\
|
|
} \
|
|
%{!-E:Requires: %{s_name} = %version} \
|
|
%{!-l:%{!-s:%{!-a:BuildArch: noarch}}} \
|
|
%description -n %_lname \
|
|
%{pname}: %{SUMMARY} \
|
|
The package %{_lname} provides the dependency to get binary package %{s_name}. \
|
|
When this package gets updated it installs the latest version of %name. \
|
|
%{-L:%posttrans -n %_lname \
|
|
[ -e %{hpc_module_dep_base}.version.%{version} ] && \\\
|
|
ln -sf .version.%{version} %{hpc_module_dep_base}.version} \
|
|
%files -n %{_lname} \
|
|
%defattr(-,root,root)\
|
|
%define _msg '%{pname}: %{SUMMARY}.\\\\nProvide the dependency to get binary package %{s_name}.\\\\nWhen this package gets updated it installs the latest version of %{pname}.' \
|
|
%define _readme README.%{_mylib}%{_name}%{_p_ext} \
|
|
%define _tmpexec %(tmp=$(mktemp /tmp/scr-XXXXXX); \
|
|
readme=%{_readme} \
|
|
echo "#!/bin/bash" > $tmp; \
|
|
echo "echo -e %_msg \> $readme && rm -f $tmp || true" >> $tmp; \
|
|
chmod u+x $tmp; echo -n $tmp) \
|
|
%doc $(%_tmpexec)./%{_readme} \
|
|
} \
|
|
%{nil}
|
|
|
|
##
|
|
# Functions
|
|
##
|
|
%hpc_upcase() %(echo %{**} | tr [a-z] [A-Z])
|
|
%hpc_PNAME() %(echo %{**} | tr [a-z-] [A-Z_])
|
|
|
|
##
|
|
# Macros specific for python packages
|
|
##
|
|
%_hpc_python_sysconfig_path() %(%1 -c "import sysconfig as s; \\\
|
|
print(s.get_paths(%{?3:vars={'platbase':\\"%3\\", 'base' : \\"%3\\"}}).get('%2'));")
|
|
|
|
# get the python version specific directory for arch specific files in the HPC
|
|
# directory structure (singlepsec).
|
|
# python_sitearch equivalent - for arch specific python modules
|
|
%hpc_python_sitearch %{_hpc_python_sysconfig_path %{expand:%__%{python_flavor}} platlib %{?hpc_prefix}}
|
|
# python_sitelib equivalent - for arch independent python modules
|
|
%hpc_python_sitelib %{_hpc_python_sysconfig_path %{expand:%__%{python_flavor}} purelib %{?hpc_prefix}}
|
|
|
|
# same for non-singlespec (using internal %%_hpc_python3)
|
|
%hpc_python_sitearch_no_singlespec %{_hpc_python_sysconfig_path %{?_hpc_python3:/usr/bin/python3}%{!?_hpc_python3:%{expand:%__%{python_flavor}}} platlib %{?hpc_prefix}}
|
|
%hpc_python_sitelib_no_singlespec %{_hpc_python_sysconfig_path %{?_hpc_python3:/usr/bin/python3}%{!?_hpc_python3:%{expand:%__%{python_flavor}}} purelib %{?hpc_prefix}}
|
|
|
|
%_hpc_python_ver() %(%1 -c "import sysconfig as s; print(s.get_config_var('py_version_short'));")
|
|
|
|
# get the (abbreviated) python version used for package and directory names (singlespec).
|
|
%hpc_python_version %{_hpc_python_ver %{expand:%__%{python_flavor}}}
|
|
|
|
# %{hpc_python_master_package [-n <package_name>] [-g <group>] [-l][-L][-a]}
|
|
# (singlespec)
|
|
# -n: specify a package name
|
|
# -g: specify a group name
|
|
# -l: mark the package as library package
|
|
# -L: (for environment modules) create a link from the
|
|
# `.version.<version_no>` file to the `.version`-file to
|
|
# mark the default version.
|
|
# -a: mark package as architecture dependent
|
|
%hpc_python_master_package(n:g:lLa) \
|
|
%{?_python_macro_init} \
|
|
%{lua: \
|
|
if _hpc_python_master_package_inited ~= true then \
|
|
_hpc_python_package_list = {} \
|
|
_hpc_python_master_package_inited = true \
|
|
end \
|
|
local arg_list = "" \
|
|
local function add_args (a, opt) \
|
|
if a ~= "" then \
|
|
if arg_list ~= "" then arg_list = arg_list .. " " end \
|
|
if opt ~= nil then arg_list = arg_list .. opt .. " " end \
|
|
arg_list = arg_list .. a \
|
|
end \
|
|
end \
|
|
local n_arg = rpm.expand("%{-n*}") \
|
|
local g_arg = rpm.expand("%{-g*}") \
|
|
local l_arg = rpm.expand("%{?-l:-l}") \
|
|
local L_arg = rpm.expand("%{?-L:-L}") \
|
|
local a_arg = rpm.expand("%{?-a:-a}") \
|
|
local other_arg = rpm.expand("%{*}") \
|
|
local pname = rpm.expand("%pname") \
|
|
local name = rpm.expand("%name") \
|
|
local python_flavor = rpm.expand("%python_flavor") \
|
|
-- io.stderr:write("n_arg "..n_arg.."\\n") \
|
|
if n_arg ~= "" then \
|
|
n_arg=n_arg:gsub("^(%w+)python%-(.*)","%1"..python_flavor.."-%2") \
|
|
-- io.stderr:write("n_arg modfied "..n_arg .."\\n") \
|
|
end \
|
|
local n_pname = pname:gsub("^python", python_flavor,1) \
|
|
local n_name = name:gsub("^python", python_flavor,1) \
|
|
rpm.define("pname "..n_pname) \
|
|
rpm.define("name "..n_name) \
|
|
add_args (g_arg, "-g") \
|
|
add_args (n_arg, "-n") \
|
|
add_args (l_arg) \
|
|
add_args (L_arg) \
|
|
add_args (a_arg) \
|
|
add_args (other_arg) \
|
|
add_args (python_flavor, "-P") \
|
|
-- io.stderr:write("pname "..rpm.expand("%pname").."\\n") \
|
|
-- io.stderr:write(rpm.expand("%{hpc_master_package " .. arg_list .."}").."\\n") \
|
|
-- io.stderr:write(rpm.expand("%{hpc_master_package " .. arg_list .." -q}"):gsub("%s","").."\\n") \
|
|
local package = rpm.expand("%{hpc_master_package " .. arg_list .." -q}"):gsub("%s","") \
|
|
if package ~= "" then \
|
|
-- check if we have seen this package before. Since we will not have an empty files section \
|
|
-- skip it entirely! \
|
|
if _hpc_python_package_list[package] == true then \
|
|
rpm.define("pname " .. pname) \
|
|
rpm.define("name " .. name) \
|
|
return \
|
|
else \
|
|
_hpc_python_package_list[package] = true \
|
|
end \
|
|
end \
|
|
-- io.stderr:write(">>> "..package.."\\n") \
|
|
io.stderr:write("pname "..rpm.expand("%pname").."\\n") \
|
|
io.stderr:write("%{hpc_master_package " .. arg_list .. "}\\n\\n") \
|
|
print(rpm.expand("%{hpc_master_package " .. arg_list .. "}") .."\\n") \
|
|
rpm.define("pname " .. pname) \
|
|
rpm.define("name " .. name) \
|
|
-- io.stderr:write("pname "..rpm.expand("%pname").."\\n\\n") \
|
|
if rpm.expand("%{?hpc_make_modules_extra}") == "" then \
|
|
rpm.define("hpc_make_modules_extra %hpc_make_modules_extra_python") \
|
|
end \
|
|
if rpm.expand("%{?hpc_module_extra}") == "" then \
|
|
rpm.define("hpc_module_extra %hpc_module_extra_python") \
|
|
end \
|
|
}
|
|
|
|
# For python packages, %hpc_write_modules_files is called inside %python_expand.
|
|
# https://github.com/openSUSE/python-rpm-macros#flavor-expansion
|
|
# Provide modules for extra flavors if the expanded flavor has <flavor>_provides defined,
|
|
# such as the primary python flavor providing "python3".
|
|
%hpc_make_modules_extra_python \
|
|
if [ -n "%%{?$python_provides}" ]; then \
|
|
targetdir=%{hpc_module_dep_base} \
|
|
targetdir=${targetdir%%%%/} \
|
|
for extra in %%{?$python_provides}; do \
|
|
ln -sf $targetdir %{buildroot}${targetdir/${python_flavor:-$(cat _current_flavor)}/$extra} \
|
|
done \
|
|
fi
|
|
|
|
%hpc_module_extra_python \
|
|
%{lua: \
|
|
local pyflavor = rpm.expand("%python_flavor") \
|
|
for extra in rpm.expand("%{?" .. pyflavor .. "_provides}"):gmatch("%S+") do \
|
|
print(rpm.expand("%hpc_module_dep_base"):gsub(pyflavor, extra):sub(1,-2) .. "\\n") \
|
|
end \
|
|
}
|
|
|
|
# %hpc_shebang_sanitize_scripts <dir>
|
|
#
|
|
# find all scripts in and below <dir> and sanitize any #!/usr/bin/env ..
|
|
%hpc_shebang_sanitize_scripts() \
|
|
for file in $(find %{1} -type f); do \
|
|
line=$(head -1 $file) \
|
|
if [[ $line =~ \\#\\!.*bin/env ]]; then \
|
|
newline="" \
|
|
case $line in \
|
|
*python3) newline='#! /usr/bin/python3' ;; \
|
|
%{!?_hpc_python3: \
|
|
*python2) newline='#! /usr/bin/python2' ;; \
|
|
*python1*) { %{hpc_verify_python3 $file}; } && \
|
|
newline='#! /usr/bin/python3' || : ;; \
|
|
*python) newline='#! /usr/bin/python' ;; } \
|
|
%{?_hpc_python3: \
|
|
*python2|*python1*|*python) \
|
|
{ %{hpc_verify_python3 $file}; } && \
|
|
newline='#! /usr/bin/python3' || : ;; }\
|
|
*perl) newline='#! /usr/bin/perl' ;; \
|
|
*bash) newline='#! /bin/bash' ;; \
|
|
*tcsh) newline='#! /usr/bin/bash' ;; \
|
|
*csh) newline='#! /usr/bin/csh' ;; \
|
|
*ksh) newline='#! /usr/bin/ksh' ;; \
|
|
*) echo "hpc_cleanup_scripts: \"$line\" found - leaving untouched" >&2 ;;\
|
|
esac; \
|
|
[ -n "$newline" ] && sed -i "1s,^.*,${newline}\\n," $file \
|
|
fi \
|
|
done
|
|
|
|
# %hpc_shebang_remove <file>
|
|
#
|
|
# remove any leading shebang (#!..) lines from <file>
|
|
%hpc_shebang_remove() \
|
|
while true; do \
|
|
line=$(head -1 %{1}) \
|
|
if [[ $line =~ \\#\\!.* ]]; then \
|
|
sed -i "1d" %{1}; \
|
|
else \
|
|
break \
|
|
fi \
|
|
done
|
|
|
|
# %hpc_shebang_prepend_list [ -n <ext> ] <filelist>
|
|
#
|
|
# prenpend a matching shebang, unless explicitely specified
|
|
# using the -n <ext> option, it is determined by the file
|
|
# 'extend'. Known types are: sh, csh, pl, py, awl, lua
|
|
# the execute bit are also set.
|
|
%hpc_shebang_prepend_list(n:) \
|
|
unset _hpc_engine \
|
|
%{-n:_hpc_shebang=%{-n*}} \
|
|
_hpc_files="%{*}" \
|
|
for file in $_hpc_files; do \
|
|
[ -n "$_hpc_engine" ] || _hpc_engine=${file##*.} \
|
|
if [ -n "$_hpc_engine" ]; then \
|
|
unset _hpc_newline \
|
|
case "$_hpc_engine" in \
|
|
sh) _hpc_newline='#! /bin/bash';; \
|
|
csh) _hpc_newline='#! /usr/bin/csh';; \
|
|
pl) _hpc_newline='#! /usr/bin/perl' ;; \
|
|
py) _hpc_newline='#! /usr/bin/python%{?_hpc_python3:3}' ;; \
|
|
awk) _hpc_newline='#! /usr/bin/awk -f' ;; \
|
|
lua) _hpc_newline='#! /usr/bin/lua' ;; \
|
|
*) echo "Unknown file type $_hpc_engine" ;; \
|
|
esac \
|
|
if [ -n "$_hpc_newline" ]; then \
|
|
line=$(head -1 $file) \
|
|
if [[ $line =~ \\#\\!.* ]]; then \
|
|
true \
|
|
else \
|
|
sed -i -e "1s;^;$_hpc_newline\\n;" $file; \
|
|
fi \
|
|
chmod a+x $file \
|
|
fi \
|
|
fi \
|
|
done
|
|
|
|
# %hpc_python_mv_to_sitearch <file> [<subdir>]
|
|
#
|
|
# move <file> to python sitearch subdir <subdir> if set, remove shebang
|
|
# lines and remove any excecute permissions.
|
|
# This should be done on any python files that do not contain
|
|
# any executable code.
|
|
%hpc_python_mv_to_sitearch() \
|
|
_hpc_pydir=%{hpc_python_sitearch_no_singlespec}%{?2:/%{2}} \
|
|
_hpc_base=$(basename %{1}) \
|
|
[ -d %{buildroot}/$_hpc_pydir ] || mkdir -p %{buildroot}/${_hpc_pydir} \
|
|
mv %{buildroot}%{1} %{buildroot}/${_hpc_pydir} \
|
|
[[ "$_hpc_base" =~ .*\.so ]] || chmod a-x %{buildroot}/$_hpc_pydir/$_hpc_base \
|
|
%{hpc_shebang_remove %{buildroot}/$_hpc_pydir/$_hpc_base}
|
|
|
|
# %hpc_verify_python3 <file>
|
|
#
|
|
# verify that code in <file> is valid python 3
|
|
%hpc_verify_python3() \
|
|
/usr/bin/python3 -c "import sys, ast\
|
|
file=sys.argv[1]\
|
|
try:\
|
|
ast.parse(open(file).read()) or sys.exit(1)\
|
|
except SyntaxError:\
|
|
sys.exit(1) \
|
|
sys.exit(0)" %{1}
|
|
|
|
#
|
|
# man pages
|
|
#
|
|
# %{hpc_compress_man <num>} compress man page in %hpc_mandir/man<num>
|
|
%hpc_compress_man() \
|
|
[ -n "%{*}" ] || { echo "no man page list!" >&2 ; exit 1; } \
|
|
for j in %{*}; do \
|
|
for i in $(ls %{buildroot}%{hpc_mandir}/man${j}/*.${j}* | grep -v ".*\.gz$"); \
|
|
do \
|
|
test -L $i && continue \
|
|
gzip $i \
|
|
done; \
|
|
done
|
|
|
|
# wraps macro from macros.cmake - paths replaced by HPC paths.
|
|
%hpc_cmake \
|
|
%{!?cmake:%{error: please include macros.cmake}} \
|
|
%{?cmake: \
|
|
%global __cmake %{_bindir}/cmake \
|
|
%define _bindir %{hpc_bindir} \
|
|
%define _datadir %{hpc_datadir} \
|
|
%define _includedir %{hpc_includedir} \
|
|
%define _infodir %{hpc_infodir} \
|
|
%define _libdir %{hpc_libdir} \
|
|
%define _libexecdir %{hpc_libexecdir} \
|
|
%global _localstatedir %{hpc_localstatedir} \
|
|
%define _mandir %{hpc_mandir} \
|
|
%define _prefix %{hpc_prefix} \
|
|
%define _sbindir %{hpc_sbindir} \
|
|
%global _sharedstatedir %{hpc_sharedstatedir} \
|
|
#Do NOT define _sysconfig to %%hpc_sysconfig here!
|
|
%cmake \\\
|
|
%undefine __cmake \\\
|
|
%undefine _bindir \\\
|
|
%undefine _datadir \\\
|
|
%undefine _includedir \\\
|
|
%undefine _infodir \\\
|
|
%undefine _libdir \\\
|
|
%undefine _libexecdir \\\
|
|
%undefine _localstatedir \\\
|
|
%undefine _mandir \\\
|
|
%undefine _prefix \\\
|
|
%undefine _sbindir \\\
|
|
%undefine _sharedstatedir \\\
|
|
}
|
|
|
|
# wraps macro from macros.meson - paths replaced by HPC paths.
|
|
%hpc_meson \
|
|
%{!?meson:%{error: please include macros.meson}} \
|
|
%{?meson: \
|
|
%global __meson %{_bindir}/meson \
|
|
%define _bindir %{hpc_bindir} \
|
|
%define _datadir %{hpc_datadir} \
|
|
%define _includedir %{hpc_includedir} \
|
|
%define _infodir %{hpc_infodir} \
|
|
%define _libdir %{hpc_libdir} \
|
|
%define _libexecdir %{hpc_libexecdir} \
|
|
%global _localstatedir %{hpc_localstatedir} \
|
|
%define _mandir %{hpc_mandir} \
|
|
%define _prefix %{hpc_prefix} \
|
|
%define _sbindir %{hpc_sbindir} \
|
|
%global _sharedstatedir %{hpc_sharedstatedir} \
|
|
%define _sysconfdir %{hpc_sysconfdir} \
|
|
%meson \\\
|
|
%undefine __meson \\\
|
|
%undefine _bindir \\\
|
|
%undefine _datadir \\\
|
|
%undefine _includedir \\\
|
|
%undefine _infodir \\\
|
|
%undefine _libdir \\\
|
|
%undefine _libexecdir \\\
|
|
%undefine _localstatedir \\\
|
|
%undefine _mandir \\\
|
|
%undefine _prefix \\\
|
|
%undefine _sbindir \\\
|
|
%undefine _sharedstatedir \\\
|
|
%undefine _sysconfdir \\\
|
|
}
|