# # # 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. # # # # Makefile # # Field G. Van Zee # # Top-level makefile for libflame linear algebra library. # # # # --- Makefile PHONY target definitions ---------------------------------------- # .PHONY: all \ libs libblis \ check-env check-env-mk check-env-fragments check-env-make-defs \ flat-header flat-cblas-header \ test \ testblas blastest-f2c blastest-bin blastest-run \ testblis testsuite testsuite-bin testsuite-run \ testblis-fast testsuite-run-fast \ check checkblas checkblis checkblis-fast \ install-headers install-libs install-lib-symlinks \ showconfig \ clean cleanmk cleanh cleanlib distclean \ cleantest cleanblastest cleanblistest \ changelog \ install uninstall uninstall-old \ uninstall-libs uninstall-lib-symlinks uninstall-headers \ uninstall-old-libs uninstall-lib-symlinks uninstall-old-headers # # --- Include common makefile definitions -------------------------------------- # # Define the name of the common makefile. COMMON_MK_FILE := common.mk # Construct the path to the makefile configuration file that was generated by # the configure script. COMMON_MK_PATH := $(COMMON_MK_FILE) # Include the configuration file. -include $(COMMON_MK_FILE) # Detect whether we actually got the configuration file. If we didn't, then # it is likely that the user has not yet generated it (via configure). ifeq ($(strip $(COMMON_MK_INCLUDED)),yes) COMMON_MK_PRESENT := yes else COMMON_MK_PRESENT := no endif # # --- Main target variable definitions ----------------------------------------- # # --- Object file paths --- # Construct the base object file path for the current configuration. BASE_OBJ_PATH := ./$(OBJ_DIR)/$(CONFIG_NAME) # Construct base object file paths corresponding to the four locations # of source code. BASE_OBJ_CONFIG_PATH := $(BASE_OBJ_PATH)/$(CONFIG_DIR) BASE_OBJ_FRAME_PATH := $(BASE_OBJ_PATH)/$(FRAME_DIR) BASE_OBJ_REFKERN_PATH := $(BASE_OBJ_PATH)/$(REFKERN_DIR) BASE_OBJ_KERNELS_PATH := $(BASE_OBJ_PATH)/$(KERNELS_DIR) BASE_OBJ_SANDBOX_PATH := $(BASE_OBJ_PATH)/$(SANDBOX_DIR) # --- Define install target names for static libraries --- LIBBLIS_A_VERS_CONF_INST := $(INSTALL_LIBDIR)/$(LIBBLIS)-$(VERS_CONF).a LIBBLIS_A_INST := $(INSTALL_LIBDIR)/$(LIBBLIS_A) # --- Define install target names for shared libraries --- LIBBLIS_SO_VERS_CONF_INST := $(INSTALL_LIBDIR)/$(LIBBLIS)-$(VERS_CONF).$(SHLIB_EXT) LIBBLIS_SO_INST := $(INSTALL_LIBDIR)/$(LIBBLIS_SO) LIBBLIS_SO_MAJ_INST := $(INSTALL_LIBDIR)/$(LIBBLIS_SO).$(SO_MAJOR) LIBBLIS_SO_MMB_INST := $(INSTALL_LIBDIR)/$(LIBBLIS_SO).$(SO_MAJOR).$(SO_MINORB) # --- Determine which libraries to build --- MK_LIBS := MK_LIBS_INST := MK_LIBS_SYML := ifeq ($(MK_ENABLE_STATIC),yes) MK_LIBS += $(LIBBLIS_A_PATH) MK_LIBS_INST += $(LIBBLIS_A_INST) MK_LIBS_SYML += endif ifeq ($(MK_ENABLE_SHARED),yes) MK_LIBS += $(LIBBLIS_SO_PATH) MK_LIBS_INST += $(LIBBLIS_SO_MMB_INST) MK_LIBS_SYML += $(LIBBLIS_SO_INST) \ $(LIBBLIS_SO_MAJ_INST) endif # Strip leading, internal, and trailing whitespace. MK_LIBS_INST := $(strip $(MK_LIBS_INST)) MK_LIBS_SYML := $(strip $(MK_LIBS_SYML)) # --- Define install directory for headers --- # Set the include installation directory subdirectory name. MK_INCL_DIR_INST := $(INSTALL_INCDIR)/blis # # --- Library object definitions ----------------------------------------------- # # In this section, we will isolate the relevant source code filepaths and # convert them to lists of object filepaths. Relevant source code falls into # four categories: configuration source; architecture-specific kernel source; # reference kernel source; and general framework source. # $(call gen-obj-paths-from-src file_exts, src_files, base_src_path, base_obj_path) gen-obj-paths-from-src = $(foreach ch, $(1), \ $(patsubst $(3)/%.$(ch), \ $(4)/%.o, \ $(filter %.$(ch), $(2)) ) ) # Generate object file paths for source code found in the sub-configuration # directories. MK_CONFIG_OBJS := $(call gen-obj-paths-from-src,$(CONFIG_SRC_SUFS),$(MK_CONFIG_SRC),$(CONFIG_PATH),$(BASE_OBJ_CONFIG_PATH)) # Generate object file paths for architecture-specific kernel source code. # We target only .c, .s, and .S files. Note that MK_KERNELS_SRC is already # limited to the kernel source corresponding to the kernel sets in # KERNEL_LIST. This is because the configure script only propogated makefile # fragments into those specific kernel subdirectories. MK_KERNELS_OBJS := $(call gen-obj-paths-from-src,$(KERNELS_SRC_SUFS),$(MK_KERNELS_SRC),$(KERNELS_PATH),$(BASE_OBJ_KERNELS_PATH)) # Generate object file paths for reference kernels, with one set of object # files for each sub-configuration in CONFIG_LIST. Note that due to the # nuances of naming the reference kernel files, we can't use the function # gen-obj-paths-from-src as we do above and below. MK_REFKERN_C := $(filter %.c, $(MK_REFKERN_SRC)) MK_REFKERN_OBJS := $(foreach arch, $(CONFIG_LIST), \ $(patsubst $(REFKERN_PATH)/%_$(REFNM).c, \ $(BASE_OBJ_REFKERN_PATH)/$(arch)/%_$(arch)_$(REFNM).o, \ $(MK_REFKERN_C) \ ) \ ) # Generate object file paths for all of the portable framework source code. MK_FRAME_OBJS := $(call gen-obj-paths-from-src,$(FRAME_SRC_SUFS),$(MK_FRAME_SRC),$(FRAME_PATH),$(BASE_OBJ_FRAME_PATH)) # Generate object file paths for the sandbox source code. If a sandbox was not # enabled a configure-time, this variable will we empty. MK_SANDBOX_OBJS := $(call gen-obj-paths-from-src,$(SANDBOX_SRC_SUFS),$(MK_SANDBOX_SRC),$(SANDBOX_PATH),$(BASE_OBJ_SANDBOX_PATH)) # Combine all of the object files into some readily-accessible variables. MK_BLIS_OBJS := $(MK_CONFIG_OBJS) \ $(MK_KERNELS_OBJS) \ $(MK_REFKERN_OBJS) \ $(MK_FRAME_OBJS) \ $(MK_SANDBOX_OBJS) # Optionally filter out the BLAS and CBLAS compatibility layer object files. # This is not actually necessary, since each affected file is guarded by C # preprocessor macros, but it but prevents "empty" object files from being # added into the library (and reduces compilation time). BASE_OBJ_BLAS_PATH := $(BASE_OBJ_FRAME_PATH)/compat BASE_OBJ_CBLAS_PATH := $(BASE_OBJ_FRAME_PATH)/compat/cblas ifeq ($(MK_ENABLE_CBLAS),no) MK_BLIS_OBJS := $(filter-out $(BASE_OBJ_CBLAS_PATH)/%.o, $(MK_BLIS_OBJS) ) endif ifeq ($(MK_ENABLE_BLAS),no) MK_BLIS_OBJS := $(filter-out $(BASE_OBJ_BLAS_PATH)/%.o, $(MK_BLIS_OBJS) ) endif # # --- Monolithic header definitions -------------------------------------------- # # Define a list of headers to install. The default is to only install blis.h. HEADERS_TO_INSTALL := $(BLIS_H_FLAT) # If CBLAS is enabled, we also install cblas.h so the user does not need to # change their source code to #include "blis.h" in order to access the CBLAS # function prototypes and enums. ifeq ($(MK_ENABLE_CBLAS),yes) HEADERS_TO_INSTALL += $(CBLAS_H_FLAT) endif # # --- BLAS test drivers definitions -------------------------------------------- # # The location of the BLAS test suite's input files. BLASTEST_INPUT_PATH := $(DIST_PATH)/$(BLASTEST_DIR)/input # The location of the BLAS test suite object directory. BASE_OBJ_BLASTEST_PATH := $(BASE_OBJ_PATH)/$(BLASTEST_DIR) # The locations of the BLAS test suite source code (f2c and drivers). BLASTEST_F2C_SRC_PATH := $(DIST_PATH)/$(BLASTEST_DIR)/f2c BLASTEST_DRV_SRC_PATH := $(DIST_PATH)/$(BLASTEST_DIR)/src # The paths to object files we will create (f2c and drivers). BLASTEST_F2C_OBJS := $(sort \ $(patsubst $(BLASTEST_F2C_SRC_PATH)/%.c, \ $(BASE_OBJ_BLASTEST_PATH)/%.o, \ $(wildcard $(BLASTEST_F2C_SRC_PATH)/*.c)) \ ) BLASTEST_DRV_OBJS := $(sort \ $(patsubst $(BLASTEST_DRV_SRC_PATH)/%.c, \ $(BASE_OBJ_BLASTEST_PATH)/%.o, \ $(wildcard $(BLASTEST_DRV_SRC_PATH)/*.c)) \ ) # libf2c name and location. BLASTEST_F2C_LIB_NAME := libf2c.a BLASTEST_F2C_LIB := $(BASE_OBJ_BLASTEST_PATH)/$(BLASTEST_F2C_LIB_NAME) # The base names of each driver source file (ie: filename minus suffix). BLASTEST_DRV_BASES := $(basename $(notdir $(BLASTEST_DRV_OBJS))) # The binary executable driver names. BLASTEST_DRV_BINS := $(addsuffix .x,$(BLASTEST_DRV_BASES)) BLASTEST_DRV_BIN_PATHS := $(addprefix $(BASE_OBJ_BLASTEST_PATH)/,$(BLASTEST_DRV_BINS)) # Binary executable driver "run-" names BLASTEST_DRV_BINS_R := $(addprefix run-,$(BLASTEST_DRV_BASES)) # Filter level-1, level-2, and level-3 names to different variables. BLASTEST_DRV1_BASES := $(filter %1,$(BLASTEST_DRV_BASES)) BLASTEST_DRV2_BASES := $(filter %2,$(BLASTEST_DRV_BASES)) BLASTEST_DRV3_BASES := $(filter %3,$(BLASTEST_DRV_BASES)) # Define some CFLAGS that we'll only use when compiling BLAS test suite # files. BLAT_CFLAGS := -Wno-maybe-uninitialized -Wno-parentheses \ -I$(BLASTEST_F2C_SRC_PATH) \ -I. -DHAVE_BLIS_H # The location of the script that checks the BLAS test output. BLASTEST_CHECK := $(DIST_PATH)/$(BUILD_DIR)/check-blastest.sh # # --- BLIS testsuite definitions ----------------------------------------------- # # The location of the test suite's general and operations-specific # input/configuration files. TESTSUITE_CONF_GEN_PATH := $(DIST_PATH)/$(TESTSUITE_DIR)/$(TESTSUITE_CONF_GEN) TESTSUITE_CONF_OPS_PATH := $(DIST_PATH)/$(TESTSUITE_DIR)/$(TESTSUITE_CONF_OPS) TESTSUITE_FAST_GEN_PATH := $(DIST_PATH)/$(TESTSUITE_DIR)/$(TESTSUITE_FAST_GEN) TESTSUITE_FAST_OPS_PATH := $(DIST_PATH)/$(TESTSUITE_DIR)/$(TESTSUITE_FAST_OPS) # The locations of the test suite source directory and the local object # directory. TESTSUITE_SRC_PATH := $(DIST_PATH)/$(TESTSUITE_DIR)/src BASE_OBJ_TESTSUITE_PATH := $(BASE_OBJ_PATH)/$(TESTSUITE_DIR) # Convert source file paths to object file paths by replacing the base source # directories with the base object directories, and also replacing the source # file suffix (eg: '.c') with '.o'. MK_TESTSUITE_OBJS := $(sort \ $(patsubst $(TESTSUITE_SRC_PATH)/%.c, \ $(BASE_OBJ_TESTSUITE_PATH)/%.o, \ $(wildcard $(TESTSUITE_SRC_PATH)/*.c)) \ ) # The test suite binary executable filename. TESTSUITE_BIN := test_$(LIBBLIS).x # The location of the script that checks the BLIS testsuite output. TESTSUITE_CHECK := $(DIST_PATH)/$(BUILD_DIR)/check-blistest.sh # # --- Uninstall definitions ---------------------------------------------------- # ifeq ($(IS_CONFIGURED),yes) # These shell commands gather the filepaths to any library in the current # LIBDIR that might be left over from an old installation. We start with # including nothing for static libraries, since older static libraries are # always overwritten by newer ones. Then we add shared libraries, which are # named with three .so version numbers. UNINSTALL_OLD_LIBS := UNINSTALL_OLD_LIBS += $(shell $(FIND) $(INSTALL_LIBDIR)/ -name "$(LIBBLIS_SO).?.?.?" 2> /dev/null | $(GREP) -v "$(LIBBLIS_SO).$(SO_MMB)") # These shell commands gather the filepaths to any library symlink in the # current LIBDIR that might be left over from an old installation. We start # with symlinks named using the .so major version number. UNINSTALL_OLD_SYML := $(shell $(FIND) $(INSTALL_LIBDIR)/ -name "$(LIBBLIS_SO).?" 2> /dev/null | $(GREP) -v "$(LIBBLIS_SO).$(SO_MAJOR)") # We also prepare to uninstall older-style symlinks whose names contain the # BLIS version number and configuration family. UNINSTALL_OLD_SYML += $(shell $(FIND) $(INSTALL_LIBDIR)/ -name "$(LIBBLIS)-*.a" 2> /dev/null | $(GREP) -v "$(LIBBLIS)-$(VERS_CONF).a") UNINSTALL_OLD_SYML += $(shell $(FIND) $(INSTALL_LIBDIR)/ -name "$(LIBBLIS)-*.$(SHLIB_EXT)" 2> /dev/null | $(GREP) -v "$(LIBBLIS)-$(VERS_CONF).$(SHLIB_EXT)") # This shell command grabs all files named "*.h" that are not blis.h or cblas.h # in the installation directory. We consider this set of headers to be "old" and # eligible for removal upon running of the uninstall-old-headers target. UNINSTALL_OLD_HEADERS := $(shell $(FIND) $(INSTALL_INCDIR)/blis/ -name "*.h" 2> /dev/null | $(GREP) -v "$(BLIS_H)" | $(GREP) -v "$(CBLAS_H)") endif # IS_CONFIGURED # # --- Targets/rules ------------------------------------------------------------ # # --- Primary targets --- all: libs libs: libblis test: testblis testblas check: checkblis-fast checkblas install: libs install-libs install-lib-symlinks install-headers uninstall: uninstall-libs uninstall-lib-symlinks uninstall-headers uninstall-old: uninstall-old-libs uninstall-old-symlinks uninstall-old-headers clean: cleanh cleanlib # --- Environment check rules --- check-env: check-env-make-defs check-env-fragments check-env-mk check-env-mk: ifeq ($(CONFIG_MK_PRESENT),no) $(error Cannot proceed: config.mk not detected! Run configure first) endif check-env-fragments: check-env-mk ifeq ($(MAKEFILE_FRAGMENTS_PRESENT),no) $(error Cannot proceed: makefile fragments not detected! Run configure first) endif check-env-make-defs: check-env-fragments ifeq ($(ALL_MAKE_DEFS_MK_PRESENT),no) $(error Cannot proceed: Some make_defs.mk files not found or mislabeled!) endif # --- Consolidated blis.h header creation --- flat-header: check-env $(BLIS_H_FLAT) $(BLIS_H_FLAT): $(FRAME_H99_FILES) ifeq ($(ENABLE_VERBOSE),yes) $(FLATTEN_H) -c -v1 $(BLIS_H_SRC_PATH) $@ "./$(INCLUDE_DIR)" "$(ALL_H99_DIRPATHS)" else @echo -n "Generating monolithic blis.h" @$(FLATTEN_H) -c -v1 $(BLIS_H_SRC_PATH) $@ "./$(INCLUDE_DIR)" "$(ALL_H99_DIRPATHS)" @echo "Generated $@" endif # --- Consolidated cblas.h header creation --- flat-cblas-header: check-env $(CBLAS_H_FLAT) $(CBLAS_H_FLAT): $(FRAME_H99_FILES) ifeq ($(ENABLE_VERBOSE),yes) $(FLATTEN_H) -c -v1 $(CBLAS_H_SRC_PATH) $@ "./$(INCLUDE_DIR)" "$(ALL_H99_DIRPATHS)" else @echo -n "Generating monolithic cblas.h" @$(FLATTEN_H) -c -v1 $(CBLAS_H_SRC_PATH) $@ "./$(INCLUDE_DIR)" "$(ALL_H99_DIRPATHS)" @echo "Generated $@" endif # --- General source code / object code rules --- # FGVZ: Add support for compiling .s and .S files in 'config'/'kernels' # directories. # - May want to add an extra foreach loop around function eval/call. # first argument: a configuration name from config_list, used to look up the # CFLAGS to use during compilation. define make-config-rule $(BASE_OBJ_CONFIG_PATH)/$(1)/%.o: $(CONFIG_PATH)/$(1)/%.c $(BLIS_H_FLAT) $(MAKE_DEFS_MK_PATHS) ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(call get-config-cflags-for,$(1)) -c $$< -o $$@ else @echo "Compiling $$@" $(call get-config-text-for,$(1)) @$(CC) $(call get-config-cflags-for,$(1)) -c $$< -o $$@ endif endef # first argument: a configuration name from the union of config_list and # config_name, used to look up the CFLAGS to use during compilation. define make-frame-rule $(BASE_OBJ_FRAME_PATH)/%.o: $(FRAME_PATH)/%.c $(BLIS_H_FLAT) $(MAKE_DEFS_MK_PATHS) ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(call get-frame-cflags-for,$(1)) -c $$< -o $$@ else @echo "Compiling $$@" $(call get-frame-text-for,$(1)) @$(CC) $(call get-frame-cflags-for,$(1)) -c $$< -o $$@ endif endef # first argument: a kernel set (name) being targeted (e.g. haswell). define make-refinit-rule $(BASE_OBJ_REFKERN_PATH)/$(1)/bli_cntx_$(1)_ref.o: $(REFKERN_PATH)/bli_cntx_ref.c $(BLIS_H_FLAT) $(MAKE_DEFS_MK_PATHS) ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(call get-refinit-cflags-for,$(1)) -c $$< -o $$@ else @echo "Compiling $$@" $(call get-refinit-text-for,$(1)) @$(CC) $(call get-refinit-cflags-for,$(1)) -c $$< -o $$@ endif endef # first argument: a kernel set (name) being targeted (e.g. haswell). define make-refkern-rule $(BASE_OBJ_REFKERN_PATH)/$(1)/%_$(1)_ref.o: $(REFKERN_PATH)/%_ref.c $(BLIS_H_FLAT) $(MAKE_DEFS_MK_PATHS) ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(call get-refkern-cflags-for,$(1)) -c $$< -o $$@ else @echo "Compiling $$@" $(call get-refkern-text-for,$(1)) @$(CC) $(call get-refkern-cflags-for,$(1)) -c $$< -o $$@ endif endef # first argument: a kernel set (name) being targeted (e.g. haswell). # second argument: the configuration whose CFLAGS we should use in compilation. # third argument: the kernel file suffix being considered. define make-kernels-rule $(BASE_OBJ_KERNELS_PATH)/$(1)/%.o: $(KERNELS_PATH)/$(1)/%.$(3) $(BLIS_H_FLAT) $(MAKE_DEFS_MK_PATHS) ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(call get-kernel-cflags-for,$(2)) -c $$< -o $$@ else @echo "Compiling $$@" $(call get-kernel-text-for,$(2)) @$(CC) $(call get-kernel-cflags-for,$(2)) -c $$< -o $$@ endif endef # first argument: a configuration name from the union of config_list and # config_name, used to look up the CFLAGS to use during compilation. define make-c99-sandbox-rule $(BASE_OBJ_SANDBOX_PATH)/%.o: $(SANDBOX_PATH)/%.$(2) $(BLIS_H_FLAT) $(SANDBOX_H99_FILES) $(MAKE_DEFS_MK_PATHS) ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(call get-sandbox-c99flags-for,$(1)) -c $$< -o $$@ else @echo "Compiling $$@" $(call get-sandbox-c99text-for,$(1)) @$(CC) $(call get-sandbox-c99flags-for,$(1)) -c $$< -o $$@ endif endef define make-cxx-sandbox-rule $(BASE_OBJ_SANDBOX_PATH)/%.o: $(SANDBOX_PATH)/%.$(2) $(BLIS_H_FLAT) $(SANDBOX_HXX_FILES) $(MAKE_DEFS_MK_PATHS) ifeq ($(ENABLE_VERBOSE),yes) $(CXX) $(call get-sandbox-cxxflags-for,$(1)) -c $$< -o $$@ else @echo "Compiling $$@" $(call get-sandbox-cxxtext-for,$(1)) @$(CXX) $(call get-sandbox-cxxflags-for,$(1)) -c $$< -o $$@ endif endef # Define functions to choose the correct sub-configuration name for the # given kernel set. This function is called when instantiating the # make-kernels-rule. get-config-for-kset = $(lastword $(subst :, ,$(filter $(1):%,$(KCONFIG_MAP)))) # Instantiate the build rule for files in the configuration directory for # each of the sub-configurations in CONFIG_LIST with the CFLAGS designated # for that sub-configuration. $(foreach conf, $(CONFIG_LIST), $(eval $(call make-config-rule,$(conf)))) # Instantiate the build rule for framework files. Use the CFLAGS for the # configuration family, which exists in the directory whose name is equal to # CONFIG_NAME. Note that this doesn't need to be in a loop since we expect # CONFIG_NAME to only ever contain a single name. (BTW: If CONFIG_NAME refers # to a singleton family, then CONFIG_LIST contains CONFIG_NAME as its only # item.) $(foreach conf, $(CONFIG_NAME), $(eval $(call make-frame-rule,$(conf)))) # Instantiate the build rule for reference kernel initialization and # reference kernels for each of the sub-configurations in CONFIG_LIST with # the CFLAGS designated for that sub-configuration. $(foreach conf, $(CONFIG_LIST), $(eval $(call make-refinit-rule,$(conf)))) $(foreach conf, $(CONFIG_LIST), $(eval $(call make-refkern-rule,$(conf)))) # Instantiate the build rule for optimized kernels for each of the kernel # sets in KERNEL_LIST with the CFLAGS designated for the sub-configuration # specified by the KCONFIG_MAP. $(foreach suf, $(KERNELS_SRC_SUFS), \ $(foreach kset, $(KERNEL_LIST), $(eval $(call make-kernels-rule,$(kset),$(call get-config-for-kset,$(kset)),$(suf))))) # Instantiate the build rule for C sandbox files. Use the CFLAGS for the # configuration family. $(foreach suf, $(SANDBOX_C99_SUFS), \ $(foreach conf, $(CONFIG_NAME), $(eval $(call make-c99-sandbox-rule,$(conf),$(suf))))) # Instantiate the build rule for C++ sandbox files. Use the CXXFLAGS for the # configuration family. $(foreach suf, $(SANDBOX_CXX_SUFS), \ $(foreach conf, $(CONFIG_NAME), $(eval $(call make-cxx-sandbox-rule,$(conf),$(suf))))) # --- All-purpose library rule (static and shared) --- libblis: check-env $(MK_LIBS) # --- Static library archiver rules --- $(LIBBLIS_A_PATH): $(MK_BLIS_OBJS) ifeq ($(ENABLE_VERBOSE),yes) ifeq ($(ARG_MAX_HACK),yes) $(file > $@.in,$^) $(AR) $(ARFLAGS) $@ @$@.in $(RM_F) $@.in $(RANLIB) $@ else $(AR) $(ARFLAGS) $@ $? $(RANLIB) $@ endif else # ifeq ($(ENABLE_VERBOSE),no) ifeq ($(ARG_MAX_HACK),yes) @echo "Archiving $@" @$(file > $@.in,$^) @$(AR) $(ARFLAGS) $@ @$@.in @$(RM_F) $@.in @$(RANLIB) $@ else @echo "Archiving $@" @$(AR) $(ARFLAGS) $@ $? @$(RANLIB) $@ endif endif # --- Dynamic library linker rules --- $(LIBBLIS_SO_PATH): $(MK_BLIS_OBJS) ifeq ($(ENABLE_VERBOSE),yes) ifeq ($(ARG_MAX_HACK),yes) $(file > $@.in,$^) $(LINKER) $(SOFLAGS) $(LDFLAGS) -o $@ @$@.in $(RM_F) $@.in else $(LINKER) $(SOFLAGS) $(LDFLAGS) -o $@ $? endif else # ifeq ($(ENABLE_VERBOSE),no) ifeq ($(ARG_MAX_HACK),yes) @echo "Dynamically linking $@" @$(file > $@.in,$^) @$(LINKER) $(SOFLAGS) $(LDFLAGS) -o $@ @$@.in @$(RM_F) $@.in else @echo "Dynamically linking $@" @$(LINKER) $(SOFLAGS) $(LDFLAGS) -o $@ $? endif endif # --- BLAS test suite rules --- testblas: blastest-run blastest-f2c: check-env $(BLASTEST_F2C_LIB) blastest-bin: check-env blastest-f2c $(BLASTEST_DRV_BIN_PATHS) blastest-run: $(BLASTEST_DRV_BINS_R) # f2c object file rule. $(BASE_OBJ_BLASTEST_PATH)/%.o: $(BLASTEST_F2C_SRC_PATH)/%.c ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(CFLAGS) $(BLAT_CFLAGS) -c $< -o $@ else @echo "Compiling $@" @$(CC) $(CFLAGS) $(BLAT_CFLAGS) -c $< -o $@ endif # driver object file rule. $(BASE_OBJ_BLASTEST_PATH)/%.o: $(BLASTEST_DRV_SRC_PATH)/%.c ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(CFLAGS) $(BLAT_CFLAGS) -c $< -o $@ else @echo "Compiling $@" @$(CC) $(CFLAGS) $(BLAT_CFLAGS) -c $< -o $@ endif # libf2c library archive rule. $(BLASTEST_F2C_LIB): $(BLASTEST_F2C_OBJS) ifeq ($(ENABLE_VERBOSE),yes) $(AR) $(ARFLAGS) $@ $? $(RANLIB) $@ else @echo "Archiving $@" @$(AR) $(ARFLAGS) $@ $? @$(RANLIB) $@ endif # first argument: the base name of the BLAS test driver. define make-blat-rule $(BASE_OBJ_BLASTEST_PATH)/$(1).x: $(BASE_OBJ_BLASTEST_PATH)/$(1).o $(BLASTEST_F2C_LIB) $(LIBBLIS_LINK) ifeq ($(ENABLE_VERBOSE),yes) $(LINKER) $(BASE_OBJ_BLASTEST_PATH)/$(1).o $(BLASTEST_F2C_LIB) $(LIBBLIS_LINK) $(LDFLAGS) -o $$@ else @echo "Linking $$(@F) against '$(notdir $(BLASTEST_F2C_LIB)) $(LIBBLIS_LINK) $(LDFLAGS)'" @$(LINKER) $(BASE_OBJ_BLASTEST_PATH)/$(1).o $(BLASTEST_F2C_LIB) $(LIBBLIS_LINK) $(LDFLAGS) -o $$@ endif endef # Instantiate the rule above for each driver file. $(foreach name, $(BLASTEST_DRV_BASES), $(eval $(call make-blat-rule,$(name)))) # A rule to run ?blat1.x driver files. define make-run-blat1-rule run-$(1): $(BASE_OBJ_BLASTEST_PATH)/$(1).x ifeq ($(ENABLE_VERBOSE),yes) $(BASE_OBJ_BLASTEST_PATH)/$(1).x > out.$(1) else @echo "Running $(1).x > 'out.$(1)'" @$(BASE_OBJ_BLASTEST_PATH)/$(1).x > out.$(1) endif endef # Instantiate the rule above for each level-1 driver file. $(foreach name, $(BLASTEST_DRV1_BASES), $(eval $(call make-run-blat1-rule,$(name)))) # A rule to run ?blat2.x and ?blat3.x driver files. define make-run-blat23-rule run-$(1): $(BASE_OBJ_BLASTEST_PATH)/$(1).x ifeq ($(ENABLE_VERBOSE),yes) $(BASE_OBJ_BLASTEST_PATH)/$(1).x < $(BLASTEST_INPUT_PATH)/$(1).in else @echo "Running $(1).x < '$(BLASTEST_INPUT_PATH)/$(1).in' (output to 'out.$(1)')" @$(BASE_OBJ_BLASTEST_PATH)/$(1).x < $(BLASTEST_INPUT_PATH)/$(1).in endif endef # Instantiate the rule above for each level-2 driver file. $(foreach name, $(BLASTEST_DRV2_BASES), $(eval $(call make-run-blat23-rule,$(name)))) # Instantiate the rule above for each level-3 driver file. $(foreach name, $(BLASTEST_DRV3_BASES), $(eval $(call make-run-blat23-rule,$(name)))) # Check the results of the BLAS test suite drivers. checkblas: blastest-run ifeq ($(ENABLE_VERBOSE),yes) - $(BLASTEST_CHECK) else @- $(BLASTEST_CHECK) endif # --- BLIS test suite rules --- testblis: testsuite testblis-fast: testsuite-run-fast testsuite: testsuite-run testsuite-bin: check-env $(TESTSUITE_BIN) # Object file rule. $(BASE_OBJ_TESTSUITE_PATH)/%.o: $(TESTSUITE_SRC_PATH)/%.c ifeq ($(ENABLE_VERBOSE),yes) $(CC) $(call get-frame-cflags-for,$(CONFIG_NAME)) -c $< -o $@ else @echo "Compiling $@" @$(CC) $(call get-frame-cflags-for,$(CONFIG_NAME)) -c $< -o $@ endif # Testsuite binary rule. $(TESTSUITE_BIN): $(MK_TESTSUITE_OBJS) $(LIBBLIS_LINK) ifeq ($(ENABLE_VERBOSE),yes) $(LINKER) $(MK_TESTSUITE_OBJS) $(LIBBLIS_LINK) $(LDFLAGS) -o $@ else @echo "Linking $@ against '$(LIBBLIS_LINK) $(LDFLAGS)'" @$(LINKER) $(MK_TESTSUITE_OBJS) $(LIBBLIS_LINK) $(LDFLAGS) -o $@ endif # A rule to run the testsuite using the normal input.* files. testsuite-run: testsuite-bin ifeq ($(ENABLE_VERBOSE),yes) ./$(TESTSUITE_BIN) -g $(TESTSUITE_CONF_GEN_PATH) \ -o $(TESTSUITE_CONF_OPS_PATH) \ > $(TESTSUITE_OUT_FILE) else @echo "Running $(TESTSUITE_BIN) with output redirected to '$(TESTSUITE_OUT_FILE)'" @./$(TESTSUITE_BIN) -g $(TESTSUITE_CONF_GEN_PATH) \ -o $(TESTSUITE_CONF_OPS_PATH) \ > $(TESTSUITE_OUT_FILE) endif # A rule to run the testsuite using the input.*.fast files, which # run a set of tests designed to finish much more quickly. testsuite-run-fast: testsuite-bin ifeq ($(ENABLE_VERBOSE),yes) ./$(TESTSUITE_BIN) -g $(TESTSUITE_FAST_GEN_PATH) \ -o $(TESTSUITE_FAST_OPS_PATH) \ > $(TESTSUITE_OUT_FILE) else @echo "Running $(TESTSUITE_BIN) (fast) with output redirected to '$(TESTSUITE_OUT_FILE)'" @./$(TESTSUITE_BIN) -g $(TESTSUITE_FAST_GEN_PATH) \ -o $(TESTSUITE_FAST_OPS_PATH) \ > $(TESTSUITE_OUT_FILE) endif # Check the results of the BLIS testsuite. checkblis: testsuite-run ifeq ($(ENABLE_VERBOSE),yes) - $(TESTSUITE_CHECK) $(TESTSUITE_OUT_FILE) else @- $(TESTSUITE_CHECK) $(TESTSUITE_OUT_FILE) endif # Check the results of the BLIS testsuite (fast). checkblis-fast: testsuite-run-fast ifeq ($(ENABLE_VERBOSE),yes) - $(TESTSUITE_CHECK) $(TESTSUITE_OUT_FILE) else @- $(TESTSUITE_CHECK) $(TESTSUITE_OUT_FILE) endif # --- Install header rules --- install-headers: check-env $(MK_INCL_DIR_INST) $(MK_INCL_DIR_INST): $(HEADERS_TO_INSTALL) $(CONFIG_MK_FILE) ifeq ($(ENABLE_VERBOSE),yes) $(MKDIR) $(@) $(INSTALL) -m 0644 $(HEADERS_TO_INSTALL) $(@) else @$(MKDIR) $(@) @echo "Installing $(notdir $(HEADERS_TO_INSTALL)) into $(@)/" @$(INSTALL) -m 0644 $(HEADERS_TO_INSTALL) $(@) endif # --- Install library rules --- install-libs: check-env $(MK_LIBS_INST) # Install static library. $(INSTALL_LIBDIR)/%.a: $(BASE_LIB_PATH)/%.a $(CONFIG_MK_FILE) ifeq ($(ENABLE_VERBOSE),yes) $(MKDIR) $(@D) $(INSTALL) -m 0644 $< $@ else @echo "Installing $(@F) into $(INSTALL_LIBDIR)/" @$(MKDIR) $(@D) @$(INSTALL) -m 0644 $< $@ endif # Install shared library containing .so major, minor, and build versions. $(INSTALL_LIBDIR)/%.$(SHLIB_EXT).$(SO_MMB): $(BASE_LIB_PATH)/%.$(SHLIB_EXT) $(CONFIG_MK_FILE) ifeq ($(ENABLE_VERBOSE),yes) $(MKDIR) $(@D) $(INSTALL) -m 0644 $< $@ else @echo "Installing $(@F) into $(INSTALL_LIBDIR)/" @$(MKDIR) $(@D) @$(INSTALL) -m 0644 $< $@ endif # --- Install-symlinks rules --- install-lib-symlinks: check-env $(MK_LIBS_SYML) # Install generic shared library symlink. $(INSTALL_LIBDIR)/%.$(SHLIB_EXT): $(INSTALL_LIBDIR)/%.$(SHLIB_EXT).$(SO_MMB) ifeq ($(ENABLE_VERBOSE),yes) $(SYMLINK) $( $(DIST_PATH)/$(CHANGELOG) # --- Uninstall rules --- # NOTE: We can't write these uninstall rules directly in terms of targets # $(MK_LIBS_VERS_CONF_INST), $(MK_LIBS_INST), and $(MK_INCL_DIR_INST) # because those targets are already defined in terms of rules that *build* # those products. uninstall-libs: check-env ifeq ($(ENABLE_VERBOSE),yes) - $(RM_F) $(MK_LIBS_INST) else @echo "Uninstalling libraries $(notdir $(MK_LIBS_INST)) from $(dir $(firstword $(MK_LIBS_INST)))." @- $(RM_F) $(MK_LIBS_INST) endif uninstall-lib-symlinks: check-env ifeq ($(ENABLE_VERBOSE),yes) - $(RM_F) $(MK_LIBS_SYML) else @echo "Uninstalling symlinks $(notdir $(MK_LIBS_SYML)) from $(dir $(firstword $(MK_LIBS_SYML)))." @- $(RM_F) $(MK_LIBS_SYML) endif uninstall-headers: check-env ifeq ($(ENABLE_VERBOSE),yes) - $(RM_RF) $(MK_INCL_DIR_INST) else @echo "Uninstalling directory '$(notdir $(MK_INCL_DIR_INST))' from $(dir $(MK_INCL_DIR_INST))." @- $(RM_RF) $(MK_INCL_DIR_INST) endif # --- Uninstall old rules --- uninstall-old-libs: $(UNINSTALL_OLD_LIBS) check-env uninstall-old-symlinks: $(UNINSTALL_OLD_SYML) check-env uninstall-old-headers: $(UNINSTALL_OLD_HEADERS) check-env $(UNINSTALL_OLD_LIBS) $(UNINSTALL_OLD_SYML) $(UNINSTALL_OLD_HEADERS): check-env ifeq ($(ENABLE_VERBOSE),yes) - $(RM_F) $@ else @echo "Uninstalling $(@F) from $(@D)/." @- $(RM_F) $@ endif