#!/bin/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. # # # # Makefile # # Field G. Van Zee # # Makefile for standalone BLIS test drivers. # # # --- Makefile PHONY target definitions ---------------------------------------- # .PHONY: all bin clean \ check-env check-env-mk check-env-fragments check-env-make-defs \ run run-amd64 run-x86 run-arm # # --- Makefile initialization -------------------------------------------------- # # Define the name of the configuration file. CONFIG_MK_FILE := config.mk # Define the name of the file containing build and architecture-specific # makefile definitions. MAKE_DEFS_FILE := make_defs.mk # All makefile fragments in the tree will have this name. FRAGMENT_MK := .fragment.mk # Locations of important files. CONFIG_DIR := config FRAME_DIR := frame LIB_DIR := lib # # --- Include makefile configuration file -------------------------------------- # # Construct the path to the makefile configuration file that was generated by # the configure script. CONFIG_MK_PATH := ../$(CONFIG_MK_FILE) # Include the configuration file. -include $(CONFIG_MK_PATH) # 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 $(CONFIG_MK_INCLUDED)),yes) CONFIG_MK_PRESENT := yes else CONFIG_MK_PRESENT := no endif # Override the DIST_PATH value obtained from config.mk, since it is relative # to the build directory. DIST_PATH := .. # Now we have access to CONFIG_NAME, which tells us which sub-directory of the # config directory to use as our configuration. CONFIG_PATH := $(DIST_PATH)/$(CONFIG_DIR)/$(CONFIG_NAME) FRAME_PATH := $(DIST_PATH)/$(FRAME_DIR) # # --- Include makefile definitions file ---------------------------------------- # # Construct the path to the makefile definitions file residing inside of # the configuration sub-directory. MAKE_DEFS_MK_PATH := $(CONFIG_PATH)/$(MAKE_DEFS_FILE) # Include the makefile definitions file. -include $(MAKE_DEFS_MK_PATH) # Detect whether we actually got the make definitios file. If we didn't, then # it is likely that the configuration is invalid (or incomplete). ifeq ($(strip $(MAKE_DEFS_MK_INCLUDED)),yes) MAKE_DEFS_MK_PRESENT := yes else MAKE_DEFS_MK_PRESENT := no endif # # --- Include makefile fragments ----------------------------------------------- # # Initialize our list of directory paths to makefile fragments with the empty # list. This variable will accumulate all of the directory paths in which # makefile fragments reside. FRAGMENT_DIR_PATHS := # This variable is used by the include statements as they recursively include # one another. For the framework source tree ('frame' directory), we initialize # it to the top-level directory since that is its parent. PARENT_PATH := $(DIST_PATH) # Recursively include all the makefile fragments in the framework itself. -include $(addsuffix /$(FRAGMENT_MK), $(FRAME_PATH)) # Now set PARENT_PATH to $(DIST_PATH)/config in preparation to include the # fragments in the configuration sub-directory. PARENT_PATH := $(DIST_PATH)/$(CONFIG_DIR) # Recursively include all the makefile fragments in the configuration # sub-directory. -include $(addsuffix /$(FRAGMENT_MK), $(CONFIG_PATH)) # Create a list of the makefile fragments. MAKEFILE_FRAGMENTS := $(addsuffix /$(FRAGMENT_MK), $(FRAGMENT_DIR_PATHS)) # Detect whether we actually got any makefile fragments. If we didn't, then it # is likely that the user has not yet generated them (via configure). ifeq ($(strip $(MAKEFILE_FRAGMENTS)),) MAKEFILE_FRAGMENTS_PRESENT := no else MAKEFILE_FRAGMENTS_PRESENT := yes endif # # --- Compiler include path definitions ---------------------------------------- # # Expand the fragment paths that contain .h files to attain the set of header # files present in all fragment paths. MK_HEADER_FILES := $(foreach frag_path, $(FRAGMENT_DIR_PATHS), \ $(wildcard $(frag_path)/*.h)) # Strip the leading, internal, and trailing whitespace from our list of header # files. This makes the "make install-headers" much more readable. MK_HEADER_FILES := $(strip $(MK_HEADER_FILES)) # Expand the fragment paths that contain .h files, and take the first # expansion. Then, strip the header filename to leave the path to each header # location. Notice this process even weeds out duplicates! Add the config # directory manually since it contains FLA_config.h. MK_HEADER_DIR_PATHS := $(dir $(foreach frag_path, $(FRAGMENT_DIR_PATHS), \ $(firstword $(wildcard $(frag_path)/*.h)))) # Add -I to each header path so we can specify our include search paths to the # C compiler. INCLUDE_PATHS := $(strip $(patsubst %, -I%, $(MK_HEADER_DIR_PATHS))) CFLAGS := $(CFLAGS) $(INCLUDE_PATHS) # # --- BLAS and LAPACK implementations ------------------------------------------ # # BLIS library and header path. This is simply wherever it was installed. #BLIS_LIB_PATH := $(INSTALL_PREFIX)/lib #BLIS_INC_PATH := $(INSTALL_PREFIX)/include/blis # BLIS library. BLIS_LIB_PATH := $(DIST_PATH)/$(LIB_DIR)/$(CONFIG_NAME) BLIS_LIB := $(BLIS_LIB_PATH)/libblis.a # BLAS library path(s). This is where the BLAS libraries reside. #BLAS_LIB_PATH := $(HOME)/flame/lib # OpenBLAS, ATLAS, and MKL libraries. #BLAS_LIB := $(LIB_PATH)/libblas.a #BLAS_LIB := $(LIB_PATH)/libgoto.a #BLAS_LIB := $(LIB_PATH)/libgoto2.a #OPENBLAS_LIB := $(BLAS_LIB_PATH)/libopenblas.a #ATLAS_LIB := $(BLAS_LIB_PATH)/libf77blas.a \ # $(BLAS_LIB_PATH)/libatlas.a #MKL_LIB := -L/opt/intel/mkl/10.2.2.025/lib/em64t/ \ # -lmkl_sequential -lmkl_core -lmkl_intel_lp64 # # --- Optional overrides ------------------------------------------------------- # # Uncomment and modify these definitions if you wish to override the values # present in the current BLIS configuration's makefile definitions file # (ie: config//make_defs.mk). # CC := gcc # LINKER := $(CC) # CFLAGS := -g -O2 -Wall -Wno-comment # LDFLAGS := # INSTALL_PREFIX := $(HOME)/blis # # --- General build definitions ------------------------------------------------ # TEST_SRC_PATH := src TEST_OBJ_PATH := obj # Gather all local object files. TEST_OBJS := $(patsubst $(TEST_SRC_PATH)/%.c, \ $(TEST_OBJ_PATH)/%.o, \ $(wildcard $(TEST_SRC_PATH)/*.c)) ifeq ($(CONFIG_NAME),pnacl) # Linked executable TEST_BIN := test_libblis.unstable.pexe # Finalized executable TEST_BIN_PNACL := test_libblis.pexe # Translated executable for x86-64 TEST_BIN_AMD64 := test_libblis.x86-64.nexe # Translated executable for x86 TEST_BIN_X86 := test_libblis.x86.nexe # Translated executable for ARM TEST_BIN_ARM := test_libblis.arm.nexe else # Binary executable name. TEST_BIN := test_libblis.x endif # Add installed and local header paths to CFLAGS CFLAGS += -I$(BLIS_INC_PATH) -I$(TEST_SRC_PATH) # # --- Targets/rules ------------------------------------------------------------ # # --- Primary targets --- all: check-env bin ifeq ($(CONFIG_NAME),pnacl) bin: check-env $(TEST_BIN) $(TEST_BIN_PNACL) $(TEST_BIN_AMD64) $(TEST_BIN_X86) $(TEST_BIN_ARM) else bin: check-env $(TEST_BIN) endif # --- 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 ($(MAKE_DEFS_MK_PRESENT),no) $(error Cannot proceed: make_defs.mk not detected! Invalid configuration) endif # --Object file rules -- $(TEST_OBJ_PATH)/%.o: $(TEST_SRC_PATH)/%.c $(BLIS_LIB) ifeq ($(BLIS_ENABLE_VERBOSE_MAKE_OUTPUT),yes) $(CC) $(CFLAGS) -c $< -o $@ else @echo "Compiling $<" @$(CC) $(CFLAGS) -c $< -o $@ endif # -- Executable file rules -- $(TEST_BIN): $(TEST_OBJS) $(BLIS_LIB) ifeq ($(BLIS_ENABLE_VERBOSE_MAKE_OUTPUT),yes) $(LINKER) $(TEST_OBJS) $(BLIS_LIB) $(LDFLAGS) -o $@ else @echo "Linking $@ against '$(BLIS_LIB) $(LDFLAGS)'" @$(LINKER) $(TEST_OBJS) $(BLIS_LIB) $(LDFLAGS) -o $@ endif ifeq ($(CONFIG_NAME),pnacl) # Finalize PNaCl executable (i.e. convert from LLVM bitcode to PNaCl bitcode) $(TEST_BIN_PNACL): $(TEST_BIN) ifeq ($(BLIS_ENABLE_VERBOSE_MAKE_OUTPUT),yes) $(FINALIZER) $(FINFLAGS) -o $@ $(TEST_BIN) else @echo "Finalizing $@" @$(FINALIZER) $(FINFLAGS) -o $@ $(TEST_BIN) endif # Translate PNaCl executable to x86-64 NaCl executable $(TEST_BIN_AMD64): $(TEST_BIN_PNACL) ifeq ($(BLIS_ENABLE_VERBOSE_MAKE_OUTPUT),yes) $(TRANSLATOR) $(TRNSFLAGS) $(TRNSAMD64FLAGS) $< -o $@ else @echo "Translating $< -> $@" @$(TRANSLATOR) $(TRNSFLAGS) $(TRNSAMD64FLAGS) $< -o $@ endif # Translate PNaCl executable to x86 NaCl executable $(TEST_BIN_X86): $(TEST_BIN_PNACL) ifeq ($(BLIS_ENABLE_VERBOSE_MAKE_OUTPUT),yes) $(TRANSLATOR) $(TRNSFLAGS) $(TRNSX86FLAGS) $< -o $@ else @echo "Translating $< -> $@" @$(TRANSLATOR) $(TRNSFLAGS) $(TRNSX86FLAGS) $< -o $@ endif # Translate PNaCl executable to ARMv7 NaCl executable $(TEST_BIN_ARM): $(TEST_BIN_PNACL) ifeq ($(BLIS_ENABLE_VERBOSE_MAKE_OUTPUT),yes) $(TRANSLATOR) $(TRNSFLAGS) $(TRNSARMFLAGS) $< -o $@ else @echo "Translating $< -> $@" @$(TRANSLATOR) $(TRNSFLAGS) $(TRNSARMFLAGS) $< -o $@ endif endif # -- Test run rules -- ifeq ($(CONFIG_NAME),pnacl) run-amd64: $(TEST_BIN_AMD64) $(NACL_SDK_ROOT)/tools/sel_ldr_x86_64 -a -c -q -B $(NACL_SDK_ROOT)/tools/irt_core_x86_64.nexe -- $(TEST_BIN_AMD64) run-x86: $(TEST_BIN_X86) $(NACL_SDK_ROOT)/tools/sel_ldr_x86_32 -a -c -q -B $(NACL_SDK_ROOT)/tools/irt_core_x86_32.nexe -- $(TEST_BIN_X86) run-arm: $(TEST_BIN_ARM) $(NACL_SDK_ROOT)/tools/sel_ldr_arm -a -c -q -B $(NACL_SDK_ROOT)/tools/irt_core_arm.nexe -- $(TEST_BIN_ARM) else run: $(TEST_BIN) ./$(TEST_BIN) endif # -- Clean rules -- ifeq ($(CONFIG_NAME),pnacl) clean: - $(RM_F) $(TEST_OBJS) $(TEST_BIN) $(TEST_BIN_PNACL) $(TEST_BIN_AMD64) $(TEST_BIN_X86) $(TEST_BIN_ARM) else clean: - $(RM_F) $(TEST_OBJS) $(TEST_BIN) endif