File macros.hpc of Package suse-hpc

# 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}

# Get rpm version string from %rpmversion that can be used in
# comparisons if this macro exists. If not, return 0
%_hpc_rpmv %{lua: \
   v=rpm.expand("%rpmversion") \
   r=0 \
   if (v == "%rpmversion") then \
     print("0") \
   else \
     for w in string.gmatch(v, "(%w+)") do \
       r=r*100+w \
     end \
     print(math.tointeger(r)) \
   end \
}

#
# 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) \
%if %{_hpc_rpmv} < 41901 \
%doc $(%_tmpexec)./%{_readme} \
%else \
%doc '$(%_tmpexec)'./%{_readme} \
%endif \
} \
%{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 -n $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 \\\
 }
openSUSE Build Service is sponsored by