812 строки
27 KiB
Python
812 строки
27 KiB
Python
|
#!/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()
|