# 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 ][-n ] # -l : with -l option: -l . default: none # -n : 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 ][-N] # -n : 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 [-v ] -m [-V ] # -C: build a compiler. # -c : set compiler family to (mandatory) # -v : set compiler version to (optional - default: base version) # -M: build an MPI library: -C and -M are mutually exclusive! # -m: : set MPI family to # -V: : set MPI version to (optional - default:) # -e: : 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 # : 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 ][-g ][-s# <.so-version>][-l][-L][-N ][-O ][-P # -n : specify the full package name. This may not be used in conjunction with # the package name extension . # -g : 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. 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 : Specify if a sub-package has different basename (pname) # -q: For internal use only! # -M: use specified name in place of %%name # -O : Add Provides/Obsoletes for package with # version %version, multiple names may be separated by ":" # -P : Add Provides/Obsoletes with %version-%release for package # names derived from the master package name, replacing with # the contents of %_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 ] [-g ] [-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.` 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 _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 # # find all scripts in and below 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 # # remove any leading shebang (#!..) lines from %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 ] # # prenpend a matching shebang, unless explicitely specified # using the -n 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 [] # # move to python sitearch 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 # # verify that code in 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 } compress man page in %hpc_mandir/man %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} \ %define _mandir %{hpc_mandir} \ %define _prefix %{hpc_prefix} \ %define _sbindir %{hpc_sbindir} \ #Do NOT define _sysconfig to %%hpc_sysconfig here! %cmake \\\ %undefine __cmake \\\ %undefine _bindir \\\ %undefine _datadir \\\ %undefine _includedir \\\ %undefine _infodir \\\ %undefine _libdir \\\ %undefine _libexecdir \\\ %undefine _mandir \\\ %undefine _prefix \\\ %undefine _sbindir \\\ } # 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} \ %define _localstatedir %{hpc_localstatedir} \ %define _mandir %{hpc_mandir} \ %define _prefix %{hpc_prefix} \ %define _sbindir %{hpc_sbindir} \ %define _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 \\\ }