Bring over Sven's specfile generator from /tmp/sven-specfile-generator.
This commit was SVN r14628.
Этот коммит содержится в:
родитель
2562253678
Коммит
b9195145e9
83
contrib/dist/linux/README.ompi-spec-generator
поставляемый
Обычный файл
83
contrib/dist/linux/README.ompi-spec-generator
поставляемый
Обычный файл
@ -0,0 +1,83 @@
|
||||
Open MPI specfile generator
|
||||
===========================
|
||||
|
||||
The Open MPI specfile generator is a tool that scans the Open MPI source
|
||||
tree for package description files. Based on this file a specfile will be generated
|
||||
which will produce a RPM for each specified package (if the corresponding files have
|
||||
been created). All files that are not specified to belong to a package will be put in
|
||||
the base package.
|
||||
|
||||
The produced specfile is able to detect at build time if a package RPM should be build
|
||||
or not (e.g. if the gm component hasn't been build the gm package section will be skipped).
|
||||
This approach allows to have one big specfile for all possible build systems.
|
||||
The specfile also dynamically extracts the version information for each package at build
|
||||
time. This is necessary because a static approach would require to know the exact low level
|
||||
library version we want to use for this package.
|
||||
|
||||
-- Naming Convention
|
||||
The base RPM will have the following naming convention:
|
||||
|
||||
<OMPI_NAME>-<OMPI_VERSION>-<OMPI_RELEASE>.<ARCH>.rpm
|
||||
e.g. openmpi-1.2a1r10877M-1.x86_64.rpm
|
||||
|
||||
Each RPM that is build based in a package description will have the following format:
|
||||
|
||||
<OMPI_NAME>-<TYPE>-<PACKAGE_NAME>-<OMPI_VERSIO><PACKAGE_NAME>_<PACKAGE_VERSION>-<OMPI_RELEASE>.<ARCH>.rpm
|
||||
e.g. openmpi-btl-mvapi-1.2a1r10877Mmvapi_4.1.0-1.x86_64.rpm
|
||||
|
||||
|
||||
Package Description File
|
||||
========================
|
||||
Package description files a simple INI files with the suffix ".package" instead of
|
||||
".ini". Here is an example of a descriptor file :
|
||||
|
||||
> cat mvapi.package
|
||||
[mvapi]
|
||||
summary=MVAPI btl component
|
||||
type=btl
|
||||
license=BSD
|
||||
group=Development/Libraries
|
||||
description=MVAPI btl component
|
||||
files=%{_prefix}/lib/openmpi/mca_btl_mvapi.so %{_prefix}/lib/openmpi/mca_btl_mvapi.la
|
||||
version=%{ompi_compile_root}/ompi/mca/btl/mvapi/get_vapi_version
|
||||
vendor=Mellanox
|
||||
>
|
||||
|
||||
-- section name
|
||||
The section name is the name of the package that will be created.
|
||||
|
||||
-- summary
|
||||
This summary will be the summary of the RPM.
|
||||
|
||||
-- description
|
||||
The description will become the description of the RPM.
|
||||
|
||||
-- type
|
||||
Specified the type of the package
|
||||
|
||||
-- license
|
||||
The license of the RPM. (default : BSD)
|
||||
|
||||
-- group
|
||||
The group where this package belongs to. (default = Development/Libraries)
|
||||
|
||||
-- version
|
||||
The version field specifies a command that is executed during the RPM build process to obtain
|
||||
the version number of the package. This command is executed after the source code has been configured,
|
||||
compiled and installed. The %{ompi_compile_root} specifies the top level directory of the source tree.
|
||||
|
||||
-- files
|
||||
List of files that should be part of the package. The %{_prefix} can be used to identify the prefix
|
||||
where Open MPI will be installed. If at least on of the specified files exists the package will be build.
|
||||
|
||||
-- vendor
|
||||
The vendor field of RPM. (default = Open MPI)
|
||||
|
||||
-- requires
|
||||
Additional dependencies for this package. The specfile generator will automatically add a default dependency
|
||||
for the Open MPI base RPM.
|
||||
|
||||
If the Open MPI specfile generator should find multiple definitions of the same package then the "files"
|
||||
information will be merged and all the other fields will be overwritten by the latest information. This
|
||||
allows a decentralized package description (e.g. mvapi BTL + mvapi MPOOL).
|
||||
|
811
contrib/dist/linux/ompi-spec-generator.py
поставляемый
Исполняемый файл
811
contrib/dist/linux/ompi-spec-generator.py
поставляемый
Исполняемый файл
@ -0,0 +1,811 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# generator for Open MPI
|
||||
import sys
|
||||
import os
|
||||
import optparse
|
||||
import ConfigParser
|
||||
|
||||
|
||||
######################################################################
|
||||
# global stuff
|
||||
######################################################################
|
||||
configext = ".package" # the name of the configurations files
|
||||
configfiles = [] # list with all found config files
|
||||
params = 0 # contains the cmd line options
|
||||
packages = {} # directory for packages
|
||||
options = ["name", "type", "license", "summary", "files", "version", "description", "group", "vendor", "requires"]
|
||||
shell_cmds = {}
|
||||
compilers = { "default" : {"compiler":"default",
|
||||
"cc": " ",
|
||||
"cxx":" ",
|
||||
"f77":" ",
|
||||
"fc":" "},
|
||||
"gcc" : {"compiler":"gcc",
|
||||
"cc":"gcc",
|
||||
"cxx":"c++",
|
||||
"f77":"f77",
|
||||
"fc":"gfortran"},
|
||||
"icc" : {"compiler":"icc",
|
||||
"cc":"icc",
|
||||
"cxx":"icpc",
|
||||
"f77":"ifort",
|
||||
"fc":"ifort"}
|
||||
}
|
||||
|
||||
|
||||
copyright_template = """#
|
||||
# Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
|
||||
# University Research and Technology
|
||||
# Corporation. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The University of Tennessee and The University
|
||||
# of Tennessee Research Foundation. All rights
|
||||
# reserved.
|
||||
# Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
|
||||
# University of Stuttgart. All rights reserved.
|
||||
# Copyright (c) 2004-2005 The Regents of the University of California.
|
||||
# All rights reserved.
|
||||
# Copyright (c) 2006 Cisco Systems, Inc. All rights reserved.
|
||||
# $COPYRIGHT$
|
||||
#
|
||||
# Additional copyrights may follow
|
||||
#
|
||||
# $HEADER$
|
||||
#
|
||||
|
||||
# don't stop with an error if we don't pack all files at once
|
||||
%define _unpackaged_files_terminate_build 0
|
||||
|
||||
"""
|
||||
|
||||
build_macro_template = "%%{!?build_%(name)s: %%define build_%(name)s %(value)i}\n"
|
||||
|
||||
build_command_template = '''
|
||||
BUILD_PACKAGE=%(default)s
|
||||
for entry in %(files)s; do
|
||||
for file in $RPM_BUILD_ROOT/$entry; do
|
||||
if [ -e $file ] ; then
|
||||
BUILD_PACKAGE=1
|
||||
fi
|
||||
done
|
||||
done
|
||||
if [ $BUILD_PACKAGE == 1 ] ; then
|
||||
eval export OMPI_PACKAGE_VERSION=`%(version)s`
|
||||
rpmbuild %(mode)s --define \'_topdir %%_topdir\' --define \'build_%(name)s 1\' --define \'build_default 0\' --define \"ompi_package_version $OMPI_PACKAGE_VERSION\" %%{ompi_specfile}
|
||||
fi
|
||||
'''
|
||||
|
||||
global_template = """
|
||||
#
|
||||
# global Open MPI stuff
|
||||
#
|
||||
%%define ompi_name %(name)s
|
||||
%%define ompi_name_prefix %(name_prefix)s
|
||||
%%define ompi_version %(version)s
|
||||
%%{!?ompi_package_version:%%define ompi_package_version default}
|
||||
%%define ompi_extra_version %(extra_version)s
|
||||
%%define ompi_release 1
|
||||
%%define ompi_prefix %(prefix)s
|
||||
%%define ompi_build_root %%{_tmppath}/%%{ompi_name}-%%{ompi_version}-%%{ompi_release}-root
|
||||
%%define ompi_source %%{ompi_name_prefix}%%{ompi_name}-%%{ompi_version}.tar.gz
|
||||
%%define ompi_url %(url)s
|
||||
%%define ompi_specfile %%{_topdir}/SPECS/%(output)s
|
||||
%%define ompi_configure_params %(configure_params)s
|
||||
%%define ompi_compile_root %%{ompi_name_prefix}%%{ompi_name}-%%{ompi_version}
|
||||
|
||||
|
||||
#
|
||||
# fix configure
|
||||
#
|
||||
%%define _prefix %%{ompi_prefix}
|
||||
%%define _sysconfdir %%{_prefix}/etc
|
||||
%%define _libdir %%{_prefix}/lib
|
||||
%%define _includedir %%{_prefix}/include
|
||||
%%define _mandir %%{_prefix}/man
|
||||
%%define _pkgdatadir %%{_prefix}/share/%%{ompi_name}
|
||||
|
||||
"""
|
||||
|
||||
compiler_template = """
|
||||
#
|
||||
# compiler settings
|
||||
#
|
||||
%%define ompi_compiler %(compiler)s
|
||||
%%define ompi_cc \"%(cc)s\"
|
||||
%%define ompi_cxx \"%(cxx)s\"
|
||||
%%define ompi_f77 \"%(f77)s\"
|
||||
%%define ompi_fc \"%(fc)s\"
|
||||
|
||||
"""
|
||||
|
||||
build_template = """
|
||||
######################################################################
|
||||
#
|
||||
# Build section
|
||||
#
|
||||
######################################################################
|
||||
%%if %%{build_build}
|
||||
Summary: Configure and build the Open MPI tree
|
||||
Name: %%{ompi_name_prefix}%%{ompi_name}
|
||||
Version: %%{ompi_version}
|
||||
Release: %%{ompi_release}
|
||||
License: BSD
|
||||
Group: Others
|
||||
URL: %%{ompi_url}
|
||||
Source0: %%{ompi_source}
|
||||
BuildRoot: %%{ompi_build_root}
|
||||
|
||||
%%description
|
||||
This part build and install the Open MPI source tree.
|
||||
|
||||
%%prep
|
||||
%%setup -q
|
||||
|
||||
%%build
|
||||
OMPI_CONFIGURE_FLAGS=\"%%{ompi_configure_params}\"
|
||||
if [ \"%%{ompi_compiler}\" != \"default\" ]; then
|
||||
OMPI_CONFIGURE_FLAGS=\"$OMPI_CONFIGURE_FLAGS CC=%%{ompi_cc} CXX=%%{ompi_cxx} F77=%%{ompi_f77} FC=%%{ompi_fc}\"
|
||||
fi
|
||||
|
||||
%%configure $OMPI_CONFIGURE_FLAGS
|
||||
make -j4
|
||||
|
||||
%%install
|
||||
|
||||
%%clean
|
||||
|
||||
%%files
|
||||
%%defattr(-,root,root,-)
|
||||
|
||||
%%endif
|
||||
|
||||
"""
|
||||
|
||||
|
||||
install_template = """
|
||||
######################################################################
|
||||
#
|
||||
# Install section
|
||||
#
|
||||
######################################################################
|
||||
%%if %%{build_install}
|
||||
Summary: Install a already compiled tree
|
||||
Name: %%{ompi_name_prefix}%%{ompi_name}
|
||||
Version: %%{ompi_version}
|
||||
Release: %%{ompi_release}
|
||||
License: BSD
|
||||
Group: Others
|
||||
URL: %%{ompi_url}
|
||||
Source0: %%{ompi_source}
|
||||
BuildRoot: %%{ompi_build_root}
|
||||
|
||||
%%description
|
||||
This part build and install the Open MPI source tree.
|
||||
|
||||
%%prep
|
||||
|
||||
%%build
|
||||
|
||||
|
||||
%%install
|
||||
cd %%{ompi_compile_root}
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
make DESTDIR=$RPM_BUILD_ROOT install
|
||||
|
||||
|
||||
#
|
||||
# create a module file on request
|
||||
#
|
||||
if [ %(modulefile_condition)s ] ; then
|
||||
%%{__mkdir_p} $RPM_BUILD_ROOT/%(modulefile_path)s/%%{ompi_name}/
|
||||
cat <<EOF >$RPM_BUILD_ROOT/%(modulefile_path)s/%%{ompi_name}/%%{ompi_version}
|
||||
#%%Module
|
||||
|
||||
# NOTE: This is an automatically-generated file! (generated by the
|
||||
# Open MPI RPM). Any changes made here will be lost a) if the RPM is
|
||||
# uninstalled, or b) if the RPM is upgraded or uninstalled.
|
||||
|
||||
proc ModulesHelp { } {
|
||||
puts stderr \"This module adds Open MPI v%(ompi_version)s to various paths\"
|
||||
}
|
||||
|
||||
module-whatis \"Sets up Open MPI v%(ompi_version)s in your enviornment\"
|
||||
|
||||
append-path PATH \"%%{_prefix}/bin/\"
|
||||
append-path LD_LIBRARY_PATH %%{_libdir}
|
||||
append-path MANPATH %%{_mandir}
|
||||
EOF
|
||||
fi
|
||||
|
||||
|
||||
#
|
||||
# profile.d files
|
||||
#
|
||||
if [ %(profile_condition)s ] ; then
|
||||
%%{__mkdir_p} $RPM_BUILD_ROOT/etc/profile.d/
|
||||
cat <<EOF > $RPM_BUILD_ROOT/etc/profile.d/%%{ompi_name}-%%{ompi_version}.sh
|
||||
# NOTE: This is an automatically-generated file! (generated by the
|
||||
# Open MPI RPM). Any changes made here will be lost a) if the RPM is
|
||||
# uninstalled, or b) if the RPM is upgraded or uninstalled.
|
||||
|
||||
CHANGED=0
|
||||
if test -z \"`echo $PATH | grep %%{_prefix}/bin`\"; then
|
||||
PATH=\${PATH}:%%{_prefix}/bin/
|
||||
CHANGED=1
|
||||
fi
|
||||
if test -z \"`echo $LD_LIBRARY_PATH | grep %%{_libdir}`\"; then
|
||||
LD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:%%{_libdir}
|
||||
CHANGED=1
|
||||
fi
|
||||
if test -z \"`echo $MANPATH | grep %%{_mandir}`\"; then
|
||||
MANPATH=\${MANPATH}:%%{_mandir}
|
||||
CHANGED=1
|
||||
fi
|
||||
if test \"$CHANGED\" = \"1\"; then
|
||||
export PATH LD_LIBRARY_PATH MANPATH
|
||||
fi
|
||||
EOF
|
||||
|
||||
cat <<EOF > $RPM_BUILD_ROOT/etc/profile.d/%%{ompi_name}-%%{ompi_version}s.csh
|
||||
# NOTE: This is an automatically-generated file! (generated by the
|
||||
# Open MPI RPM). Any changes made here will be lost a) if the RPM is
|
||||
# uninstalled, or b) if the RPM is upgraded or uninstalled.
|
||||
|
||||
if (\"`echo $PATH | grep %%{_prefix}/bin`\") then
|
||||
setenv PATH \${PATH}:%%{_prefix}/bin/
|
||||
endif
|
||||
if (\"$?LD_LIBRARY_PATH\") then
|
||||
if (\"`echo $LD_LIBRARY_PATH | grep %%{_libdir}`\") then
|
||||
setenv LD_LIBRARY_PATH \${LD_LIBRARY_PATH}:%%{_libdir}
|
||||
endif
|
||||
endif
|
||||
if (\"$?MANPATH\") then
|
||||
if (\"`echo $MANPATH | grep %%{_mandir}`\") then
|
||||
setenv MANPATH \${MANPATH}:%%{_mandir}
|
||||
endif
|
||||
endif
|
||||
EOF
|
||||
fi
|
||||
|
||||
|
||||
%%clean
|
||||
|
||||
%%files
|
||||
%%defattr(-,root,root,-)
|
||||
|
||||
%%endif
|
||||
|
||||
"""
|
||||
|
||||
package_template = """
|
||||
######################################################################
|
||||
#
|
||||
# %(name)s package section
|
||||
#
|
||||
######################################################################
|
||||
%%if %%{build_%(name)s}
|
||||
Summary: %(summary)s
|
||||
Name: %%{ompi_name_prefix}%%{ompi_name}-%(type)s-%(name)s
|
||||
Version: %%{ompi_version}%(name)s_%%{ompi_package_version}%%{ompi_extra_version}
|
||||
Release: %%{ompi_release}
|
||||
License: %(license)s
|
||||
Group: %(group)s
|
||||
URL: %%{ompi_url}
|
||||
Source0: %%{ompi_source}
|
||||
BuildRoot: %%{ompi_build_root}
|
||||
Requires: %(requires)s
|
||||
|
||||
%%description
|
||||
%(description)s
|
||||
|
||||
%%prep
|
||||
|
||||
%%build
|
||||
|
||||
%%install
|
||||
rm -f %(name)s.files
|
||||
rm -f %(name)s.files.tmp
|
||||
for i in %(installed_files)s; do
|
||||
echo $i >> %(name)s.files.tmp
|
||||
done
|
||||
sort -u %(name)s.files.tmp > %(name)s.files
|
||||
rm -f %(name)s.files.tmp
|
||||
|
||||
%%clean
|
||||
for i in `cat %(name)s.files`; do
|
||||
rm -f $RPM_BUILD_ROOT/$i
|
||||
done
|
||||
rm %(name)s.files
|
||||
|
||||
%%files -f %(name)s.files
|
||||
%%defattr(-,root,root,-)
|
||||
|
||||
%%endif
|
||||
|
||||
"""
|
||||
|
||||
default_template = """
|
||||
######################################################################
|
||||
#
|
||||
# default
|
||||
#
|
||||
######################################################################
|
||||
%%if %%{build_default}
|
||||
Summary: Open MPI
|
||||
Name: %%{ompi_name_prefix}%%{ompi_name}
|
||||
Version: %%{ompi_version}%%{ompi_extra_version}
|
||||
Release: %%{ompi_release}
|
||||
License: %%{ompi_license}
|
||||
Group: Development/Library
|
||||
URL: %%{ompi_url}
|
||||
Source0: %%{ompi_source}
|
||||
BuildRoot: %%{ompi_build_root}
|
||||
|
||||
%%description
|
||||
Open MPI is a project combining technologies and resources from
|
||||
several other projects (FT-MPI, LA-MPI, LAM/MPI, and PACX-MPI) in
|
||||
order to build the best MPI library available.
|
||||
|
||||
This RPM contains all the tools necessary to compile, link, and run
|
||||
Open MPI jobs. Additional this RPM also contains modules for communicating
|
||||
via shared memory and TCP networks. Components for other transports (e.g.
|
||||
Myrinet, Infiniband, ...) are provided in separate RPMs.
|
||||
|
||||
|
||||
%%prep
|
||||
|
||||
%%build
|
||||
%(build_cmds)s
|
||||
|
||||
%%install
|
||||
|
||||
%%clean
|
||||
rm -rf $RPM_BUILD_ROOT
|
||||
|
||||
%%files
|
||||
%%defattr(-,root,root,-)
|
||||
%%{ompi_prefix}
|
||||
|
||||
%%endif
|
||||
|
||||
"""
|
||||
|
||||
changelog = """
|
||||
#############################################################################
|
||||
#
|
||||
# Changelog
|
||||
#
|
||||
#############################################################################
|
||||
%changelog
|
||||
* Tue Jun 27 2006 Sven Stork <stork@hlrs.de>
|
||||
- switch to specfile generator
|
||||
|
||||
* Wed Apr 26 2006 Jeff Squyres <jsquyres@cisco.com>
|
||||
- Revamp files listings to ensure that rpm -e will remove directories
|
||||
if rpm -i created them.
|
||||
- Simplify options for making modulefiles and profile.d scripts.
|
||||
- Add oscar define.
|
||||
- Ensure to remove the previous installation root during prep.
|
||||
- Cleanup the modulefile specification and installation; also ensure
|
||||
that the profile.d scripts get installed if selected.
|
||||
- Ensure to list sysconfdir in the files list if it's outside of the
|
||||
prefix.
|
||||
|
||||
* Wed Mar 30 2006 Jeff Squyres <jsquyres@cisco.com>
|
||||
- Lots of bit rot updates
|
||||
- Reorganize and rename the subpackages
|
||||
- Add / formalize a variety of rpmbuild --define options
|
||||
- Comment out the docs subpackage for the moment (until we have some
|
||||
documentation -- coming in v1.1!)
|
||||
|
||||
* Wed May 03 2005 Jeff Squyres <jsquyres@open-mpi.org>
|
||||
- Added some defines for LANL defaults
|
||||
- Added more defines for granulatirty of installation location for
|
||||
modulefile
|
||||
- Differentiate between installing in /opt and whether we want to
|
||||
install environment script files
|
||||
- Filled in files for man and mca-general subpackages
|
||||
|
||||
* Thu Apr 07 2005 Greg Kurtzer <GMKurtzer@lbl.gov>
|
||||
- Added opt building
|
||||
- Added profile.d/modulefile logic and creation
|
||||
- Minor cleanups
|
||||
|
||||
* Fri Apr 01 2005 Greg Kurtzer <GMKurtzer@lbl.gov>
|
||||
- Added comments
|
||||
- Split package into subpackages
|
||||
- Cleaned things up a bit
|
||||
- Sold the code to Microsoft, and now I am retiring. Thanks guys!
|
||||
|
||||
* Wed Mar 23 2005 Mezzanine <mezzanine@kainx.org>
|
||||
- Specfile auto-generated by Mezzanine
|
||||
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# class to represent a package
|
||||
#
|
||||
######################################################################
|
||||
class Package:
|
||||
def __init__(self, name):
|
||||
self.options = {}
|
||||
for option in options:
|
||||
if option == "name":
|
||||
self.options[option] = name
|
||||
elif option == "files":
|
||||
self.options[option] = []
|
||||
elif option == "version":
|
||||
self.options[option] = "/bin/echo unknown"
|
||||
elif option == "group":
|
||||
self.options[option] = "Development/Library"
|
||||
elif option == "license":
|
||||
self.options[option] = "BSD"
|
||||
elif option == "vendor":
|
||||
self.options[option] = "Open MPI"
|
||||
elif option == "requires":
|
||||
name_prefix = ""
|
||||
if ( params.ompi_name_prefix != "%{nil}" ):
|
||||
name_prefix = params.ompi_name_prefix
|
||||
self.options[option] = name_prefix + params.ompi_name + " >= " + params.ompi_version
|
||||
else:
|
||||
self.options[option] = None
|
||||
|
||||
def getOption(self, option):
|
||||
if option in self.options.keys():
|
||||
return self.options[option]
|
||||
else:
|
||||
return None
|
||||
|
||||
def setOption(self, option, value):
|
||||
if ( option == "files" ):
|
||||
# append file list
|
||||
self.options["files"] += value.split()
|
||||
elif ( option == "requires"):
|
||||
self.options["requires"] += ", " + value
|
||||
else:
|
||||
# replace value
|
||||
self.options[option] = value
|
||||
|
||||
def getOptions(self):
|
||||
return self.options
|
||||
|
||||
def Validate(self):
|
||||
if ( self.options["files"] == [] ):
|
||||
error("Package %(package)s does not contain files\n" % {"package":self.options["name"]})
|
||||
sys.exit(-1)
|
||||
|
||||
def Dump(self, prefix=""):
|
||||
global options
|
||||
for option in options:
|
||||
print "%(prefix)s %(name)-15s : %(value)s" % {"prefix":prefix, "name":option, "value":self.options[option]}
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# return the specified package object. If not such an object exist a
|
||||
# new object will be created and stored in the global packages list
|
||||
#
|
||||
######################################################################
|
||||
def get_package(name):
|
||||
global packages
|
||||
if not (name in packages.keys()):
|
||||
packages[name] = Package(name)
|
||||
return packages[name]
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# verbose output
|
||||
#
|
||||
######################################################################
|
||||
def verbose(msg):
|
||||
if (params.verbose or params.debug):
|
||||
print msg
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# debug output
|
||||
#
|
||||
######################################################################
|
||||
def debug(msg):
|
||||
if (params.debug):
|
||||
print msg
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# error output
|
||||
#
|
||||
######################################################################
|
||||
def error(msg):
|
||||
print "+++ ERROR : " + msg
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# error output
|
||||
#
|
||||
######################################################################
|
||||
def get_compiler(name):
|
||||
if name in compilers.keys():
|
||||
return compilers[name]
|
||||
else:
|
||||
error("Failed to find comiler : "+name);
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# interactive shell
|
||||
#
|
||||
######################################################################
|
||||
|
||||
def shell_help(cmd):
|
||||
for item in shell_cmds.values():
|
||||
print "%(cmd)-10s - %(help)s" % {"cmd":item["name"], "help":item["help"]}
|
||||
return True
|
||||
|
||||
def shell_quit(cmd):
|
||||
return False
|
||||
|
||||
def shell_list(cmd):
|
||||
return True
|
||||
|
||||
def shell_list(cmd):
|
||||
for package in packages.keys():
|
||||
print package
|
||||
return True
|
||||
|
||||
def shell_show(cmd):
|
||||
if len(cmd) < 2:
|
||||
print "Usage : show PACKAGE\n"
|
||||
else:
|
||||
if cmd[1] in packages.keys():
|
||||
package = packages[cmd[1]]
|
||||
package.Dump()
|
||||
else:
|
||||
print "Invalid package : " + cmd[1]
|
||||
return True
|
||||
|
||||
def shell_drop(cmd):
|
||||
if len(cmd) < 2:
|
||||
print "Usage : drop PACKAGE"
|
||||
else:
|
||||
if cmd[1] in packages.keys():
|
||||
packages.pop(cmd[1])
|
||||
else:
|
||||
print "Package not found : " + cmd[1]
|
||||
return True
|
||||
|
||||
def shell_write(cmd):
|
||||
write_specfile(packages.values())
|
||||
return True
|
||||
|
||||
def register_shell_cmd(name, help, function):
|
||||
shell_cmds[name] = {"name":name, "help":help, "function":function}
|
||||
|
||||
def shell():
|
||||
loop = True
|
||||
register_shell_cmd("help", "Display list of available commands.", shell_help)
|
||||
register_shell_cmd("quit", "Quit the interactive shell", shell_quit)
|
||||
register_shell_cmd("list", "List all found packages", shell_list)
|
||||
register_shell_cmd("show", "Display one specific package", shell_show)
|
||||
register_shell_cmd("drop", "Remove the specified package from the list", shell_drop)
|
||||
register_shell_cmd("write", "Write the specfile", shell_write)
|
||||
print "ompi-spec-generator interactive shell"
|
||||
print "Type 'help' to get more information about available commands."
|
||||
while loop:
|
||||
try:
|
||||
cmd = raw_input("ompi-spec-generator> ")
|
||||
cmd = cmd.split()
|
||||
if 0 == len(cmd):
|
||||
continue
|
||||
if ( cmd[0] in shell_cmds.keys() ):
|
||||
shell_cmd = shell_cmds[cmd[0]]
|
||||
shell_cmd_func = shell_cmd["function"]
|
||||
loop = shell_cmd_func(cmd)
|
||||
else:
|
||||
print "Invalid command"
|
||||
except Exception:
|
||||
print "\n"
|
||||
continue
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# interactive shell
|
||||
#
|
||||
######################################################################
|
||||
def write_specfile(build_packages):
|
||||
global params
|
||||
# create output file
|
||||
print "--> Create output file"
|
||||
verbose(" Open outout file : %(filename)s" % {"filename":params.output})
|
||||
specfile = open(params.output, 'w')
|
||||
verbose(" Write copyright header")
|
||||
specfile.write(copyright_template)
|
||||
|
||||
verbose(" Create build macros")
|
||||
specfile.write("# macros to select which part of the specfile should be active\n")
|
||||
for package in build_packages:
|
||||
specfile.write(build_macro_template % {"name":package.getOption("name"), "value":0})
|
||||
specfile.write(build_macro_template % {"name":"build", "value":0})
|
||||
specfile.write(build_macro_template % {"name":"install", "value":0})
|
||||
specfile.write(build_macro_template % {"name":"default", "value":1})
|
||||
|
||||
verbose(" Write global macro section")
|
||||
global_params = {"name":params.ompi_name, "prefix" : params.ompi_prefix, "url":params.ompi_url, "version":params.ompi_version, "output":params.output, "extra_version":params.ompi_extra_version, "configure_params":params.ompi_configure_params, "name_prefix":params.ompi_name_prefix}
|
||||
specfile.write(global_template % global_params)
|
||||
|
||||
verbose(" Write compiler section")
|
||||
specfile.write(compiler_template % get_compiler(params.ompi_compiler))
|
||||
|
||||
verbose(" Create package sections")
|
||||
build_cmds = ""
|
||||
if params.no_build:
|
||||
build_cmds += build_command_template % {"files":"/no_build", "default":"0", "name":"build", "mode":"-bc", "version":"/bin/echo unknown"}
|
||||
else:
|
||||
build_cmds += build_command_template % {"files":"/no_build", "default":"1", "name":"build", "mode":"-bc", "version":"/bin/echo unknown"}
|
||||
if params.no_install:
|
||||
build_cmds += build_command_template % {"files":"/no_install", "default":"0", "name":"install", "mode":"-bi", "version":"/bin/echo unknown"}
|
||||
else:
|
||||
build_cmds += build_command_template % {"files":"/no_install", "default":"1", "name":"install", "mode":"-bi", "version":"/bin/echo unknown"}
|
||||
for package in build_packages:
|
||||
verbose(" Create section for " + package.getOption("name"));
|
||||
package_params = package.getOptions()
|
||||
package_params["installed_files"] = ""
|
||||
for f in package_params["files"]:
|
||||
package_params["installed_files"] += "\"" + f + "\" "
|
||||
specfile.write(package_template % package_params);
|
||||
# create build command
|
||||
build_cmds += build_command_template % {"files":package_params["installed_files"], "default":"0", "name":package_params["name"], "mode":"-bb", "version":package_params["version"]}
|
||||
|
||||
verbose(" Create build section")
|
||||
specfile.write(build_template % {"ompi_prefix":params.ompi_prefix})
|
||||
|
||||
verbose(" Create install section")
|
||||
inst_params = {}
|
||||
inst_params["ompi_name"] = params.ompi_name
|
||||
inst_params["ompi_version"] = params.ompi_version
|
||||
if params.ompi_modulefile_path == None:
|
||||
inst_params["modulefile_condition"] = "1 == 0"
|
||||
inst_params["modulefile_path"] = "nirwana"
|
||||
else:
|
||||
inst_params["modulefile_condition"] = "0 == 0"
|
||||
inst_params["modulefile_path"] = params.ompi_modulefile_path
|
||||
if params.ompi_profile_files:
|
||||
inst_params["profile_condition"] = "0 == 0"
|
||||
else:
|
||||
inst_params["profile_condition"] = "1 == 0"
|
||||
specfile.write(install_template % inst_params)
|
||||
|
||||
verbose(" Create default section")
|
||||
default_params = { "build_cmds": build_cmds, "version":params.ompi_version}
|
||||
specfile.write(default_template % default_params)
|
||||
|
||||
verbose(" Write changelog")
|
||||
specfile.write(changelog)
|
||||
|
||||
verbose(" Close outputfile")
|
||||
specfile.close()
|
||||
|
||||
|
||||
|
||||
######################################################################
|
||||
#
|
||||
# main function
|
||||
#
|
||||
######################################################################
|
||||
def main():
|
||||
# parse comand line parameters
|
||||
global params
|
||||
param_parser = optparse.OptionParser()
|
||||
param_parser.add_option("-r", "--root", action="store", dest="root", default="../../../",help="Specify the top root directory of the Open MPI Sources.")
|
||||
param_parser.add_option("-v", "--verbose", action="store_true", dest="verbose", default=False, help="Dis/Enable verbose output.")
|
||||
param_parser.add_option("-d", "--debug", action="store_true", dest="debug", default=False, help="Dis/Enable debug output.")
|
||||
param_parser.add_option("-p", "--packages", action="store", dest="packages", default=None, help="Comma separated list of packages to build.")
|
||||
param_parser.add_option("-o", "--output", action="store", dest="output", default=None, help="Specify the filename of the outputfile.")
|
||||
param_parser.add_option("-i", "--interactive", action="store_true", dest="interactive", default=False, help="Enter interactive shell after all config files have been parsed.")
|
||||
param_parser.add_option("--no-build", action="store_true", dest="no_build", default=False, help="Disable the build section.")
|
||||
param_parser.add_option("--no-install", action="store_true", dest="no_install", default=False, help="Disable the installation.")
|
||||
param_parser.add_option("--ompi-name", action="store", dest="ompi_name", default="openmpi", help="Specify the name.")
|
||||
param_parser.add_option("--ompi-prefix", action="store", dest="ompi_prefix", default="/opt/openmpi", help="Specify the installation prefix.")
|
||||
param_parser.add_option("--ompi-url", action="store", dest="ompi_url", default="http://www.open-mpi.org", help="Specify the tarball to use.")
|
||||
param_parser.add_option("--ompi-version", action="store", dest="ompi_version", default="1.1", help="Specify the version to use.")
|
||||
param_parser.add_option("--ompi-extra-version", action="store", dest="ompi_extra_version", default="%{nil}", help="Specify extra version to indicate special builds.")
|
||||
param_parser.add_option("--ompi-name-prefix", action="store", dest="ompi_name_prefix", default="%{nil}", help="Specify and name prefix for the RPMS.")
|
||||
param_parser.add_option("--ompi-configure-params", action="store", dest="ompi_configure_params", default="%{nil}", help="Specify extra version to indicate special builds.")
|
||||
param_parser.add_option("--ompi-compiler", action="store", dest="ompi_compiler", default="default", help="Specify the compiler to use.(default: let configure decide)")
|
||||
param_parser.add_option("--ompi-modulefile-path", action="store", dest="ompi_modulefile_path", default=None, help="Sets the path of the modulefile directory. If this parameter is omitted no modulefile will be generated.")
|
||||
param_parser.add_option("--ompi-profile-file", action="store_true", dest="ompi_profile_files", default=False, help="Add file to /etc/profile.d.")
|
||||
(params, args) = param_parser.parse_args()
|
||||
if ( params.root == None ):
|
||||
error("You must specify a the top root directory (option -r).")
|
||||
sys.exit(-1)
|
||||
# fix parameters
|
||||
params.root = os.path.abspath(params.root)
|
||||
if ( params.ompi_prefix == "/opt/openmpi" ):
|
||||
params.ompi_prefix = params.ompi_prefix + "/" + params.ompi_version
|
||||
|
||||
print "--> Using root " + params.root
|
||||
if params.output == None:
|
||||
params.output = params.ompi_name_prefix + params.ompi_name + "-" + params.ompi_version + ".spec"
|
||||
|
||||
# find config files
|
||||
print "--> Search for configuration files"
|
||||
for root, dirs, files in os.walk(params.root):
|
||||
for f in files:
|
||||
if configext != os.path.splitext(f)[1]:
|
||||
continue
|
||||
cf = root + "/" + f
|
||||
configfiles.append(cf)
|
||||
verbose(" Found : " + cf)
|
||||
|
||||
# parse config files
|
||||
print "--> Parse config files"
|
||||
for file in configfiles:
|
||||
verbose(" Parse " + file)
|
||||
# parse configfile
|
||||
config = ConfigParser.ConfigParser()
|
||||
if not (file in config.read(file)):
|
||||
error("Failed to parse " + file )
|
||||
sys.exit(-1)
|
||||
for section in config.sections():
|
||||
verbose(" Found package information : " + section)
|
||||
package = get_package(section)
|
||||
for option in config.options(section):
|
||||
debug(" Found " + option + "= " + config.get(section, option))
|
||||
# allow only predefined sections
|
||||
if not(option in options):
|
||||
error("Parse error, found invalid option")
|
||||
error("File : " + file)
|
||||
error("Package : " + section)
|
||||
error("Option : " + option)
|
||||
sys.exit(-1)
|
||||
# add data into the package object
|
||||
package.setOption(option, config.get(section, option))
|
||||
|
||||
# shell or not shell that's the question
|
||||
if params.interactive:
|
||||
shell()
|
||||
return
|
||||
|
||||
# filter packages
|
||||
print "--> Select packages"
|
||||
build_packages = []
|
||||
# filter packages
|
||||
if params.packages != None:
|
||||
verbose(" Apply user profided packages list : " + params.packages);
|
||||
user_packages = params.packages.split(',')
|
||||
for name in packages.keys():
|
||||
if name in user_packages:
|
||||
build_packages.append(packages[name])
|
||||
else:
|
||||
verbose(" Remove package : " + name);
|
||||
else:
|
||||
# if nothing is specified than use all found packages
|
||||
build_packages = packages.values()
|
||||
|
||||
# do sanity check on the components
|
||||
print "--> Sanity check packages"
|
||||
for package in build_packages:
|
||||
verbose(" Check package " + package.getOption("name") )
|
||||
if params.debug:
|
||||
package.Dump(" ")
|
||||
package.Validate()
|
||||
|
||||
# write output file
|
||||
write_specfile(build_packages)
|
||||
|
||||
# done
|
||||
print "--> Finished."
|
||||
|
||||
|
||||
if ("__main__" == __name__):
|
||||
main()
|
Загрузка…
Ссылка в новой задаче
Block a user