Files
blis/configure
Field G. Van Zee bf03503059 Renamed (shortened) a few build system variables.
Details:
- Renamed the following variables in config.mk (via build/config.mk.in):
    BLIS_ENABLE_VERBOSE_MAKE_OUTPUT -> ENABLE_VERBOSE
    BLIS_ENABLE_STATIC_BUILD        -> MK_ENABLE_STATIC
    BLIS_ENABLE_SHARED_BUILD        -> MK_ENABLE_SHARED
    BLIS_ENABLE_BLAS2BLIS           -> MK_ENABLE_BLAS
    BLIS_ENABLE_CBLAS               -> MK_ENABLE_CBLAS
    BLIS_ENABLE_MEMKIND             -> MK_ENABLE_MEMKIND
  and also renamed all uses of these variables in makefiles and makefile
  fragments. Notice that we use the "MK_" prefix so that those variables
  can be easily differentiated (such as via grep) from their "BLIS_" C
  preprocessor macro counterparts.
- Other whitespace changes to build/config.mk.in.
- Renamed the following C preprocessor macros in bli_config.h (via
  build/bli_config.h.in):
    BLIS_ENABLE_BLAS2BLIS        -> BLIS_ENABLE_BLAS
    BLIS_DISABLE_BLAS2BLIS       -> BLIS_DISABLE_BLAS
    BLIS_BLAS2BLIS_INT_TYPE_SIZE -> BLIS_BLAS_INT_TYPE_SIZE
  and also renamed all relevant uses of these macros in BLIS source
  files.
- Renamed "blas2blis" variable occurrences in configure to "blas", as
  was done in build/config.mk.in and build/bli_config.h.in.
- Renamed the following functions in frame/base/bli_info.c:
    bli_info_get_enable_blas2blis() -> bli_info_get_enable_blas()
    bli_info_get_blas2blis_int_type_size()
                                    -> bli_info_get_blas_int_type_size()
- Remove bli_config.h during 'make cleanh' target of top-level Makefile.
2018-05-08 16:49:22 -05:00

