mirror of
https://github.com/amd/blis.git
synced 2026-05-04 14:31:12 +00:00
Details: - Commented out redundant setting of LIBBLIS_LINK within all driver- level Makefiles. This variable is already set within common.mk, and so the only time it should be overridden is if the user wants to link to a different copy of libblis. - Very minor changes to build/gen-make-frags/gen-make-frag.sh. - Whitespace and inconsequential quoting change to configure. - Moved top-level 'windows' directory into a new 'attic' directory.
361 lines
11 KiB
Python
361 lines
11 KiB
Python
#! /usr/bin/env python
|
|
#
|
|
# BLIS
|
|
# An object-based framework for developing high-performance BLAS-like
|
|
# libraries.
|
|
#
|
|
# Copyright (C) 2014, The University of Texas at Austin
|
|
#
|
|
# Redistribution and use in source and binary forms, with or without
|
|
# modification, are permitted provided that the following conditions are
|
|
# met:
|
|
# - Redistributions of source code must retain the above copyright
|
|
# notice, this list of conditions and the following disclaimer.
|
|
# - Redistributions in binary form must reproduce the above copyright
|
|
# notice, this list of conditions and the following disclaimer in the
|
|
# documentation and/or other materials provided with the distribution.
|
|
# - Neither the name(s) of the copyright holder(s) nor the names of its
|
|
# contributors may be used to endorse or promote products derived
|
|
# from this software without specific prior written permission.
|
|
#
|
|
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
# HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
#
|
|
#
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Import modules
|
|
import sys
|
|
import os
|
|
import os.path
|
|
import getopt
|
|
import re
|
|
import string
|
|
|
|
# Global variables for command line options, with default settings.
|
|
script_name = ""
|
|
dry_run_flag = False
|
|
verbose_flag = False
|
|
|
|
# Global constants
|
|
config_dirname = "config"
|
|
source_dirname = "frame"
|
|
object_dirname = "obj"
|
|
object_extension = ".obj"
|
|
leaf_list_path = "build/leaf_list"
|
|
revision_filename = "revision"
|
|
rev_varname = "REVISION"
|
|
pwd_varname = "PWD"
|
|
arch_varname = "ARCH_STR"
|
|
build_varname = "BUILD_STR"
|
|
ccompiler_varname = "CCOMPILER_STR"
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
def print_usage():
|
|
|
|
# Print help information.
|
|
print " "
|
|
print " %s" % script_name
|
|
print " "
|
|
print " Field G. Van Zee"
|
|
print " "
|
|
print " Create a config.mk file that is to be included by the nmake Makefile."
|
|
print " This config.mk file is based on a template, but also includes variable"
|
|
print " definitions that are needed for the specific build were are performing."
|
|
print " The variables which are currently appended to config.mk at runtime are:"
|
|
print " - the revision string"
|
|
print " - the path to the current working directory"
|
|
print " - the build string (e.g. debug, release)"
|
|
print " - the architecture string (e.g. x86, x64)"
|
|
print " - the C compiler to use (e.g. icl, cl)"
|
|
print " - a list of paths to the object files to be compiled"
|
|
print " The config.mk file is placed within the config subdirectory."
|
|
print " "
|
|
print " Usage:"
|
|
print " %s [options] flat_dir arch build ccompiler path\\to\\config.mk.in" % script_name
|
|
print " "
|
|
print " The following options are accepted:"
|
|
print " "
|
|
print " -d dry-run"
|
|
print " Go through all the motions, but don't actually output"
|
|
print " the nmake definition file."
|
|
print " -v verbose"
|
|
print " Be verbose about actions (one line of output her action)."
|
|
print " "
|
|
|
|
# Exit the script.
|
|
sys.exit()
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
def main():
|
|
|
|
# Extern our global veriables.
|
|
global script_name
|
|
global dry_run_flag
|
|
global verbose_flag
|
|
|
|
# Get the script name so we can use it in our output.
|
|
( script_dir, script_name ) = os.path.split( sys.argv[0] )
|
|
|
|
try:
|
|
|
|
# Get the command line options.
|
|
options, args = getopt.getopt( sys.argv[1:], "dv")
|
|
|
|
except getopt.GetoptError, err:
|
|
|
|
# print help information and exit:
|
|
print str( err ) # will print something like "option -a not recognized"
|
|
print_usage()
|
|
|
|
# Parse our expected command line options.
|
|
for o, a in options:
|
|
|
|
if o == "-d":
|
|
dry_run_flag = True
|
|
elif o == "-v":
|
|
verbose_flag = True
|
|
else:
|
|
assert False, "unhandled option"
|
|
|
|
# Check the number of arguments after command line option processing.
|
|
n_args = len( args )
|
|
if n_args != 5:
|
|
print_usage()
|
|
|
|
# Acquire the non-optional arguments.
|
|
flat_dir = args[0]
|
|
arch_string = args[1]
|
|
build_string = args[2]
|
|
ccompiler_string = args[3]
|
|
input_filepath = args[4]
|
|
|
|
# Acquire the list of leaf-type directories we will descend into.
|
|
leaf_list = read_leaf_list()
|
|
|
|
# Read the contents of the template file.
|
|
template_file_line_list = read_template_file( input_filepath )
|
|
|
|
# Initialize a new list for the lines to be output
|
|
output_file_line_list = template_file_line_list
|
|
|
|
# Read the revision number from the revision file.
|
|
rev_num_str = read_revision_file( revision_filename )
|
|
|
|
# Add a variable for the revision number of the code we're working with.
|
|
rev_var_value = rev_varname + " = " + rev_num_str + "\n"
|
|
output_file_line_list.append( rev_var_value )
|
|
|
|
# Add a variable for the path to the current working directory and append
|
|
# it to our list.
|
|
pwd_var_value = pwd_varname + " = " + os.getcwd() + "\n"
|
|
output_file_line_list.append( pwd_var_value )
|
|
|
|
# Add a variable for the architecture string and append it to our list.
|
|
arch_var_value = arch_varname + " = " + arch_string + "\n"
|
|
output_file_line_list.append( arch_var_value )
|
|
|
|
# Add a variable for the build type string and append it to our list.
|
|
build_var_value = build_varname + " = " + build_string + "\n"
|
|
output_file_line_list.append( build_var_value )
|
|
|
|
# Add a variable for the C compiler string and append it to our list.
|
|
ccompiler_var_value = ccompiler_varname + " = " + ccompiler_string + "\n"
|
|
output_file_line_list.append( ccompiler_var_value )
|
|
|
|
# Walk the flat subdirectories for each of the leaves.
|
|
for leaf_spec in leaf_list:
|
|
|
|
# Unpack the leaf_spec tuple.
|
|
src_exts, hdr_exts = leaf_spec
|
|
|
|
# Create the paths to the source and object subdirectories.
|
|
src_dirpath = os.path.join( flat_dir, source_dirname )
|
|
obj_dirpath = os.path.join( flat_dir, object_dirname, arch_string, build_string )
|
|
|
|
# Get a list of files from the leaf subdirectory.
|
|
src_filenames = os.listdir( src_dirpath )
|
|
|
|
# This will be the nmake variable name to which we will assign the list
|
|
# of source files.
|
|
nmake_varname = "BLIS_OBJS"
|
|
|
|
# Generate the line to output.
|
|
leaf_line = generate_object_list( nmake_varname, src_filenames, src_exts, obj_dirpath )
|
|
|
|
# Accumulate the lines.
|
|
output_file_line_list.append( leaf_line )
|
|
|
|
# Get the filename part of the input filepath.
|
|
input_filedir, input_filename = os.path.split( input_filepath )
|
|
|
|
# Remove the .in extension in the output filename.
|
|
output_filename = re.sub( '.mk.in', '.mk', input_filename )
|
|
|
|
# Construct the filepath for the output file.
|
|
output_filepath = os.path.join( flat_dir, config_dirname, output_filename )
|
|
|
|
# Write the output lines.
|
|
write_output_file( output_filepath, output_file_line_list )
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
def read_revision_file( filepath ):
|
|
|
|
# Try to open the revision file.
|
|
try:
|
|
|
|
revision_file = open( filepath, 'r' )
|
|
|
|
except IOError, err:
|
|
|
|
print "%s: Couldn't open revision file %s" % ( script_name, filepath )
|
|
sys.exit(1)
|
|
|
|
# Read the first (and only) line.
|
|
line = revision_file.readline()
|
|
|
|
# Close the file.
|
|
revision_file.close()
|
|
|
|
# Grab the string and strip the it of whitespace (should just be a newline).
|
|
rev_num_str = line.strip()
|
|
|
|
# Return the revision number string.
|
|
return rev_num_str
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
def generate_object_list( nmake_varname, src_filenames, src_exts, obj_dirpath ):
|
|
|
|
# Initialize the string as an assignment operation.
|
|
the_line = nmake_varname + " = "
|
|
|
|
# Return early if there are no source extensions for this leaf spec.
|
|
if src_exts == []:
|
|
return ""
|
|
|
|
# Construct a pattern to match any file ending with any of the source file
|
|
# extensions given. This string is going to look something like ".[cf]".
|
|
src_pattern = '\.['
|
|
for src_ext in src_exts:
|
|
src_pattern = src_pattern + src_ext
|
|
src_pattern = src_pattern + ']'
|
|
|
|
# Consider all source files.
|
|
for src_filename in src_filenames:
|
|
|
|
obj_filename = re.sub( src_pattern, '.obj', src_filename )
|
|
|
|
# Create the full path to the file.
|
|
obj_filepath = os.path.join( obj_dirpath, obj_filename )
|
|
|
|
# Be verbose if verbosity was requested.
|
|
if verbose_flag == True:
|
|
print "%s: adding file %s" % ( script_name, obj_filepath )
|
|
|
|
# And then add it to the list.
|
|
the_line = the_line + obj_filepath + " "
|
|
|
|
# Be verbose if verbosity was requested.
|
|
if verbose_flag == True:
|
|
print "%s: %s" % ( script_name, the_line )
|
|
|
|
# Append a newline to the end of the line, for file.writelines().
|
|
the_line = the_line + "\n"
|
|
|
|
# Return the new line.
|
|
return the_line
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
def read_template_file( template_filepath ):
|
|
|
|
# Open the template file as read-only.
|
|
template_file = open( template_filepath, 'r' )
|
|
|
|
# Read all lines in the template file.
|
|
template_file_lines = template_file.readlines()
|
|
|
|
# Close the file.
|
|
template_file.close()
|
|
|
|
# Return the list of lines in the template file.
|
|
return template_file_lines
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
def write_output_file( output_filepath, output_lines ):
|
|
|
|
# Take action only if this is not a dry run.
|
|
if dry_run_flag == False:
|
|
|
|
# Open the template file as writable.
|
|
output_file = open( output_filepath, 'w' )
|
|
|
|
# Write the lines.
|
|
output_file.writelines( output_lines )
|
|
|
|
# Close the file.
|
|
output_file.close()
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
def read_leaf_list():
|
|
|
|
# Open the leaf list file.
|
|
leaf_file = open( leaf_list_path, 'r' )
|
|
|
|
# Read the lines in the file.
|
|
line_list = leaf_file.readlines()
|
|
|
|
# Start with a blank list.
|
|
leaf_list = []
|
|
|
|
# Iterate over the lines.
|
|
for line in line_list:
|
|
|
|
# Split the specification by colon to separate the fields.
|
|
fields = string.split( string.strip( line ), ':' )
|
|
|
|
# Get the individual fields of the specification.
|
|
src_exts = string.split( fields[0], ',' )
|
|
hdr_exts = string.split( fields[1], ',' )
|
|
|
|
# If it's a singleton list of an empty string, make it an empty list.
|
|
if len(src_exts) == 1:
|
|
if src_exts[0] == '':
|
|
src_exts = []
|
|
|
|
# If it's a singleton list of an empty string, make it an empty list.
|
|
if len(hdr_exts) == 1:
|
|
if hdr_exts[0] == '':
|
|
hdr_exts = []
|
|
|
|
# Pack the fields into a tuple.
|
|
leaf_spec = ( src_exts, hdr_exts )
|
|
|
|
# Append the tuple to our list.
|
|
leaf_list.append( leaf_spec )
|
|
|
|
# Return the list.
|
|
return leaf_list
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# Begin by executing main().
|
|
main()
|