2525 lines
76 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# 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 of The University of Texas at Austin 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.
#
#
#
# -- Helper functions ----------------------------------------------------------
#
print_usage()
{
# Use the version string in the 'version' file since we don't have
# the patched version string yet.
if [ -z "${version}" ]; then
version=$(cat "${version_filepath}")
fi
# Echo usage info.
echo " "
echo " ${script_name} (BLIS ${version})"
#echo " "
#echo " BLIS ${version}"
echo " "
echo " Field G. Van Zee"
echo " "
echo " Configure BLIS's build system for compilation using a specified"
echo " configuration directory."
echo " "
echo " Usage:"
echo " "
echo " ${script_name} [options] [env. vars.] confname"
echo " "
echo " Arguments:"
echo " "
echo " confname The name of the sub-directory inside of the 'config'"
echo " directory containing the desired BLIS configuration."
echo " Note that confname MUST be specified; if it is not,"
echo " configure will complain. To build a completely generic"
echo " implementation, use the 'generic' configuration"
echo " "
echo " Options:"
echo " "
echo " -p PREFIX, --prefix=PREFIX"
echo " "
echo " The path to which make will install all build products."
echo " If given, this option implicitly sets LIBDIR to"
echo " PREFIX/lib and INCDIR to PREFIX/include (see below); if"
echo " not given, PREFIX defaults to \$(HOME)/blis. If PREFIX"
echo " refers to a directory that does not exist, it will be"
echo " created."
echo " "
echo " --libdir=LIBDIR"
echo " "
echo " The path to which make will install libraries. If given,"
echo " LIBDIR will override the corresponding directory implied"
echo " by --prefix; if not not given, LIBDIR defaults to"
echo " PREFIX/lib. If LIBDIR refers to a directory that does not"
echo " exist, it will be created."
echo " "
echo " --includedir=INCDIR"
echo " "
echo " The path to which make will install development header"
echo " files. If given, INCDIR will override the corresponding"
echo " directory implied by --prefix; if not given, INCDIR"
echo " defaults to PREFIX/include. If INCDIR refers to a"
echo " directory that does not exist, it will be created."
echo " "
echo " -d DEBUG, --enable-debug[=DEBUG]"
echo " "
echo " Enable debugging symbols in the library. If argument"
echo " DEBUG is given as 'opt', then optimization flags are"
echo " kept in the framework, otherwise optimization is"
echo " turned off."
echo " "
echo " --enable-verbose-make, --disable-verbose-make"
echo " "
echo " Enable (disabled by default) verbose compilation output"
echo " during make."
echo " "
echo " --disable-static, --enable-static"
echo " "
echo " Disable (enabled by default) building BLIS as a static"
echo " library. May be combined with --enable-shared."
echo " "
echo " --enable-shared, --disable-static"
echo " "
echo " Enable (disabled by default) building BLIS as a shared"
echo " library. May be combined with --enable-static."
echo " "
echo " -t MODEL, --enable-threading[=MODEL], --disable-threading"
echo " "
echo " Enable threading in the library, using threading model"
echo " MODEL={openmp,pthreads,no}. If MODEL=no or "
echo " --disable-threading is specified, threading will be"
echo " disabled. The default is 'no'."
echo " "
echo " --disable-packbuf-pools, --enable-packbuf-pools"
echo " "
echo " Disable (enabled by default) use of internal memory"
echo " pools for managing packing buffers. When disabled,"
echo " the function specified by BLIS_MALLOC_POOL is called"
echo " on-demand, whenever a packing buffer is needed, and"
echo " the buffer is released via the function specified by"
echo " BLIS_FREE_POOL() when the loop in which it was"
echo " allocated terminates. When enabled, the memory pools"
echo " minimize calls to both BLIS_MALLOC_POOL() and"
echo " BLIS_FREE_POOL(), especially in a multithreaded"
echo " environment, but does so through a mechanism that may"
echo " incur additional overhead in some (but not all)"
echo " situations."
echo " "
echo " -q, --quiet Suppress informational output. By default, configure"
echo " is verbose. (NOTE: -q is not yet implemented)"
echo " "
echo " -i SIZE, --int-size=SIZE"
echo " "
echo " Set the size (in bits) of internal BLIS integers and"
echo " integer types used in native BLIS interfaces. The"
echo " default inteter type size is architecture dependent."
echo " (Hint: You can always find this value printed at the"
echo " beginning of the testsuite output.)"
echo " "
echo " -b SIZE, --blas-int-size=SIZE"
echo " "
echo " Set the size (in bits) of integer types in external"
echo " BLAS and CBLAS interfaces, if enabled. The default"
echo " integer type size used in BLAS/CBLAS is 32 bits."
echo " "
echo " --disable-blas, --enable-blas"
echo " "
echo " Disable (enabled by default) building the BLAS"
echo " compatibility layer."
echo " "
echo " --enable-cblas, --disable-cblas"
echo " "
echo " Enable (disabled by default) building the CBLAS"
echo " compatibility layer. This automatically enables the"
echo " BLAS compatibility layer as well."
echo " "
echo " --with-memkind, --without-memkind"
echo " "
echo " Forcibly enable or disable the use of libmemkind's"
echo " hbw_malloc() and hbw_free() as substitutes for malloc()"
echo " and free(), respectively, when allocating memory for"
echo " BLIS's memory pools, which are used to manage buffers"
echo " into which matrices are packed. The default behavior"
echo " for this option is environment-dependent; if configure"
echo " detects the presence of libmemkind, libmemkind is used"
echo " by default, and otherwise it is not used by default."
echo " "
echo " --force-version=STRING"
echo " "
echo " Force configure to use an arbitrary version string"
echo " STRING. This option may be useful when repackaging"
echo " custom versions of BLIS by outside organizations."
echo " "
echo " -c, --show-config-lists"
echo " "
echo " Print the config and kernel lists, and kernel-to-config"
echo " map after they are read from file. This can be useful"
echo " when debugging certain configuration issues, and/or as"
echo " a sanity check to make sure these lists are constituted"
echo " as expected."
echo " "
echo " -h, --help Output this information and quit."
echo " "
echo " Environment Variables:"
echo " "
echo " CC Specifies the C compiler to use."
echo " RANLIB Specifies the ranlib executable to use."
echo " "
echo " Environment variables may also be specified as command line"
echo " options, e.g.:"
echo " "
echo " ./configure [options] CC=gcc sandybridge"
echo " "
echo " Note that not all compilers are compatible with a given"
echo " configuration."
echo " "
# Exit with non-zero exit status
exit 1
}
query_array()
{
local arr key var_name
arr="$1"
key="$2"
var_name="${arr}_${key}"
echo "${!var_name}"
}
assign_key_value()
{
local arr key val
arr="$1"
key="$2"
val="$3"
printf -v "${arr}_${key}" %s "${val}"
}
#
# FGVZ: This commented-out function is being kept as an example how how
# to effectively "pass by reference" in bash. That is, pass the name of
# a variable, instead of its conents, and then let the function use the
# variable by prepending a $, at which time it can evaluate the string
# as if it were a literal variable occurance.
#
#filteradd_to_list()
#{
# local dlist ditem list_c item_c is_blacklisted
#
# # Add $1 to the list identified by $2, but only if $1 is not
# # found in a blacklist.
#
# # Note: $2 can actually be a list of items.
# dlist=\$"$1"
# ditem=\$"$2"
#
# # Acquire the contents of $list and $item and store them in list_c
# # and item_c, respectively.
# list_c=$(eval "expr \"$dlist\" ")
# item_c=$(eval "expr \"$ditem\" ")
#
# # Iterate over $item_c in case it is actually multiple items.
# for cur_item in $item_c; do
#
# is_blacklisted=$(is_in_list "${cur_item}" "${config_blist}")
# if [ ${is_blacklisted} == "false" ]; then
#
# # If cur_item is not blacklisted, add it to list_c.
# list_c="${list_c} ${cur_item}"
# fi
# done
#
# # Update the argument.
# eval "$1=\"${list_c}\""
#}
pass_config_kernel_registries()
{
local filename passnum
local all_blist
local curline list item config kernels
local cname clist klist
# Read function arguments:
# first argument: the file containing the configuration registry.
# second argument: the pass number: 0 or 1. Pass 0 builds the
# indirect config blacklist (indirect_blist) ONLY. Pass 1 actually
# begins populating the config and kernel registries, and assumes
# the indirect_blist has already been created.
filename="$1"
passnum="$2"
# Initialize a list of indirect blacklisted configurations for the
# current iteration. These are configurations that are invalidated
# by the removal of blacklisted configurations. For example, if
# haswell is registered as needing the 'haswell' and 'zen' kernel
# sets:
#
# haswell: haswell/haswell/zen
#
# and 'zen' was blacklisted because of the compiler version, then
# the 'haswell' configuration must be omitted from the registry,
# as it no longer has all of the kernel sets it was expecting.
if [ "${passnum}" == "0" ]; then
indirect_blist=""
fi
# For convenience, merge the original and indirect blacklists.
# NOTE: During pass 0, all_blist is equal to config_blist, since
# indirect_blist is still empty.
all_blist="${config_blist} ${indirect_blist}"
while read -r line
do
curline="${line}"
# Remove everything after comment character '#'.
curline=${curline%%#*}
# We've stripped out leading whitespace and trailing comments. If
# the line is now empty, then we can skip it altogether.
if [ "x${curline}" = "x" ]; then
continue;
fi
# Read the config name and config list for the current line.
cname=${curline%%:*}
list=${curline##*:}
# If we encounter a slash, it means the name of the configuration
# and the kernel set needed by that configuration are different.
if [[ "${list}" == *[/]* ]]; then
#echo "Slash found."
klist=""
clist=""
for item in "${list}"; do
# The sub-configuration name is always the first sub-word in
# the slash-separated compound word.
config=${item%%/*}
# Delete the sub-configuration name from the front of the
# string, leaving the slash-separated kernel names (or just
# the kernel name, if there is only one).
kernels=${list#*/}
# Replace the slashes with spaces to transform the string
# into a space-separated list of kernel names.
kernels=$(echo -e ${kernels} | sed -e "s/\// /g")
clist="${clist} ${config}"
klist="${klist} ${kernels}"
done
else
#echo "Slash not found."
clist=${list}
klist=${list}
fi
# Strip out whitespace from the config name and config/kernel list
# on each line.
cname=$(canonicalize_ws "${cname}")
clist=$(canonicalize_ws "${clist}")
klist=$(canonicalize_ws "${klist}")
# Next, we prepare to:
# - pass 0: inspect klist for blacklisted configurations, which may
# reveal configurations as needing to be indirectly blacklisted.
# - pass 1: compare cname to the blacklists and commit clist/klist
# to their respective registries, as appropriate.
# Handle singleton and umbrella configuration entries separately.
if [ $(is_singleton_family "${cname}" "${clist}") == "true" ]; then
# Singleton configurations/families.
# Note: for singleton families, clist contains one item, which
# always equals cname, but klist could contain more than one
# item.
# Only consider updating the indirect blacklist (pass 0) or
# committing clist and klist to the registries (pass 1) if the
# configuration name (cname) is not blacklisted.
if [ $(is_in_list "${cname}" "${all_blist}") == "false" ]; then
if [ "${passnum}" == "0" ]; then
# Even if the cname isn't blacklisted, one of the requisite
# kernels might be, so we need to check klist for blacklisted
# items. If we find one, we must assume that the entire entry
# must be thrown out. (Ideally, we would simply fall back to
# reference code for the blacklisted kernels, but that is not
# at all straightforward under the current configuration
# system architecture.) Thus, we add cname to the indirect
# blacklist.
for item in ${klist}; do
if [ $(is_in_list "${item}" "${config_blist}") == "true" ]; then
indirect_blist="${indirect_blist} ${cname}"
break
fi
done
fi
if [ "${passnum}" == "1" ]; then
# Store the clist to the cname key of the config registry.
#config_registry[${cname}]=${clist}
#printf -v "config_registry_${cname}" %s "${clist}"
assign_key_value "config_registry" "${cname}" "${clist}"
fi
fi
if [ "${passnum}" == "1" ]; then
# Store the klist to the cname key of the kernel registry.
#kernel_registry[${cname}]=${klist}
#printf -v "kernel_registry_${cname}" %s "${klist}"
assign_key_value "kernel_registry" "${cname}" "${klist}"
fi
else
# Umbrella configurations/families.
# First we check cname, which should generally not be blacklisted
# for umbrella families, but we check anyway just to be safe.
if [ $(is_in_list "${cname}" "${all_blist}") == "false" ]; then
if [ "${passnum}" == "1" ]; then
# Check each item in the clist and klist. (At this point,
# clist == klist.) If any sub-config is blacklisted, we
# omit it from clist and klist.
for item in ${clist}; do
if [ $(is_in_list "${item}" "${all_blist}") == "true" ]; then
clist=$(remove_from_list "${item}" "${clist}")
klist=$(remove_from_list "${item}" "${klist}")
fi
done
# Store the config and kernel lists to entries that
# corresponds to the config name.
#config_registry[${cname}]=${clist}
#kernel_registry[${cname}]=${klist}
#printf -v "config_registry_${cname}" %s "${clist}"
#printf -v "kernel_registry_${cname}" %s "${klist}"
assign_key_value "config_registry" "${cname}" "${clist}"
assign_key_value "kernel_registry" "${cname}" "${klist}"
fi
fi
fi
done < "${filename}"
if [ "${passnum}" == "0" ]; then
# Assign the final indirect blacklist (with whitespace removed).
indirect_blist="$(canonicalize_ws ${indirect_blist})"
fi
}
read_registry_file()
{
local filename
local clist klist
local iterate_again config
local cr_var mem mems_mem newclist
local kr_var ker kers_ker newklist
filename="$1"
# Execute an initial pass through the config_registry file so that
# we can accumulate a list of indirectly blacklisted configurations,
# if any.
pass_config_kernel_registries "${filename}" "0"
# Now that the indirect_blist has been created, make a second pass
# through the 'config_registry' file, this time creating the actual
# config and kernel registry data structures.
pass_config_kernel_registries "${filename}" "1"
# Now we must go back through the config_registry and subsitute any
# configuration families with their constituents' members. Each time
# one of these substitutions occurs, we set a flag that causes us to
# make one more pass. (Subsituting a singleton definition does not
# prompt additional iterations.) This process stops when a full pass
# does not result in any subsitution.
iterate_again="1"
while [ "${iterate_again}" == "1" ]; do
iterate_again="0"
#for config in "${!config_registry[@]}"; do
for cr_var in ${!config_registry_*}; do
config=${cr_var##config_registry_}
clist=$(query_array "config_registry" ${config})
# The entries that define singleton families should never need
# any substitution.
if [ $(is_singleton_family "${config}" "${clist}") == "true" ]; then
continue
fi
#for mem in ${config_registry[$config]}; do
#for mem in ${!cr_var}; do
for mem in ${clist}; do
#mems_mem="${config_registry[${mem}]}"
mems_mem=$(query_array "config_registry" ${mem})
# If mems_mem is empty string, then mem was not found as a key
# in the config list associative array. In that case, we continue
# and will echo an error later in the script.
if [ "${mems_mem}" == "" ]; then
#echo " config for ${mem} is empty string! no entry in config list."
continue;
fi
if [ "${mem}" != "${mems_mem}" ]; then
#clist="${config_registry[$config]}"
clist=$(query_array "config_registry" ${config})
# Replace the current config with its constituent config set,
# canonicalize whitespace, and then remove duplicate config
# set names, if they exist. Finally, update the config registry
# with the new config list.
newclist=$(echo -e "${clist}" | sed -e "s/${mem}/${mems_mem}/g")
newclist=$(canonicalize_ws "${newclist}")
newclist=$(rm_duplicate_words "${newclist}")
#config_registry[${config}]=${newclist}
#printf -v "config_registry_${config}" %s "${newclist}"
assign_key_value "config_registry" "${config}" "${newclist}"
# Since we performed a substitution and changed the config
# list, mark the iteration flag to continue another round,
# but only if the config (mem) value is NOT present
# in the list of sub-configs. If it is present, then further
# substitution may not necessarily be needed this round.
if [ $(is_in_list "${mem}" "${mems_mem}") == "false" ]; then
iterate_again="1"
fi
fi
done
done
done
# Similar to what we just did for the config_registry, we now iterate
# through the kernel_registry and substitute any configuration families
# in the kernel list (right side of ':') with the members of that
# family's kernel set. This process continues iteratively, as before,
# until all families have been replaced with singleton configurations'
# kernel sets.
iterate_again="1"
while [ "${iterate_again}" == "1" ]; do
iterate_again="0"
#for config in "${!kernel_registry[@]}"; do
for kr_var in ${!kernel_registry_*}; do
config=${kr_var##kernel_registry_}
klist=$(query_array "kernel_registry" ${config})
# The entries that define singleton families should never need
# any substitution. In the kernel registry, we know it's a
# singleton entry when the cname occurs somewhere in the klist.
# (This is slightly different than the same test in the config
# registry, where we test that clist is one word and that
# clist == cname.)
if [ $(is_in_list "${config}" "${klist}") == "true" ]; then
#echo "debug: '${config}' not found in '${klist}'; skipping."
continue
fi
#for ker in ${kernel_registry[$config]}; do
#for ker in ${!kr_var}; do
for ker in ${klist}; do
#kers_ker="${kernel_registry[${ker}]}"
kers_ker=$(query_array "kernel_registry" ${ker})
# If kers_ker is empty string, then ker was not found as a key
# in the kernel registry. While not common, this can happen
# when ker identifies a kernel set that does not correspond to
# any configuration. (Example: armv7a and armv8a kernel sets are
# used by cortexa* configurations, but do not corresond to their
# own configurations.)
if [ "${kers_ker}" == "" ]; then
#echo "debug: ${ker} not found in kernel registry."
continue
fi
# If the current config/kernel (ker) differs from its singleton kernel
# entry (kers_ker), then that singleton entry was specified to use
# a different configuration's kernel set. Thus, we need to replace the
# occurrence in the current config/kernel name with that of the kernel
# set it needs.
if [ "${ker}" != "${kers_ker}" ]; then
#klisttmp="${kernel_registry[$config]}"
klisttmp=$(query_array "kernel_registry" ${config})
# Replace the current config with its requisite kernels,
# canonicalize whitespace, and then remove duplicate kernel
# set names, if they exist. Finally, update the kernel registry
# with the new kernel list.
newklist=$(echo -e "${klisttmp}" | sed -e "s/${ker}/${kers_ker}/g")
newklist=$(canonicalize_ws "${newklist}")
newklist=$(rm_duplicate_words "${newklist}")
#kernel_registry[${config}]=${newklist}
#printf -v "kernel_registry_${config}" %s "${newklist}"
assign_key_value "kernel_registry" "${config}" "${newklist}"
# Since we performed a substitution and changed the kernel
# list, mark the iteration flag to continue another round,
# unless we just substituted using a singleton family
# definition, in which case we don't necessarily need to
# iterate further this round.
if [ $(is_in_list "${ker}" "${kers_ker}") == "false" ]; then
iterate_again="1"
fi
fi
done
done
done
}
build_kconfig_registry()
{
local familyname clist config kernels kernel cur_configs newvalue
familyname="$1"
#clist="${config_registry[${familyname}]}"
clist=$(query_array "config_registry" ${familyname})
for config in ${clist}; do
# Look up the kernels for the current sub-configuration.
#kernels="${kernel_registry[${config}]}"
kernels=$(query_array "kernel_registry" ${config})
for kernel in ${kernels}; do
# Add the sub-configuration to the list associated with the
# kernel.
# Query the current sub-configs for the current ${kernel}.
#cur_configs="${kconfig_registry[${kernel}]}"
cur_configs=$(query_array "kconfig_registry" ${kernel})
# Add the current sub-configuration to the list of sub-configs
# we just queried.
newvalue=$(canonicalize_ws "${cur_configs} ${config}")
# Update the array.
#kconfig_registry[${kernel}]="${newvalue}"
#printf -v "kconfig_registry_${kernel}" %s "${newvalue}"
assign_key_value "kconfig_registry" "${kernel}" "${newvalue}"
done
done
}
is_in_list()
{
local word list rval item
word="$1"
list="$2"
rval="false"
for item in ${list}; do
if [ "${item}" == "${word}" ]; then
rval="true"
break
fi
done
echo "${rval}"
}
is_singleton()
{
local list rval count_str item
list="$1"
rval="false"
count_str=""
for item in ${list}; do
count_str="${count_str}x"
done
if [ "${count_str}" == "x" ]; then
rval="true"
fi
echo "${rval}"
}
is_singleton_family()
{
local familyname memberlist rval
familyname="$1"
memberlist="$2"
rval="false"
if [ $(is_singleton "${memberlist}") ]; then
if [ "${memberlist}" == "${familyname}" ]; then
rval="true"
fi
fi
echo "${rval}"
}
remove_from_list()
{
local strike_list list flist item
strike_words="$1"
list="$2"
flist=""
for item in ${list}; do
# Filter out any list item that matches any of the strike words.
if [ $(is_in_list "${item}" "${strike_words}") == "false" ]; then
flist="${flist} ${item}"
fi
done
flist=$(canonicalize_ws "${flist}")
# Return the filtered list.
echo "${flist}"
}
canonicalize_ws()
{
local str
str="$1"
# Remove leading and trailing whitespace.
str=$(echo -e "${str}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')
# Remove duplicate spaces between words.
str=$(echo -e "${str}" | tr -s " ")
# Update the input argument.
echo "${str}"
}
rm_duplicate_words()
{
local str revstr revres res
str="$1"
# We reverse the initial string, THEN remove duplicates, then reverse
# the de-duplicated result so that only the last instance is kept after
# removing duplicates (rather than keeping only the first). This is
# totally unnecessary but works well for the kinds of duplicates that
# show up in certain use cases of the config and kernel registries.
# For example, these gymnastics allow us to keep only the last instance
# of the 'generic' configuration in a configuration family that
# includes it twice or more.
revstr=$(echo "${str}" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }')
revres=$(echo "${revstr}" | awk '{for (i=1;i<=NF;i++) if (!a[$i]++) printf("%s%s",$i,FS)}{printf("\n")}')
res=$(echo "${revres}" | awk '{ for (i=NF; i>1; i--) printf("%s ",$i); print $1; }')
echo "${res}"
}
select_cc()
{
local se_suf found_cc se_file rval
se_suf="stderr.txt"
# Initialize our selected compiler to empty.
found_cc=""
# If CC was specified on the configure command line, see if it works.
if [ -n "${CC}" ]; then
se_file="cc_${se_suf}"
# See if CC works and/or is present.
rval=$(${CC} --version 2> ${se_file})
if [ -z "$(cat ${se_file})" ]; then
found_cc=${CC}
fi
rm ${se_file}
fi
# Now check if gcc works.
if [ -z "${found_cc}" ]; then
se_file="gcc_${se_suf}"
# See if CC works and/or is present.
rval=$(gcc --version 2> ${se_file})
if [ -z "$(cat ${se_file})" ]; then
found_cc=gcc
fi
rm ${se_file}
fi
# Now check if clang works.
if [ -z "${found_cc}" ]; then
se_file="clang_${se_suf}"
# See if CC works and/or is present.
rval=$(clang --version 2> ${se_file})
if [ -z "$(cat ${se_file})" ]; then
found_cc=clang
fi
rm ${se_file}
fi
# If neither $CC, nor gcc, nor clang work, then we're probably all dead,
# so this fallback selection won't matter.
if [ -z "${found_cc}" ]; then
found_cc=cc
fi
# Return the selected compiler.
echo "${found_cc}"
}
auto_detect()
{
local cc cflags config_defines detected_config rval
# Use the same compiler that was found earlier.
cc="${found_cc}"
# For debugging: reveal what compiler was chosen for auto-detection.
#touch "${cc}.txt"
# Tweak the flags we use based on the compiler. This is mostly just
# an opportunity to turn off annoying warnings that some compilers
# may throw off.
if [ "${cc}" == "clang" ]; then
cflags="-Wno-tautological-compare"
else
cflags=
fi
# Locate our source files.
bli_arch_c="bli_arch.c"
bli_cpuid_c="bli_cpuid.c"
main_c="config_detect.c"
bli_arch_c_filepath=$(find ${dist_path}/frame -name "${bli_arch_c}")
bli_cpuid_c_filepath=$(find ${dist_path}/frame -name "${bli_cpuid_c}")
main_c_filepath=$(find ${dist_path}/build -name "${main_c}")
# Locate headers needed directly by the above files.
bli_arch_h="bli_arch.h"
bli_cpuid_h="bli_cpuid.h"
bli_typed_h="bli_type_defs.h"
bli_arch_h_filepath=$(find ${dist_path}/frame -name "${bli_arch_h}")
bli_cpuid_h_filepath=$(find ${dist_path}/frame -name "${bli_cpuid_h}")
bli_typed_h_filepath=$(find ${dist_path}/frame -name "${bli_typed_h}")
bli_arch_h_path=${bli_arch_h_filepath%/${bli_arch_h}}
bli_cpuid_h_path=${bli_cpuid_h_filepath%/${bli_cpuid_h}}
bli_typed_h_path=${bli_typed_h_filepath%/${bli_typed_h}}
# Locate other headers needed by bli_type_defs.h.
bli_mutex_h="bli_mutex.h"
bli_malloc_h="bli_malloc.h"
bli_mutex_h_filepath=$(find ${dist_path}/frame -name "${bli_mutex_h}")
bli_malloc_h_filepath=$(find ${dist_path}/frame -name "${bli_malloc_h}")
bli_mutex_h_path=${bli_mutex_h_filepath%/${bli_mutex_h}}
bli_malloc_h_path=${bli_malloc_h_filepath%/${bli_malloc_h}}
# Define the executable name.
autodetect_x="auto-detect.x"
# Create #defines for all of the BLIS_CONFIG_ macros in bli_cpuid.c.
config_defines=$(grep BLIS_CONFIG_ ${bli_cpuid_c_filepath} \
| sed -e 's/#ifdef /-D/g')
# Compile the auto-detect program using source code inside the
# framework.
${cc} ${config_defines} \
-DBLIS_CONFIGURETIME_CPUID \
-I${bli_cpuid_h_path} \
-I${bli_arch_h_path} \
-I${bli_typed_h_path} \
-I${bli_mutex_h_path} \
-I${bli_malloc_h_path} \
-std=c99 \
${cflags} \
${bli_arch_c_filepath} \
${bli_cpuid_c_filepath} \
${main_c_filepath} \
-o ${autodetect_x}
# Run the auto-detect program.
detected_config=$(./${autodetect_x})
# Remove the executable file.
rm -f ./${autodetect_x}
# Return the detected sub-configuration name.
echo "${detected_config}"
}
has_libmemkind()
{
local found_cc main_c main_c_filepath LDFLAGS_mk binname rval
found_cc="$1"
# Path to libmemkind detection source file.
main_c="libmemkind_detect.c"
main_c_filepath=$(find ${dist_path}/build -name "${main_c}")
# Add libmemkind to LDFLAGS.
LDFLAGS_mk="${LDFLAGS} -lmemkind"
# Binary executable filename.
binname="libmemkind-detect.x"
# Attempt to compile a simple main() program that contains a call
# to hbw_malloc() and that links to libmemkind.
${found_cc} -o ${binname} ${main_c_filepath} ${LDFLAGS_mk} 2> /dev/null
# Depending on the return code from the compile step above, we set
# enable_memkind accordingly.
if [ "$?" == 0 ]; then
rval='yes'
else
rval='no'
fi
# Remove the executable generated above.
rm -f ./${binname}
echo "${rval}"
}
echoerr()
{
printf "${script_name}: error: %s\n" "$*" #>&2;
}
echowarn()
{
printf "${script_name}: warning: %s\n" "$*" #>&2;
}
blacklistcc_add()
{
# Check whether we've already blacklisted the given sub-config so
# we don't output redundant messages.
if [ $(is_in_list "$1" "${config_blist}") == "false" ]; then
echowarn "${cc_vendor} ${cc_version} does not support '$1'; adding to blacklist."
config_blist="${config_blist} $1"
fi
}
blacklistbu_add()
{
# Check whether we've already blacklisted the given sub-config so
# we don't output redundant messages.
if [ $(is_in_list "$1" "${config_blist}") == "false" ]; then
echowarn "assembler ('as' ${bu_version}) does not support '$1'; adding to blacklist."
config_blist="${config_blist} $1"
fi
}
blacklist_init()
{
config_blist=""
}
blacklist_cleanup()
{
# Remove duplicates and whitespace from the blacklist.
config_blist=$(rm_duplicate_words "${config_blist}")
config_blist=$(canonicalize_ws "${config_blist}")
}
echoerr_unsupportedcc()
{
echoerr "*** Unsupported compiler version: ${cc_vendor} ${cc_version}."
exit 1
}
get_binutils_version()
{
binutil="as"
# Query the full binutils version string output. This includes the
# version string along with (potentially) a bunch of other textual
# clutter.
if [ "$(uname -s)" == "Darwin" ]; then
# The default OS X assembler uses a trifecta of brain-dead
# conventions: responding only to '-v', hanging indefinitely if
# not given an argument, and outputing the result to stderr.
# (And if you still weren't convinced, it creates an 'a.out'
# by default. So yeah.)
bu_string=$(${binutil} -v /dev/null -o /dev/null 2>&1)
else
bu_string=$(${binutil} --version 2>/dev/null)
fi
# Query the binutils version number.
# The last part ({ read first rest ; echo $first ; }) is a workaround
# to OS X's egrep only returning the first match.
bu_version=$(echo "${bu_string}" | egrep -o '[0-9]+\.[0-9]+\.?[0-9]*' | { read first rest ; echo ${first} ; })
# Parse the version number into its major, minor, and revision
# components.
bu_major=$(echo "${bu_version}" | cut -d. -f1)
bu_minor=$(echo "${bu_version}" | cut -d. -f2)
bu_revision=$(echo "${bu_version}" | cut -d. -f3)
echo "${script_name}: found assembler ('as') version ${bu_version} (maj: ${bu_major}, min: ${bu_minor}, rev: ${bu_revision})."
}
get_compiler_version()
{
local cc vendor_string
cc="${found_cc}"
# Query the full vendor version string output. This includes the
# version number along with (potentially) a bunch of other textual
# clutter.
vendor_string="$(${cc} --version 2>/dev/null)"
# Query the compiler "vendor" (ie: the compiler's simple name) and
# isolate the version number.
# The last part ({ read first rest ; echo $first ; }) is a workaround
# to OS X's egrep only returning the first match.
cc_vendor=$(echo "${vendor_string}" | egrep -o 'icc|gcc|clang|emcc|pnacl|IBM' | { read first rest ; echo $first ; })
if [ "$cc_vendor" = "icc" -o "$cc_vendor" = "gcc" -o "$cc_vendor" = "clang" ]
then
cc_version=$(${cc} -dumpversion)
else
cc_version=$(echo "${vendor_string}" | egrep -o '[0-9]+\.[0-9]+\.?[0-9]*' | { read first rest ; echo ${first} ; })
fi
# Parse the version number into its major, minor, and revision
# components.
cc_major=$(echo "${cc_version}" | cut -d. -f1)
cc_minor=$(echo "${cc_version}" | cut -d. -f2)
cc_revision=$(echo "${cc_version}" | cut -d. -f3)
echo "${script_name}: found ${cc} version ${cc_version} (maj: ${cc_major}, min: ${cc_minor}, rev: ${cc_revision})."
}
check_compiler()
{
local cc
cc="${found_cc}"
#
# Compiler requirements
#
# General:
#
# icc 15+, gcc 4.7+, clang 3.3+
#
# Specific:
#
# skx: icc 15.0.1+, gcc 6.0+, clang 3.9+
# knl: icc 14.0.1+, gcc 5.0+, clang 3.5+
# haswell: any
# sandybridge: any
# penryn: any
#
# zen: gcc 6.0+[1], clang 4.0+
# excavator: gcc 4.9+, clang 3.5+
# steamroller: any
# piledriver: any
# bulldozer: any
#
# cortexa57: any
# cortexa15: any
# cortexa9: any
#
# generic: any
#
# Note: These compiler requirements were originally modeled after similar
# requirements encoded into TBLIS's configure.ac [2].
#
# [1] While gcc 6.0 or newer is needed for zen support (-march=znver1),
# we relax this compiler version constraint a bit by targeting bdver4
# and then disabling the instruction sets that were removed in the
# transition from bdver4 to znver1.
# [2] https://github.com/devinamatthews/tblis/
#
echo "${script_name}: checking for blacklisted configurations due to ${cc} ${cc_version}."
# gcc
if [ "x${cc_vendor}" = "xgcc" ]; then
if [ ${cc_major} -lt 4 ]; then
echoerr_unsupportedcc
fi
if [ ${cc_major} -eq 4 ]; then
blacklistcc_add "knl"
if [ ${cc_minor} -lt 7 ]; then
echoerr_unsupportedcc
fi
if [ ${cc_minor} -lt 9 ]; then
blacklistcc_add "excavator"
blacklistcc_add "zen"
fi
fi
if [ ${cc_major} -lt 5 ]; then
blacklistcc_add "knl"
fi
if [ ${cc_major} -lt 6 ]; then
# Normally, zen would be blacklisted for gcc prior to 6.0.
# However, we have a workaround in place in the zen
# configuration's make_defs.mk file that starts with bdver4
# and disables the instructions that were removed in znver1.
# Thus, this "blacklistcc_add" statement has been moved above.
#blacklistcc_add "zen"
blacklistcc_add "skx"
fi
fi
# icc
if [ "x${cc_vendor}" = "xicc" ]; then
if [ ${cc_major} -lt 15 ]; then
echoerr_unsupportedcc
fi
if [ ${cc_major} -eq 15 ]; then
if [ ${cc_revision} -lt 1 ]; then
blacklistcc_add "skx"
fi
fi
fi
# clang
if [ "x${cc_vendor}" = "xclang" ]; then
if [ ${cc_major} -lt 3 ]; then
echoerr_unsupportedcc
fi
if [ ${cc_major} -eq 3 ]; then
if [ ${cc_minor} -lt 3 ]; then
echoerr_unsupportedcc
fi
if [ ${cc_minor} -lt 5 ]; then
blacklistcc_add "excavator"
blacklistcc_add "zen"
blacklistcc_add "knl"
fi
if [ ${cc_minor} -lt 9 ]; then
blacklistcc_add "skx"
fi
fi
if [ ${cc_major} -lt 4 ]; then
# See comment above regarding zen support.
#blacklistcc_add "zen"
: # explicit no-op since bash can't handle empty loop bodies.
fi
fi
}
check_assembler()
{
local cc asm_dir cflags asm_fp
cc="${found_cc}"
# The directory where the assembly files will be.
asm_dir="${dist_path}/build"
# Most of the time, we won't need any additional compiler flags.
cflags=""
echo "${script_name}: checking for blacklisted configurations due to as ${bu_version}."
#
# Check support for FMA4 (amd: bulldozer).
#
asm_fp=$(find ${asm_dir} -name "fma4.s")
knows_fma4=$(try_assemble "${cc}" "${cflags}" "${asm_fp}")
if [ "x${knows_fma4}" == "xno" ]; then
blacklistbu_add "bulldozer"
fi
#
# Check support for AVX (intel: sandybridge+, amd: piledriver+).
#
asm_fp=$(find ${asm_dir} -name "avx.s")
knows_avx=$(try_assemble "${cc}" "${cflags}" "${asm_fp}")
if [ "x${knows_avx}" == "xno" ]; then
blacklistbu_add "sandybridge"
fi
#
# Check support for FMA3 (intel: haswell+, amd: piledriver+).
#
asm_fp=$(find ${asm_dir} -name "fma3.s")
knows_fma3=$(try_assemble "${cc}" "${cflags}" "${asm_fp}")
if [ "x${knows_fma3}" == "xno" ]; then
blacklistbu_add "haswell"
blacklistbu_add "piledriver"
blacklistbu_add "steamroller"
blacklistbu_add "excavator"
blacklistbu_add "skx"
fi
#
# Check support for AVX-512f (knl, skx).
#
# The assembler on OS X won't recognize AVX-512 without help.
if [ "$(uname -s)" == "Darwin" ]; then
cflags="-Wa,-march=knl"
fi
asm_fp=$(find ${asm_dir} -name "avx512f.s")
knows_avx512f=$(try_assemble "${cc}" "${cflags}" "${asm_fp}")
if [ "x${knows_avx512f}" == "xno" ]; then
blacklistbu_add "knl"
blacklistbu_add "skx"
fi
#
# Check support for AVX-512dq (skx).
#
# The assembler on OS X won't recognize AVX-512 without help.
if [ "$(uname -s)" == "Darwin" ]; then
cflags="-Wa,-march=skylake-avx512"
fi
asm_fp=$(find ${asm_dir} -name "avx512dq.s")
knows_avx512dq=$(try_assemble "${cc}" "${cflags}" "${asm_fp}")
if [ "x${knows_avx512dq}" == "xno" ]; then
blacklistbu_add "skx"
fi
}
try_assemble()
{
local cc cflags asm_src asm_base asm_bin rval
cc="$1"
cflags="$2"
asm_src="$3"
# Construct the filename to the .o file corresponding to asm_src.
# (Strip the filepath, then the file extension, and then add ".o".)
asm_base=${asm_src##*/}
asm_base=${asm_base%.*}
asm_bin="${asm_base}.o"
# Try to assemble the file.
${cc} ${cflags} -c ${asm_src} -o ${asm_bin} > /dev/null 2>&1
if [ "$?" == 0 ]; then
rval='yes'
else
rval='no'
fi
# Remove the object file.
rm -f "${asm_bin}"
# Return the result.
echo "${rval}"
}
set_default_version()
{
local gitdir version_file gd_stderr git_describe_str git_error new_version_str
gitdir='.git'
# The path to the version file.
version_file=$1
echo "${script_name}: determining default version string."
# Check if the .git dir exists; if it does not, we do nothing.
if [ -d "${dist_path}/${gitdir}" ]; then
echo "${script_name}: found '${gitdir}' directory; assuming git clone."
echo "${script_name}: executing: git describe --tags."
gd_stderr="git_describe_stderr.txt"
# Query git for the version string, which is simply the current tag,
# followed by a number signifying how many commits have transpired
# since the tag, followed by a 'g' and a shortened hash tab. Capture
# stderr to a file.
git_describe_str=$(git -C ${dist_path} describe --tags 2> ${gd_stderr})
# Pull in whatever error message was generated, if any, and delete
# the file.
git_error=$(cat ${gd_stderr})
# Remove the stderr file.
rm -f ${gd_stderr}
# If git returned an error, don't do anything.
if [ -n "${git_error}" ]; then
echo "${script_name}: git returned an error: '${git_error}'."
echo "${script_name}: using string from unmodified version file."
# Use what's in the version file as-is.
version=$(cat "${version_file}")
else
echo "${script_name}: got back ${git_describe_str}."
# Strip off the commit hash label.
new_version_str=$(echo ${git_describe_str} | cut -d- -f-2)
echo "${script_name}: truncating to ${new_version_str}."
# Write the new version string to the version file.
#echo "${new_version_str}" > ${version_file}
# Set the version variable.
version="${new_version_str}"
fi
else
echo "${script_name}: could not find '${gitdir}' directory; using unmodified version file."
# Use what's in the version file as-is.
version=$(cat "${version_file}")
fi
}
#
# -- main function -------------------------------------------------------------
#
main()
{
#declare -A config_registry
#declare -A kernel_registry
#declare -A kconfig_registry
# The name of the script, stripped of any preceeding path.
script_name=${0##*/}
# The path to the script. We need this to find the top-level directory
# of the source distribution in the event that the user has chosen to
# build elsewhere.
dist_path=${0%/${script_name}}
# The path to the directory in which we are building. We do this to
# make explicit that we distinguish between the top-level directory
# of the distribution and the directory in which we are building.
cur_dirpath="."
# The file in which the version string is kept.
version_file="version"
version_filepath="${dist_path}/${version_file}"
# The name of and path to the directory named "build" in the top-level
# directory of the source distribution.
build_dir='build'
build_dirpath="${dist_path}/${build_dir}"
# The name/path to the registry (master list) of supported configurations.
registry_file="config_registry"
registry_filepath=${dist_path}/${registry_file}
# The names/paths for the template config.mk.in and its instantiated
# counterpart.
config_mk_in='config.mk.in'
config_mk_out='config.mk'
config_mk_in_path="${build_dirpath}/${config_mk_in}"
config_mk_out_path="${cur_dirpath}/${config_mk_out}"
# The names/paths for the template bli_config.h.in and its instantiated
# counterpart.
bli_config_h_in='bli_config.h.in'
bli_config_h_out='bli_config.h'
bli_config_h_in_path="${build_dirpath}/${bli_config_h_in}"
bli_config_h_out_path="${cur_dirpath}/${bli_config_h_out}"
# Path to 'mirror-tree.sh' script.
mirror_tree_sh="${build_dirpath}/mirror-tree.sh"
# Path to 'gen-make-frags.sh' script and directory.
gen_make_frags_dirpath="${build_dirpath}/gen-make-frags"
gen_make_frags_sh="${gen_make_frags_dirpath}/gen-make-frag.sh"
# The name of the (top-level) configuration directory.
config_dir='config'
config_dirpath="${dist_path}/${config_dir}"
# The name of the (top-level) kernels directory.
kernels_dir='kernels'
kernels_dirpath="${dist_path}/${kernels_dir}"
# The name of the (top-level) reference kernels directory.
refkern_dir='ref_kernels'
refkern_dirpath="${dist_path}/${refkern_dir}"
# The root directory of the BLIS framework.
frame_dir='frame'
frame_dirpath="${dist_path}/${frame_dir}"
# The name of the directory in which object files will be kept.
obj_dir='obj'
obj_dirpath="${cur_dirpath}/${obj_dir}"
# The name of the directory in which libraries will be kept.
lib_dir='lib'
lib_dirpath="${cur_dirpath}/${lib_dir}"
# The name of the directory in which headers will be kept.
include_dir='include'
include_dirpath="${cur_dirpath}/${include_dir}"
# The name of the directory in which the BLAS test suite is kept.
blastest_dir='blastest'
# The name of the directory in which the BLIS test suite is kept.
testsuite_dir='testsuite'
# The user-given install prefix and a flag indicating it was given.
#install_prefix_def="${HOME}/blis"
install_prefix_user=${HOME}/blis # default to this directory.
prefix_flag=''
# The user-given install libdir and a flag indicating it was given.
install_libdir_user=''
libdir_flag=''
# The user-given install includedir and a flag indicating it was given.
install_incdir_user=''
incdir_flag=''
# The user-given debug type and a flag indicating it was given.
debug_type=''
debug_flag=''
# The threading flag.
threading_model='no'
# Option variables.
quiet_flag=''
show_config_list=''
# Additional flags.
enable_verbose='no'
enable_static='yes'
enable_shared='no'
enable_packbuf_pools='yes'
int_type_size=0
blas_int_type_size=32
enable_blas='yes'
enable_cblas='no'
enable_memkind='' # The default memkind value is determined later on.
force_version='no'
# Whether we are building out-of-tree.
configured_oot="no"
# The name of the chosen configuration (the configuration "family").
config_name=''
# The list of sub-configurations associated with config_name.
config_list=''
# The list of kernel sets that will be needed by the sub-configurations
# in config_list..
kernel_list=''
# The list of kernel:sub-configuration pairs for all kernels contained
# in kernel_list.
kconfig_map=''
# Dummy file. Used to check whether the cwd is the same as the top-level
# source distribution directory.
dummy_file='_blis_dir_detect.tmp'
# -- Command line option/argument parsing ----------------------------------
# Process our command line options.
while getopts ":hp:d:t:qci:b:-:" opt; do
case $opt in
-)
case "$OPTARG" in
help)
print_usage
;;
quiet)
quiet_flag=1
;;
prefix=*)
prefix_flag=1
install_prefix_user=${OPTARG#*=}
;;
libdir=*)
libdir_flag=1
install_libdir_user=${OPTARG#*=}
;;
includedir=*)
incdir_flag=1
install_incdir_user=${OPTARG#*=}
;;
enable-debug)
debug_flag=1
debug_type=noopt
;;
enable-debug=*)
debug_flag=1
debug_type=${OPTARG#*=}
;;
disable-debug)
debug_flag=0
;;
enable-verbose-make)
enable_verbose='yes'
;;
disable-verbose-make)
enable_verbose='no'
;;
enable-static)
enable_static='yes'
;;
disable-static)
enable_static='no'
;;
enable-shared)
enable_shared='yes'
;;
disable-shared)
enable_shared='no'
;;
enable-threading=*)
threading_model=${OPTARG#*=}
;;
disable-threading)
threading_model='no'
;;
enable-packbuf-pools)
enable_packbuf_pools='yes'
;;
disable-packbuf-pools)
enable_packbuf_pools='no'
;;
int-size=*)
int_type_size=${OPTARG#*=}
;;
blas-int-size=*)
blas_int_type_size=${OPTARG#*=}
;;
enable-blas)
enable_blas='yes'
;;
disable-blas)
enable_blas='no'
;;
enable-cblas)
enable_cblas='yes'
;;
disable-cblas)
enable_cblas='no'
;;
with-memkind)
enable_memkind='yes'
;;
without-memkind)
enable_memkind='no'
;;
force-version=*)
force_version=${OPTARG#*=}
;;
show-config-list)
show_config_list=1
;;
*)
print_usage
;;
esac;;
h)
print_usage
;;
p)
prefix_flag=1
install_prefix=$OPTARG
;;
d)
debug_flag=1
debug_type=$OPTARG
;;
q)
quiet_flag=1
;;
t)
threading_model=$OPTARG
;;
i)
int_type_size=$OPTARG
;;
b)
blas_int_type_size=$OPTARG
;;
c)
show_config_list=1
;;
\?)
print_usage
;;
esac
done
shift $(($OPTIND - 1))
# Parse environment variables
while [ $# -gt 0 ]; do
case $1 in
CC=*)
CC=${1#*=}
shift
;;
RANLIB=*)
RANLIB=${1#*=}
shift
;;
*=*)
print_usage
;;
*)
break
;;
esac
done
# -- Check the compiler version --------------------------------------------
# Find a working C compiler.
found_cc=$(select_cc)
echo "${script_name}: using '${found_cc}' compiler."
# Initialize the blacklist to empty.
blacklist_init
# Check the compiler's version. Certain versions of certain compilers
# will preclude building certain sub-configurations, which are added
# to a blacklist.
get_compiler_version
check_compiler
# Now check the assembler's ability to assemble code. Older versions
# of binutils may not be aware of certain instruction sets. Those
# sub-configurations employing kernels that use such instruction sets
# will also be blacklisted.
get_binutils_version
check_assembler
# Remove duplicates and whitespace from the blacklist.
blacklist_cleanup
if [ -n "${config_blist}" ]; then
echo "${script_name}: configuration blacklist:"
echo "${script_name}: ${config_blist}"
fi
# -- Read the configuration registry ---------------------------------------
# Make sure the config registry file exists and can be opened.
if [ ! -f "${registry_filepath}" ]; then
echo "${script_name}: could not open '${registry_file}' file; cannot continue."
echo "${script_name}: BLIS distribution appears to be incomplete."
exit 1
fi
# Read the registered configuration names and lists into associative
# arrays.
echo -n "${script_name}: reading configuration registry..."
read_registry_file ${registry_filepath}
echo "done."
# Report if additional configurations needed to be blacklisted.
if [ -n "${indirect_blist}" ]; then
echo "${script_name}: needed to indirectly blacklist additional configurations:"
echo "${script_name}: ${indirect_blist}"
fi
# -- Acquire the BLIS version ----------------------------------------------
# Set the 'version' variable to the default value (the 'git describe' augmented
# instance of whatever is in the 'version' file if this is a git clone, or
# whatever is in the 'version' file unmodified if it is a bare source release).
set_default_version "${version_filepath}"
# Initial message.
echo "${script_name}: starting configuration of BLIS ${version}."
# Check if the user requested a custom version string.
if [ "x${force_version}" = "xno" ]; then
echo "${script_name}: configuring with official version string."
else
echo "${script_name}: configuring with custom version string '${force_version}'."
version="${force_version}"
fi
# -- Various pre-configuration checks --------------------------------------
# Set config_name based on the number of arguments leftover (after command
# line option processing).
if [ $# = "0" ]; then
#configs_avail="auto "$(ls ${config_dirpath})
echo "${script_name}: "
echo "${script_name}: *** No configuration given! ***"
echo "${script_name}: "
echo "${script_name}: Default configuration behavior is not implemented (for your"
echo "${script_name}: own safety). Please re-run '${script_name}' and specify one"
echo "${script_name}: of the existing configurations in the source distribution's"
echo "${script_name} '${registry_file}' file:"
echo "${script_name}: "
#for k in "${!config_registry[@]}"; do
for cr_var in ${!config_registry_*}; do
#v=${config_registry[$k]}
k=${cr_var##config_registry_}; v=${!cr_var}
echo "${script_name}: $k (${v})"
done
echo "${script_name}: "
exit 1
elif [ $# != "1" ]; then # more than one configuration argument given.
print_usage
fi
if [ $1 = "auto" ]; then
echo "${script_name}: automatic configuration requested."
# Call the auto_detect() function and save the returned string in
# config_name.
config_name=$(auto_detect)
echo "${script_name}: hardware detection driver returned '${config_name}'."
else
# Use the command line argument as the configuration name.
config_name=$1
#echo "${script_name}: manual configuration requested."
echo "${script_name}: manual configuration requested; configuring with '${config_name}'."
fi
# Use the selected config name to look up the list of configurations
# and kernels associated with that name.
#config_list=${config_registry[${config_name}]}
#kernel_list=${kernel_registry[${config_name}]}
config_list=$(query_array "config_registry" ${config_name})
kernel_list=$(query_array "kernel_registry" ${config_name})
# Use the config_registry and kernel_registry to build a kconfig_registry
# for the selected config_name.
build_kconfig_registry "${config_name}"
# Print the configuration list and kernel list, if requested.
if [ "${show_config_list}" == "1" ]; then
echo "${script_name}: configuration list:"
#for k in "${!config_registry[@]}"; do
for cr_var in ${!config_registry_*}; do
#v=${config_registry[$k]}
k=${cr_var##config_registry_}; v=${!cr_var}
echo "${script_name}: $k: ${v}"
done
echo "${script_name}: kernel list:"
#for k in "${!kernel_registry[@]}"; do
for kr_var in ${!kernel_registry_*}; do
#v=${kernel_registry[$k]}
k=${kr_var##kernel_registry_}; v=${!kr_var}
echo "${script_name}: $k: ${v}"
done
echo "${script_name}: kernel-to-config map for '${config_name}':"
#for k in "${!kconfig_registry[@]}"; do
for kc_var in ${!kconfig_registry_*}; do
#v=${kconfig_registry[$k]}
k=${kc_var##kconfig_registry_}; v=${!kc_var}
echo "${script_name}: $k: ${v}"
done
fi
# For each kernel in the kernel list, reduce the list of associated
# sub-configurations (in the kconfig_registry) to a singleton using
# the following rules:
# 1. If the list is a singleton, use that name.
# 2. If the list contains a sub-configuration name that matches the
# kernel name, use that name.
# 3. Otherwise, use the first name in the list.
# We use the chosen singleton to ceate a "kernel:subconfig" pair, which
# we accumulate into a list. This list is the kernel-to-config map, or
# kconfig_map.
# We use a sorted version of kernel_list so that it ends up matching the
# display order of the kconfig_registry above.
kernel_list_sort=$(echo ${kernel_list} | xargs -n1 | sort -u)
kconfig_map=""
for kernel in ${kernel_list_sort}; do
#configs="${kconfig_registry[$kernel]}"
configs=$(query_array "kconfig_registry" ${kernel})
has_one_kernel=$(is_singleton "${configs}")
contains_kernel=$(is_in_list "${kernel}" "${configs}")
# Check if the list is a singleton.
if [ "${has_one_kernel}" == "true" ]; then
reducedclist="${configs}"
# Check if the list contains a sub-config name that matches the kernel.
elif [ "${contains_kernel}" == "true" ]; then
reducedclist="${kernel}"
# Otherwise, use the first name.
else
first_config=${configs%% *}
reducedclist="${first_config}"
fi
# Create a new "kernel:subconfig" pair and add it to the kconfig_map
# list, removing whitespace.
new_pair="${kernel}:${reducedclist}"
kconfig_map=$(canonicalize_ws "${kconfig_map} ${new_pair}")
done
if [ "${show_config_list}" == "1" ]; then
echo "${script_name}: kernel-to-config map for '${config_name}' (chosen pairs):"
for k in ${kconfig_map}; do
echo "${script_name}: $k"
done
fi
echo "${script_name}: checking configuration against contents of '${registry_file}'."
# First, ensure that the config name is registered (ie: it is present
# in the config_registry file).
if [ -z "${config_list}" ]; then
# NOTE: This branch should never execute when using auto-detection,
# but we have it here just in case.
if [ $1 = "auto" ]; then
echo "${script_name}: 'auto-detected configuration '${conf}' is NOT registered!"
echo "${script_name}: "
echo "${script_name}: *** Cannot continue with unregistered configuration '${conf}'. ***"
echo "${script_name}: "
exit 1;
else
echo "${script_name}: 'user-specified configuration '${conf}' is NOT registered!"
echo "${script_name}: "
echo "${script_name}: *** Cannot continue with unregistered configuration '${conf}'. ***"
echo "${script_name}: "
exit 1;
fi
else
# This branch executes when the configuration is found to be present
# (i.e. registered) in the config_registry file.
echo "${script_name}: configuration '${config_name}' is registered."
echo "${script_name}: '${config_name}' is defined as having the following sub-configurations:"
echo "${script_name}: ${config_list}"
echo "${script_name}: which collectively require the following kernels:"
echo "${script_name}: ${kernel_list}"
fi
echo "${script_name}: checking sub-configurations:"
# Now, verify that the constituent configurations associated with the
# config name are all valid.
for conf in ${config_list}; do
# First confirm that the current configuration is registered.
#this_clist=${config_registry[${conf}]}
this_clist=$(query_array "config_registry" ${conf})
# If the config_list associated with conf is empty, then it was
# never entered into the config_registry to begin with. Thus,
# conf must be unregistered.
if [ -z "${this_clist}" ]; then
echo "${script_name}: '${conf}' is NOT registered!"
echo "${script_name}: "
echo "${script_name}: *** Cannot continue with unregistered configuration '${conf}'. ***"
echo "${script_name}: "
exit 1;
else
echo -n "${script_name}: '${conf}' is registered."
fi
# Then confirm that the current sub-configuration directory exists.
if [ ! -d "${config_dirpath}/${conf}" ]; then
echo "..but does NOT exist!"
echo "${script_name}: "
echo "${script_name}: *** Cannot continue with nonexistent configuration '${conf}'. ***"
echo "${script_name}: "
exit 1;
else
echo "..and exists."
fi
done
echo "${script_name}: checking sub-configurations' requisite kernels:"
# Also, let's verify that the requisite kernel sets associated with
# the config name all correspond to directories that exist.
for kernel in ${kernel_list}; do
echo -n "${script_name}: '${kernel}' kernels..."
# Confirm that the current kernel sub-directory exists.
if [ ! -d "${kernels_dirpath}/${kernel}" ]; then
echo "do NOT exist!"
echo "${script_name}: "
echo "${script_name}: *** Cannot continue with nonexistent kernel '${kernel}'. ***"
echo "${script_name}: "
exit 1;
else
echo "exist."
fi
done
# In order to determine the default behavior of the --with[out]-memkind
# option, we try to detect whether libmemkind is available. If it is,
# the default implied option will be --with-memkind; otherwise, will be
# --without-memkind.
has_memkind=$(has_libmemkind "${found_cc}")
# -- Prepare variables for subsitution into template files -----------------
# Parse the status of the install prefix and echo feedback.
if [ -n "${prefix_flag}" ]; then
echo "${script_name}: detected --prefix='${install_prefix_user}'."
else
echo "${script_name}: no install prefix option given; defaulting to '${install_prefix_user}'."
fi
# Set initial (candidate) values for the libdir and includedir using the
# install prefix that was determined above.
install_libdir=${install_prefix_user}/lib
install_incdir=${install_prefix_user}/include
# Set the install libdir, if it was specified. Note that this will override
# the default libdir implied by the install prefix, even if both options
# were given.
if [ -n "${libdir_flag}" ]; then
echo "${script_name}: detected --libdir='${install_libdir_user}'."
install_libdir=${install_libdir_user}
else
echo "${script_name}: no install libdir option given; defaulting to PREFIX/lib."
fi
# Set the install includedir, if it was specified. Note that this will
# override the default includedir implied by the install prefix, even if
# both options were given.
if [ -n "${incdir_flag}" ]; then
echo "${script_name}: detected --includedir='${install_incdir}'."
install_incdir=${install_incdir_user}
else
echo "${script_name}: no install includedir option given; defaulting to PREFIX/include."
fi
# Echo the installation directories that we settled on.
echo "${script_name}: final installation directories:"
echo "${script_name}: libdir: ${install_libdir}"
echo "${script_name}: includedir: ${install_incdir}"
# Check if the debug flag was specified.
if [ -n "${debug_flag}" ]; then
if [ "x${debug_type}" = "xopt" ]; then
echo "${script_name}: enabling debug symbols with optimizations."
elif [ "x${debug_type}" = "xsde" ]; then
debug_type='sde'
echo "${script_name}: enabling SDE processor emulation."
else
debug_type='noopt'
echo "${script_name}: enabling debug symbols; optimizations disabled."
fi
else
debug_type='off'
echo "${script_name}: debug symbols disabled."
fi
# Check if the verbose make flag was specified.
if [ "x${enable_verbose}" = "xyes" ]; then
echo "${script_name}: enabling verbose make output. (disable with 'make V=0'.)"
else
echo "${script_name}: disabling verbose make output. (enable with 'make V=1'.)"
fi
# Check if the static lib flag was specified.
if [ "x${enable_static}" = "xyes" ]; then
echo "${script_name}: building BLIS as a static library."
fi
# Check if the shared lib flag was specified.
if [ "x${enable_shared}" = "xyes" ]; then
echo "${script_name}: building BLIS as a shared library."
fi
# Check if neither flag was specified.
if [ "x${enable_static}" = "xno" -a "x${enable_shared}" = "xno" ]; then
echo "Neither a shared nor static library build has been requested."
exit 1
fi
# Check the threading model flag and standardize its value, if needed.
# NOTE: 'omp' is deprecated but still supported; 'openmp' is preferred.
enable_openmp='no'
enable_openmp_01=0
enable_pthreads='no'
enable_pthreads_01=0
if [ "x${threading_model}" = "xauto" ]; then
echo "${script_name}: determining the threading model automatically."
elif [ "x${threading_model}" = "xopenmp" ] ||
[ "x${threading_model}" = "xomp" ]; then
echo "${script_name}: using OpenMP for threading."
enable_openmp='yes'
enable_openmp_01=1
threading_model="openmp" # Standardize the value.
elif [ "x${threading_model}" = "xpthreads" ] ||
[ "x${threading_model}" = "xpthread" ] ||
[ "x${threading_model}" = "xposix" ]; then
echo "${script_name}: using Pthreads for threading."
enable_pthreads='yes'
enable_pthreads_01=1
threading_model="pthreads" # Standardize the value.
elif [ "x${threading_model}" = "xno" ] ||
[ "x${threading_model}" = "xnone" ]; then
echo "${script_name}: threading is disabled."
else
echo "Unsupported threading model: ${threading_model}."
exit 1
fi
# Convert 'yes' and 'no' flags to booleans.
if [ "x${enable_packbuf_pools}" = "xyes" ]; then
echo "${script_name}: internal memory pools for packing buffers are enabled."
enable_packbuf_pools_01=1
else
echo "${script_name}: internal memory pools for packing buffers are disabled."
enable_packbuf_pools_01=0
fi
if [ "x${has_memkind}" = "xyes" ]; then
# If no explicit option was given for libmemkind one way or the other,
# default to the value previously returned by has_libmemkind().
if [ "x${enable_memkind}" = "x" ]; then
enable_memkind=${has_memkind}
fi
echo "${script_name}: libmemkind found; default is to enable use."
if [ "x${enable_memkind}" = "xyes" ]; then
echo "${script_name}: received explicit request to enable libmemkind."
enable_memkind_01=1
else
echo "${script_name}: received explicit request to disable libmemkind."
enable_memkind_01=0
fi
else
echo "${script_name}: libmemkind not found; disabling."
if [ "x${enable_memkind}" = "xyes" ]; then
echo "${script_name}: cannot honor explicit request to enable libmemkind."
fi
enable_memkind_01=0
fi
if [ "x${enable_blas}" = "xyes" ]; then
echo "${script_name}: the BLAS compatibility layer is enabled."
enable_blas_01=1
else
echo "${script_name}: the BLAS compatibility layer is disabled."
enable_blas_01=0
fi
if [ "x${enable_cblas}" = "xyes" ]; then
echo "${script_name}: the CBLAS compatibility layer is enabled."
enable_cblas_01=1
# Force BLAS layer when CBLAS is enabled
enable_blas='yes'
else
echo "${script_name}: the CBLAS compatibility layer is disabled."
enable_cblas_01=0
fi
# Report integer sizes
if [ "x${int_type_size}" = "x32" ]; then
echo "${script_name}: the internal integer size is 32-bit."
elif [ "x${int_type_size}" = "x64" ]; then
echo "${script_name}: the internal integer size is 64-bit."
else
echo "${script_name}: the internal integer size is automatically determined."
fi
if [ "x${blas_int_type_size}" = "x32" ]; then
echo "${script_name}: the BLAS/CBLAS interface integer size is 32-bit."
elif [ "x${blas_int_type_size}" = "x64" ]; then
echo "${script_name}: the BLAS/CBLAS interface integer size is 64-bit."
else
echo "${script_name}: the BLAS/CBLAS interface integer size is automatically determined."
fi
# Variables that contain forward slashes, such as paths, need extra
# escaping when used in sed commands. We insert those extra escape
# characters here so that the sed commands below do the right thing.
install_libdir_esc=$(echo "${install_libdir}" | sed 's/\//\\\//g')
install_incdir_esc=$(echo "${install_incdir}" | sed 's/\//\\\//g')
dist_path_esc=$(echo "${dist_path}" | sed 's/\//\\\//g')
cc_esc=$(echo "${CC}" | sed 's/\//\\\//g')
ranlib_esc=$(echo "${RANLIB:-ranlib}" | sed 's/\//\\\//g')
# Create a #define for the configuration family (config_name).
uconf=$(echo ${config_name} | tr '[:lower:]' '[:upper:]')
config_name_define="#define BLIS_FAMILY_${uconf}\n"
# Create a list of #defines, one for each configuration in config_list.
config_list_defines=""
for conf in ${config_list}; do
# Convert the current config name to uppercase.
uconf=$(echo ${conf} | tr '[:lower:]' '[:upper:]')
# Create a #define and add it to the running list.
config_define="BLIS_CONFIG_${uconf}"
config_list_defines="${config_list_defines}#define ${config_define}\n"
done
# Create a list of #defines, one for each kernel set in kernel_list.
kernel_list_defines=""
for kern in ${kernel_list}; do
# Convert the current config name to uppercase.
uconf=$(echo ${kern} | tr '[:lower:]' '[:upper:]')
# Create a #define and add it to the running list.
kernel_define="BLIS_KERNELS_${uconf}"
kernel_list_defines="${kernel_list_defines}#define ${kernel_define}\n"
done
# -- Determine whether we are performing an out-of-tree build --------------
if [ ${dist_path} != "./" ]; then
# At this point, we know the user did not run "./configure". But we
# have not yet ruled out "<fullpath>/configure" or some # equivalent
# that uses relative paths. To further rule out these possibilities,
# we create a dummy file in the current build directory.
touch ./${dummy_file}
# If the dummy file we just created in the current directory does not
# appear in the source distribution path, then we are in a different
# directory and thus we must create a symbolic link.
if [ ! -f "${dist_path}/${dummy_file}" ]; then
configured_oot="yes"
else
configured_oot="no"
fi
# Remove the dummy file.
rm -f "./${dummy_file}"
fi
# -- Instantiate config.mk, bli_config.h files from templates --------------
# Begin substituting information into the config_mk_in file, outputting
# to config_mk_out.
echo "${script_name}: creating ${config_mk_out_path} from ${config_mk_in_path}"
cat "${config_mk_in_path}" \
| sed -e "s/@version@/${version}/g" \
| sed -e "s/@config_name@/${config_name}/g" \
| sed -e "s/@config_list@/${config_list}/g" \
| sed -e "s/@kernel_list@/${kernel_list}/g" \
| sed -e "s/@kconfig_map@/${kconfig_map}/g" \
| sed -e "s/@dist_path@/${dist_path_esc}/g" \
| sed -e "s/@CC@/${cc_esc}/g" \
| sed -e "s/@RANLIB@/${ranlib_esc}/g" \
| sed -e "s/@debug_type@/${debug_type}/g" \
| sed -e "s/@threading_model@/${threading_model}/g" \
| sed -e "s/@install_libdir@/${install_libdir_esc}/g" \
| sed -e "s/@install_incdir@/${install_incdir_esc}/g" \
| sed -e "s/@enable_verbose@/${enable_verbose}/g" \
| sed -e "s/@configured_oot@/${configured_oot}/g" \
| sed -e "s/@enable_static@/${enable_static}/g" \
| sed -e "s/@enable_shared@/${enable_shared}/g" \
| sed -e "s/@enable_blas@/${enable_blas}/g" \
| sed -e "s/@enable_cblas@/${enable_cblas}/g" \
| sed -e "s/@enable_memkind@/${enable_memkind}/g" \
> "${config_mk_out_path}"
# Begin substituting information into the bli_config_h_in file, outputting
# to bli_config_h_out. NOTE: We use perl instead of sed because the version
# of sed used on OS X is old and does not handle the '\n' character
# intuitively, which was used when constructing ${config_name_define},
# ${config_list_defines}, and ${kernel_list_defines}.
echo "${script_name}: creating ${bli_config_h_out_path} from ${bli_config_h_in_path}"
cat "${bli_config_h_in_path}" \
| perl -pe "s/\@config_name_define\@/${config_name_define}/g" \
| perl -pe "s/\@config_list_defines\@/${config_list_defines}/g" \
| perl -pe "s/\@kernel_list_defines\@/${kernel_list_defines}/g" \
| sed -e "s/@enable_openmp@/${enable_openmp_01}/g" \
| sed -e "s/@enable_pthreads@/${enable_pthreads_01}/g" \
| sed -e "s/@enable_packbuf_pools@/${enable_packbuf_pools_01}/g" \
| sed -e "s/@int_type_size@/${int_type_size}/g" \
| sed -e "s/@blas_int_type_size@/${blas_int_type_size}/g" \
| sed -e "s/@enable_blas@/${enable_blas_01}/g" \
| sed -e "s/@enable_cblas@/${enable_cblas_01}/g" \
| sed -e "s/@enable_memkind@/${enable_memkind_01}/g" \
> "${bli_config_h_out_path}"
# -- Create top-level object directories -----------------------------------
# Create obj sub-directories (if they do not already exist).
base_obj_dirpath="${obj_dirpath}/${config_name}"
echo "${script_name}: creating ${base_obj_dirpath}"
mkdir -p ${base_obj_dirpath}
obj_config_dirpath="${base_obj_dirpath}/${config_dir}"
echo "${script_name}: creating ${obj_config_dirpath}"
mkdir -p ${obj_config_dirpath}
for conf in ${config_list}; do
echo "${script_name}: creating ${obj_config_dirpath}/${conf}"
mkdir -p ${obj_config_dirpath}/${conf}
done
obj_kernels_dirpath="${base_obj_dirpath}/${kernels_dir}"
echo "${script_name}: creating ${obj_kernels_dirpath}"
mkdir -p ${obj_kernels_dirpath}
for kern in ${kernel_list}; do
echo "${script_name}: creating ${obj_kernels_dirpath}/${kern}"
mkdir -p ${obj_kernels_dirpath}/${kern}
done
obj_refkern_dirpath="${base_obj_dirpath}/${refkern_dir}"
echo "${script_name}: creating ${obj_refkern_dirpath}"
mkdir -p ${obj_refkern_dirpath}
for conf in ${config_list}; do
echo "${script_name}: creating ${obj_refkern_dirpath}/${conf}"
mkdir -p ${obj_refkern_dirpath}/${conf}
done
obj_frame_dirpath="${base_obj_dirpath}/${frame_dir}"
echo "${script_name}: creating ${obj_frame_dirpath}"
mkdir -p ${obj_frame_dirpath}
obj_blastest_dirpath="${base_obj_dirpath}/${blastest_dir}"
echo "${script_name}: creating ${obj_blastest_dirpath}"
mkdir -p ${obj_blastest_dirpath}
obj_testsuite_dirpath="${base_obj_dirpath}/${testsuite_dir}"
echo "${script_name}: creating ${obj_testsuite_dirpath}"
mkdir -p ${obj_testsuite_dirpath}
# Create lib directory (if it does not already exist).
base_lib_dirpath="${lib_dirpath}/${config_name}"
echo "${script_name}: creating ${base_lib_dirpath}"
mkdir -p ${base_lib_dirpath}
# Create include directory (if it does not already exist).
base_include_dirpath="${include_dirpath}/${config_name}"
echo "${script_name}: creating ${base_include_dirpath}"
mkdir -p ${base_include_dirpath}
# -- Mirror source directory hierarchies to object directories -------------
# Mirror each of the sub-configuration directories to the object directory.
for conf in ${config_list}; do
echo "${script_name}: mirroring ${config_dirpath}/${conf} to ${obj_config_dirpath}/${conf}"
${mirror_tree_sh} "${config_dirpath}/${conf}" "${obj_config_dirpath}/${conf}"
done
# Mirror optimized kernels source tree to its object sub-directory.
# We perform the mirroring on each configuration/kernel sub-directory
# within 'kernels'.
for kern in ${kernel_list}; do
# Only mirror the optimized kernels source directory if it exists.
# There are occasions where one of the sub-configurations in the
# config_list does not correspond to a kernels sub-directory, such
# as when architecture B is so close to architecture A that B can
# use A's kernel source code unmodified (though perhaps with
# different blocksizes).
#if [ -d "${kernels_dirpath}/${conf}" ]; then
echo "${script_name}: mirroring ${kernels_dirpath}/${kern} to ${obj_kernels_dirpath}/${kern}"
${mirror_tree_sh} "${kernels_dirpath}/${kern}" "${obj_kernels_dirpath}/${kern}"
#else
# echo "${script_name}: mirroring ${kernels_dirpath}/${conf} skipped... directory does not exist"
#fi
done
# Mirror reference kernels source tree to its object sub-directory.
for conf in ${config_list}; do
echo "${script_name}: mirroring ${refkern_dirpath} to ${obj_refkern_dirpath}/${conf}"
${mirror_tree_sh} "${refkern_dirpath}" "${obj_refkern_dirpath}/${conf}"
done
# Mirror framework source tree to its object sub-directory.
echo "${script_name}: mirroring ${frame_dirpath} to ${obj_frame_dirpath}"
${mirror_tree_sh} ${frame_dirpath} ${obj_frame_dirpath}
# -- Generate makefile fragements ------------------------------------------
clist_contains_cname=$(is_in_list "${config_name}" "${config_list}")
# If the config_list does not already contain the config_name (i.e.,
# if config_name is an umbrella family), generate makefiles in that
# directory. (In the next step, we will loop over the actual sub-
# configurations and create fragments there as well.)
if [ "${clist_contains_cname}" == "false" ]; then
echo "${script_name}: creating makefile fragments in ${config_dirpath}/${config_name}"
${gen_make_frags_sh} \
-h -r -v0 \
-o ${script_name} \
-p 'CONFIG' \
${config_dirpath}/${config_name} \
${gen_make_frags_dirpath}/fragment.mk \
${gen_make_frags_dirpath}/suffix_list \
${gen_make_frags_dirpath}/ignore_list
fi
# Generate makefile fragments for each of the sub-configurations present
# in the configuration list.
for conf in ${config_list}; do
echo "${script_name}: creating makefile fragments in ${config_dirpath}/${conf}"
${gen_make_frags_sh} \
-h -r -v0 \
-o ${script_name} \
-p 'CONFIG' \
${config_dirpath}/${conf} \
${gen_make_frags_dirpath}/fragment.mk \
${gen_make_frags_dirpath}/suffix_list \
${gen_make_frags_dirpath}/ignore_list
done
# Generate makefile fragments for each of the kernel sets required by
# the configuration list (in the kernel list).
for kern in ${kernel_list}; do
echo "${script_name}: creating makefile fragments in ${kernels_dirpath}/${kern}"
${gen_make_frags_sh} \
-h -r -v0 \
-o ${script_name} \
-p 'KERNELS' \
${kernels_dirpath}/${kern} \
${gen_make_frags_dirpath}/fragment.mk \
${gen_make_frags_dirpath}/suffix_list \
${gen_make_frags_dirpath}/ignore_list
done
# Generate makefile fragments in the reference kernels directory.
echo "${script_name}: creating makefile fragments in ${refkern_dirpath}"
${gen_make_frags_sh} \
-h -r -v0 \
-o ${script_name} \
-p 'REFKERN' \
${refkern_dirpath} \
${gen_make_frags_dirpath}/fragment.mk \
${gen_make_frags_dirpath}/suffix_list \
${gen_make_frags_dirpath}/ignore_list
# Generate makefile fragments in the framework directory.
echo "${script_name}: creating makefile fragments in ${frame_dirpath}"
${gen_make_frags_sh} \
-h -r -v0 \
-o ${script_name} \
-p 'FRAME' \
${frame_dirpath} \
${gen_make_frags_dirpath}/fragment.mk \
${gen_make_frags_dirpath}/suffix_list \
${gen_make_frags_dirpath}/ignore_list
# -- Handle out-of-tree builds ---------------------------------------------
# Under some circumstances, we need to create some symbolic links to
# properly handle out-of-tree builds.
if [ "${configured_oot}" = "yes" ]; then
# If 'Makefile' does not already exist in the current directory,
# create a symbolic link to it. If one does exist, we us -f to
# force creation of a new link.
if [ ! -e "./Makefile" ]; then
echo "${script_name}: creating symbolic link to Makefile."
ln -s "${dist_path}/Makefile"
else
echo "${script_name}: symbolic link to Makefile already exists; forcing creation of new link."
ln -sf "${dist_path}/Makefile"
fi
# If 'common.mk' does not already exist in the current directory,
# create a symbolic link to it. If one does exist, we us -f to
# force creation of a new link.
if [ ! -e "./common.mk" ]; then
echo "${script_name}: creating symbolic link to common.mk."
ln -s "${dist_path}/common.mk"
else
echo "${script_name}: symbolic link to common.mk already exists; forcing creation of new link."
ln -sf "${dist_path}/common.mk"
fi
echo "${script_name}: configured to build outside of source distribution."
else
echo "${script_name}: configured to build within top-level directory of source distribution."
fi
# Exit peacefully.
return 0
}
# The script's main entry point, passing all parameters given.
main "$@"