# ESA (C) 2000-2022 # # This file is part of ESA's XMM-Newton Scientific Analysis System (SAS). # # SAS is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # SAS is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with SAS. If not, see . # # Each Makefile should include this file. # # The following targets exist: # all (default) builds packages. Produces an HTML # result page. Non-zero exit code in case of an error # check inspects, builds and tests packages # incheck inspects, builds and tests packages: only ps doc, leaves # object files so as to allow one to make incremental # builds. # depend construct dependencies # bin create everything needed to run the software # clean remove all but configuration, executables and documentation # clobber remove all that is not part of original distribution # tests compile test programs # test run all tests; exits != 0 if one or more failed # data run data generating scripts # ps produces PostScript documentation # html produces HTML documentation # doc produce PostScript and HTML documentation # dist make a tgz file of a package # upload package the directory and send it to the SOC # distcheck run the distribution check for the package # depcheck run the dependency check for the package # # The following variables can be defined in a Makefile that includes this file: # BINS binaries that are to be compiled # LIBS libraries that are to be constructed # COMBILIBS library that is constructed from a list of other libraries # TASKS tasks to be constructed from a Fortran module # SCRIPTS scripts that should be publicly accessible # DATACRIPTS scripts that are executed for target 'data' # FMODS fortran modules that are not part of a library # LINKS extra symbolic links; a rule has to be provided as well # EXTERNALS extra linker/compiler flags related to external packages # CONFIGFILES configuration files # USEDLIBS list of all libraries to be included and linked # a_OBJS objects to link with target a # TEXDOCS tex documents # TEXFORM format of tex documents (book|package[=default]) # TESTBINS binaries that are to be compiled for testing # TESTS executables that should exit with status 0 # MKDIRS directories to be created during make # DOCS HTML pages that are entry points into the documentation # DOCDIRS HTML subdirectories # INTERFACES Files to export to 'include' directory (default is the directory) # INTERNALS Package subdirectories to be used to search for headers/modules # DEVBINS development binaries. As BINS but placed in bin/devel # DEVSCRIPTS development scripts. As SCRIPTS but placed in bin/devel # DEVTASKS development tasks. As TASKS but placed in bin/devel # DATADIRS directories to be linked under lib/data # ODFDIRS directories to be linked under lib/testodf # PERLDIRS directories with Perl code to be linked directly under lib/perl5 # PERLMODS for individual modules that must be placed under lib/perl5 # EXTPERLMODS list of external perl modules to be built for a specific perl task # EXTPERLDIR directory containing the external perl modules EXTPERLMODS # EXTPERLSCRIPT script to build sequentially EXTPERLMODS # PYTHONMODS for individual python modules which must be placed under lib/python # PYTHONDIRS directories with python code to be linked directly under lib/python # # The following environment variables have to be set: # SAS_DIR the location of the toplevel of the official SAS distribution # SAS_PATH a list of directories containing SAS packages. # SHELL := /bin/bash GNUTAR := /usr/bin/tar GNUFIND := /usr/bin/find SHARED = yes SHAREDVERSION = no TARGETOS := x86_64-apple-darwin22.6.0 TARGET_OS := macOS-13.6.9 TRACE = no DEBUG = yes VERBOSE = no PROFILE = no RELEASETYPE = devel SLOPPY = yes STRICTCPP = no RUNTESTS = yes FULLDOC = yes OPTIMIZATION = no OLEVEL := 2 F90OLEVEL := 2 CXXOLEVEL := $(OLEVEL) SAS_PERL := /Volumes/SAS/sasbuild/local/xmmm23/GNU_CC_CXX_11.3.0/perl/bin/perl PYTHON := /Volumes/SAS/sasbuild/local/xmmm23/GNU_CC_CXX_11.3.0/python/bin/python # # Profiling requires DEBUG=yes, SHARED=no and SHAREDVERSION=no # ifeq ($(PROFILE), yes) DEBUG = yes SHARED = no OPTIMIZATION = no endif # # Get rid of the several entering/leaving directory messages # MAKEFLAGS := --no-print-directory # # Compilation flags determined by configure. # They may be modified later. # CXXFLAGS := -Wall -DGFORTRAN -std=gnu++14 -fno-common CFLAGS := -Wall -std=gnu++14 -fno-common F90FLAGS := -fimplicit-none -fno-range-check -DGFORTRAN -fallow-argument-mismatch FFLAGS := -fno-range-check -DGFORTRAN -fallow-argument-mismatch # # Linker flags determined by configure # LDFLAGS := # # Path names # # # Directory with utilities under the sas package # SASBIN := $(SAS_DIR)/packages/sas/bin SASBINDEV := $(SAS_DIR)/bin/devel # # TOPDIR is that component of the SAS_PATH that we're in right now. # Evaluate it only in the toplevel make and pass it down to recursive makes. # ifeq (0,$(MAKELEVEL)) TOPDIR := $(shell $(SASBIN)/whichpart $(SAS_PATH)) MAKE += "TOPDIR=$(TOPDIR)" endif # # SASDIRS is the space separated list of directories in SAS_PATH # Defer evaluation by sing = instead of := # SASDIRS = $(shell $(SASBIN)/saspath $(SAS_PATH)) # # RELATDIR is the relative path to TOPDIR # REFERDIR := $(patsubst /%,%,$(subst $(shell cd $(TOPDIR);pwd),,$(shell pwd))) RELATDIR := $(subst . .,./.,$(patsubst %,..,$(subst /, ,$(REFERDIR)))) # # Basic SAS directories # LIBDIR := $(TOPDIR)/lib PERLLIBDIR := $(LIBDIR)/perl5 PYTHONLIBDIR := $(LIBDIR)/python PYTHONLIBDISTSDIR := $(PYTHONLIBDIR)/dists PYTHONLIBPYSASDIR := $(PYTHONLIBDIR)/pysas INCDIR := $(TOPDIR)/include BINDIR := $(TOPDIR)/bin DEVBINDIR := $(TOPDIR)/bin/devel CONFIGDIR := $(TOPDIR)/config DOCDIR := $(TOPDIR)/doc DATADIR := $(TOPDIR)/lib/data DATADIRTMP := $(TOPDIR)/lib/data/tmp ODFDIR := $(TOPDIR)/lib/testodf # # List of all directories that contain SAS libraries # LIBDIRS += $(addsuffix /lib,$(SASDIRS)) # # V A R I A B L E S # # # In this directory we make combilibs. # COMBIDIR := __combidir__ # # AKA and RELEASE # AKA := 22.0.0 ifneq (,$(wildcard RELEASE)) RELEASE := $(strip $(shell cat RELEASE)) MAKE += RELEASE=$(RELEASE) endif # # The package's version is equal to the contents # of the VERSION file encountered within it # ifneq (,$(wildcard VERSION)) VERSION := $(strip $(shell cat VERSION)) PKGDIR := $(shell pwd) PACKAGE := $(notdir $(shell pwd)) MAKE += PKGDIR=$(PKGDIR) VERSION=$(VERSION) PACKAGE=$(PACKAGE) # # Create a VERSION tag for the libraries # ifeq ($(SHARED),yes) ifeq ($(SHAREDVERSION),yes) MAJOR_VERSION :=$(strip $(shell cat VERSION | cut -d. -f1)) MINOR_VERSION :=$(strip $(shell cat VERSION | cut -d. -f2)) # # From now on we can test against SO_VERSION, to determine usage of # shared version numbering SO_VERSION := $(MAJOR_VERSION).$(MINOR_VERSION) MAKE += SO_VERSION=$(SO_VERSION) endif endif endif # # document format: (package[default], book) # ifeq (,$(TEXFORM)) TEXFORM := package endif # # The default suffix of shared libraries as given by configure # SO := dylib # # This makes the list of packages topologically sorted according to dependencies # This determines the package's building order # PKGLIST = $(shell $(SASBIN)/mkpkglist) # # If tracing is on (yes) we add -DTRACE to C++ flags # ifeq ($(TRACE),yes) CPPFLAGS += -DTRACE endif # # These links must be registered before DEVTASKS and TASKS are # actually merged below. Go via an intermediate variable to prevent # recursive expansion, given that the two variables are merged. # task_links := $(strip \ $(addprefix $(BINDIR)/,$(TASKS)) \ $(addprefix $(DEVBINDIR)/,$(DEVTASKS))) LINKS += $(task_links) # # from now on there is no difference between TASKS and DEVTASKS # TASKS += $(DEVTASKS) # # Check which part of the infrastructure is used. # # # Currently *all* tasks must include metatask :-( # Someday that should be FIXED. # ifneq ($(TASKS),) ifneq (metatask,$(filter metatask,$(USEDLIBS))) USEDLIBS := metatask $(USEDLIBS) metatask endif endif # # This is ugly, but cal and oal should be combilibs (someday to be FIXED) # # Must use sort to eliminate duplicates, or the hack does not work # param -> qt needed, dal needed # # If param is used, then link in qt. This must not make # used of EXTERNALS = qt because otherwise every task becomes a # QtApplication, and this makes it difficult to run tasks in the # background # ifeq (param,$(sort $(filter param,$(USEDLIBS)))) USEDLIBS := $(USEDLIBS:param=param selector caloalutils dal slatec) #### EXTERNALS += qt INCS += -I/Volumes/SAS/sasbuild/local/xmmm23/GNU_CC_CXX_11.3.0/qt-x11-free/include LDLIBS += -L/Volumes/SAS/sasbuild/local/xmmm23/GNU_CC_CXX_11.3.0/qt-x11-free/lib -lqt -framework Security endif ifeq (cal,$(sort $(filter cal,$(USEDLIBS)))) USEDLIBS := $(USEDLIBS:cal=cal selector caloalutils selector slatec) CPPFLAGS += -DUSE_CAL endif ifeq (oal,$(sort $(filter oal,$(USEDLIBS)))) USEDLIBS := $(USEDLIBS:oal=oal dal caloalutils slatec) CPPFLAGS += -DUSE_OAL endif ifeq (dal,$(sort $(filter dal,$(USEDLIBS)))) CPPFLAGS += -DUSE_DAL endif # # qt # ifeq (qt,$(sort $(filter qt,$(EXTERNALS)))) CPPFLAGS += -DUSE_QT endif # # cfitsio # ifeq (cfitsio,$(sort $(filter cfitsio,$(EXTERNALS)))) CPPFLAGS += -DUSE_CFITSIO endif # # Determine the type of tasks # # Look for anything with .pl and get rid of the .pl part # Look for anything with .cc and get rid of the .cc part # Look for anything with _mod.f90 and get rid of the _mod.f90 part # Look for anything with .py and get rid of the .py part # PERLTASKS=$(strip $(subst .pl,,$(wildcard $(TASKS:=.pl)))) CXXTASKS=$(strip $(subst .cc,,$(wildcard $(TASKS:=.cc)))) FTASKS=$(strip $(subst _mod.f90,,$(wildcard $(TASKS:=_mod.f90)))) PYTHONTASKS=$(strip $(subst .py,,$(wildcard $(TASKS:=.py)))) # # Tasks that main use of a c++ main # # Get out of TASKS the PERLTASKS and PYTHONTASKS # NEEDTASKMAIN = $(filter-out $(PERLTASKS) $(PYTHONTASKS), $(TASKS)) # # Code that is to be generated automatically. # TASKHEADERS = $(addsuffix .h,$(NEEDTASKMAIN)) TASKHEADIMPS = $(addsuffix _h_imp.cc,$(NEEDTASKMAIN)) ####TASKMODS = $(addsuffix _f_mod.f90,$(CXXTASKS)) $(addsuffix _f_mod.f90,$(PERLTASKS)) TASKMODS = $(addsuffix _f_mod.f90,$(CXXTASKS)) TASKMAINS = $(addsuffix _main.cc,$(NEEDTASKMAIN)) FTASKWRAPPERS = $(addsuffix _f.cc,$(CXXTASKS)) CXXTASKWRAPPERS = $(addsuffix _c.cc,$(FTASKS)) ####FTASKWRAPPERS = $(addsuffix _f.cc,$(CXXTASKS)) $(addsuffix _f.cc,$(PERLTASKS)) ####CXXTASKWRAPPERS = $(addsuffix _c.cc,$(FTASKS)) $(addsuffix _c.cc,$(PERLTASKS)) PERLTASKWRAPPERS = # # # On the road to a proper dependency mechanism at least for tex/ps # documents, and in order to make incremental builds faster, the old # dummy _ps rule (that is still available below) is no longer used # in PSTARGETS. Rather we use .ps.gz. # ####PSTARGETS += $(TEXDOCS:=_ps) # PSTARGETS += $(TEXDOCS:=.ps.gz) # # Since we do not have a proper dependency mechanism, we force making # the documentation. # HTMLTARGETS += $(TEXDOCS:=_html) DOCTARGETS += $(PSTARGETS) $(HTMLTARGETS) # # .prm files are no longer in use, but they appear in the make # files. Convert .prm to .par. # CONFIGFILES := $(CONFIGFILES:.prm=.par) # # List of all symbolic links to create before make depend or make all # NOTE: the links for TASKS and DEVTASKS are registered earlier # LINKS += $(strip \ $(addprefix $(LIBDIR)/,$(LIBFILES)) \ $(addprefix $(LIBDIR)/,$(COMBILIBFILES)) \ $(addprefix $(PERLLIBDIR)/,$(addsuffix .pl,$(PERLTASKS))) \ $(addprefix $(PERLLIBDIR)/,$(PERLMODS)) \ $(addprefix $(PERLLIBDIR)/,$(PERLDIRS)) \ $(addprefix $(PYTHONLIBDIR)/,$(addsuffix .py,$(PYTHONTASKS))) \ $(addprefix $(PYTHONLIBDIR)/, $(PYTHONMODS)) \ $(addprefix $(PYTHONLIBDIR)/, $(PYTHONDIRS)) \ $(addprefix $(BINDIR)/,$(BINS)) \ $(addprefix $(BINDIR)/,$(SCRIPTS)) \ $(addprefix $(DEVBINDIR)/,$(DEVBINS)) \ $(addprefix $(DEVBINDIR)/,$(DEVSCRIPTS)) \ $(addprefix $(CONFIGDIR)/,$(CONFIGFILES)) \ $(addprefix $(DATADIR)/,$(DATADIRS)) \ $(addprefix $(ODFDIR)/,$(ODFDIRS)) \ $(addprefix $(DOCDIR)/,$(DOCDIRS)) \ $(addprefix $(DOCDIR)/,$(TEXDOCS)) \ $(addprefix $(DOCDIR)/,$(addsuffix .ps.gz,$(TEXDOCS))) \ $(addprefix $(DOCDIR)/,$(addsuffix .pdf,$(TEXDOCS))) \ $(addprefix $(DOCDIR)/,$(DOCS))) # # If INTERFACES is defined, create links to invidividual header files, # else create a link to the directory (with trailing '/' that can be # matched by a separate rule). # Create an additional link to the ".mod" file, for each ".f90" file specified. # ifdef INTERFACES LINKS += $(strip \ $(addprefix $(INCDIR)/,$(INTERFACES)) \ $(addprefix $(INCDIR)/,$(subst .f90,.mod,$(filter %.f90,$(INTERFACES))))) else LINKS += $(strip \ $(addsuffix \/,$(addprefix $(INCDIR)/,$(COMBILIBS))) \ $(addsuffix \/,$(addprefix $(INCDIR)/,$(LIBS))) \ $(addsuffix \/,$(addprefix $(INCDIR)/,$(TASKS)))) endif # # Define the list of files and directories to be cleaned # CLEANFILES += sasdoc_version.tex *.g90 gmon.out dataconv.out *.o *.M *% *~ .\#* *.idx *.dvi *.aux *.log *.bbl makedoc.log *.blg *.toc core core.* a.out $(TESTBINS) m_*.cc test.result $(TEXDOCS:=.tex) $(FTASKWRAPPERS) $(CXXTASKWRAPPERS) $(PERLTASKWRAPPERS) $(TASKMODS) $(TASKMAINS) ._.DS_Store .DS_Store CLEANDIRS += Templates.DB autom4te.cache $(COMBIDIR)* __pychache__ # # Define the list of files and directories to be clobbered # CLOBBERFILES += *.mod lib*.a lib*.so lib*.so.* lib*.dylib $(LINKS) $(BINS) $(DEVBINS) $(TASKS) $(TEXDOCS:=.ps.gz) *.pdf *.prm $(addprefix $(CONFIGDIR)/,$(CONFIGFILES)) *.tmp build_log_second *_log check.txt check.html build.txt build.html Make.depends $(TASKHEADERS) $(TASKHEADIMPS) *.out ._.DS_Store .DS_Store CLOBBERDIRS += $(MKDIRS) $(TEXDOCS) __pycache__ # # Define the PWD variable # PWD := $(shell pwd) # # Set the VPATH so that the -l dependencies to static libraries can be found # VPATH += $(LIBDIRS) LIBBASES = $(strip $(LIBS) $(NEEDTASKMAIN)) LIBFILES = $(addprefix lib,$(addsuffix .a,$(LIBBASES))) COMBILIBFILES = $(addprefix lib,$(addsuffix .a,$(COMBILIBS))) # # Set the proper debug flags if DEBUG is set. # # By default debugging is off for any building, which means that # --disable-debug is set at configure time. # # Executables are stripped (-s option passed to ld), but this # option is not set here anymore. # ifeq ($(DEBUG), yes) CFLAGS += -g CXXFLAGS += -g F90FLAGS += -g FFLAGS += -g endif # # Set the proper flags is PROFILE is set # ifeq ($(PROFILE), yes) CFLAGS += -pg CXXFLAGS += -pg F90FLAGS += -pg FFLAGS += -pg LDFLAGS += -pg endif # # Set the proper flags when OPTIMIZATION is set # ifeq ($(OPTIMIZATION), yes) CFLAGS += -O$(CXXOLEVEL) CXXFLAGS += -O$(CXXOLEVEL) F90FLAGS += -O$(F90OLEVEL) FFLAGS += -O$(F90OLEVEL) endif # # If SHARED (default), define USE_POPUP # ifeq ($(SHARED), yes) CPPFLAGS += -DUSE_POPUP endif SHARED_LIBS_FLAGS = -bind_at_load -dynamiclib -single_module -undefined dynamic_lookup -Wl,-install_name,@loader_path/../lib/$@ # # If the $(SO_VERSION) is defined (not null), which means that both SHARED # and SHAREDVERSION are set to yes, then set the proper order for shared # library numbering depending on whether we are in a Linux # or on a Mac OS X (Darwin) platform. # ifneq (,$(SO_VERSION)) ifeq ($(SO),dylib) # libFOO.M.m.dylib SO_FULL_EXT:=$(SO_VERSION).$(SO) endif ifeq ($(SO),so) # libFOO.so.M.m SO_FULL_EXT:=$(SO).$(SO_VERSION) endif else SO_FULL_EXT:=$(SO) endif # # C O N F I G U R A T I O N # INSTALL := /usr/bin/install -c CC := gcc CPP := gcc -E CXX := g++ CXXCPP := g++ -E MOC := /Volumes/SAS/sasbuild/local/xmmm23/GNU_CC_CXX_11.3.0/qt-x11-free/bin/moc ECHO := /bin/echo ECHO_N := -n ECHO_C := # # Define a function that acts as echo -n # echon = $(ECHO) $(ECHO_N) "$(1)$(ECHO_C)" MV := mv MKDIR := /bin/mkdir PREFIX := /usr/local LEX := flex YACC := bison -y # # -->From here [until :-> below] the order is important # # If EXTERNALS includes any of the external tools below, # then the proper flags are set. # # # cfitsio # ifeq (cfitsio, $(findstring cfitsio,$(EXTERNALS))) LDLIBS += -lcfitsio endif # # Qt # ifeq (qt, $(findstring qt,$(EXTERNALS))) INCS += -I/Volumes/SAS/sasbuild/local/xmmm23/GNU_CC_CXX_11.3.0/qt-x11-free/include LDLIBS += -L/Volumes/SAS/sasbuild/local/xmmm23/GNU_CC_CXX_11.3.0/qt-x11-free/lib -lqt -framework Security endif # # Grace # ifeq (grace, $(findstring grace,$(EXTERNALS))) INCS += LDLIBS += -lgrace_np endif # # FTOOLS # ifeq (ftools, $(findstring ftools,$(EXTERNALS))) LDLIBS += -L/Volumes/SAS/sasbuild/local/xmmm23/GNU_CC_CXX_11.3.0/headas/architecture/lib -lpow -ltcl8.0 -ltk8.0 -litcl3.0 -litk3.0 endif # # PGPLOT (will include X11) # ifeq (pgplot, $(findstring pgplot,$(EXTERNALS))) INCS += LDLIBS += -lgfortran -lcpgplot -lpng -lz -lpgplot -lXaw -lXmu -lXt -lXext -lX11 endif # # X11 # ifeq (X11, $(findstring X11,$(EXTERNALS))) INCS += LDLIBS += -lXaw -lXmu -lXt -lXext -lX11 endif # # Perl # ifeq (perl, $(findstring perl,$(EXTERNALS))) INCS += -I/sasbuild/local/mushi/GNU_CC_CXX_11.3.0/perl_5.34.1/lib/5.34.1/darwin-2level/CORE LDLIBS += -mmacosx-version-min=12.6 -fstack-protector-strong -L/sasbuild/local/mushi/GNU_CC_CXX_11.3.0/perl_5.34.1/lib/5.34.1/darwin-2level/CORE -lperl endif # # fftw 3 single precission # ifeq (fftw3f, $(findstring fftw3f,$(EXTERNALS))) INCS += LDLIBS += -lfftw3f endif # # fftw 3 double precission # ifeq (fftw3, $(findstring fftw3,$(EXTERNALS))) INCS += LDLIBS += -lfftw3 endif # # Flags to generate position independent code # At the moment this must be turned on explicitly. # ifeq ($(SHARED), yes) CFLAGS += -fPIC # do not add -fPIC by default to CXXFLAGS since the main # program should not be compiled with -fPIC. CXXSHAREDFLAGS += -fPIC F90FLAGS += -fPIC FFLAGS += -fPIC # lib.$(SO) is always a link to the actual library -- LIBFILES is added to # LINKS. We do not use += because it create a space which we don't want LIBFILES := $(strip $(LIBFILES) $(addprefix lib,$(addsuffix .$(SO_FULL_EXT),$(LIBBASES)))) COMBILIBFILES := $(strip $(COMBILIBFILES) $(addprefix lib,$(addsuffix .$(SO_FULL_EXT),$(COMBILIBS)))) ifneq ($(SO),$(SO_FULL_EXT)) # add links for versioned shared libraries LINKS+=$(addprefix $(LIBDIR)/lib,$(addsuffix .$(SO),$(LIBS))) LINKS+=$(addprefix $(LIBDIR)/lib,$(addsuffix .$(SO),$(COMBILIBS))) LINKS+=$(addprefix $(LIBDIR)/lib,$(addsuffix .$(SO),$(NEEDTASKMAIN))) endif endif # # The list of targets when invoking 'make bin' # Libraries are generated via a special rule since we have to remove VPATH= # before doing the make. # TARGETS += $(strip $(FMODS:=.mod) extperlmods libs.here combilibs.here $(BINS) $(DEVBINS) $(TASKS) $(CONFIGFILES)) # # Verbose flag # VERBOSE_FLAG = ifeq ($(VERBOSE),yes) VERBOSE_FLAG = "-v" endif # # Fortran compiler # F90 := gfortran FC := gfortran # # Includes # INCS += -I. # # More variables # AR := /usr/bin/ar LN_S := ln -s RANLIB := ranlib # # Down to here we have modified LDLIBS to take into account the # EXTERNALS. Here LIBS_LDLIBS must be the same as LDLIBS. # Make sure you use := and not = here! # LIBS_LDLIBS := $(LDLIBS) # Here configure adds a few extra libraries, but on some machine these # extra libraries must not be given when the shared libraries are # created. # Use this one when creating executables # LDLIBS += -lgfortran -lcfitsio -ldl -lm -L. # # Use this one when creating libraries # LIBS_LDLIBS += # # The include files are determined by looking for the library directories in # all include subdirectories of SAS_PATH. # Make these recursively evaluated variable (= instead of :=) so that they # are only evaluated where needed. # # This adds using namespace std to everything # ifeq ($(STRICTCPP), no) CPPFLAGS += -include $(SAS_DIR)/include/config-std.h endif CPPFLAGS += -imacros $(SAS_DIR)/config.h CPPFLAGS += $(addprefix -I,$(addsuffix /include,$(SASDIRS))) CPPFLAGS += $(addprefix -I,$(shell $(SASBIN)/findinclude $(sort $(USEDLIBS)))) CPPFLAGS += $(INCS) # $(X_CFLAGS) # # The include files are determined by looking for the library directories in # all include subdirectories of SAS_PATH. # F90INCFLAGS += $(addprefix -I,$(addsuffix /include,$(SASDIRS))) F90INCFLAGS += $(addprefix -I,$(shell $(SASBIN)/findinclude $(sort $(USEDLIBS)))) # # Access to header files and modules that are not exported. # ifdef INTERNALS CPPFLAGS += $(addprefix -I$(PKGDIR)/,$(INTERNALS)) F90INCSFLAGS += $(addprefix -I$(PKGDIR)/,$(INTERNALS)) endif LDFLAGS += $(addprefix -L,$(addsuffix /lib,$(SASDIRS))) # # Variables to obtain dependencies # CXXDEPEND = g++ -M $(CPPFLAGS) $(CXXFLAGS) CDEPEND = gcc -M $(CPPFLAGS) $(CFLAGS) F90DEPEND = LANG=C $(SASBIN)/f90depend $(F90INCFLAGS) $(F90FLAGS) # # The default variables that are dump by running 'make infokey' # Add further variables to get info on then # KEYS:=CFLAGS CPPFLAGS CXXFLAGS FFLAGS F90FLAGS LDFLAGS SHARED_LIBS_FLAGS KEYVALS:=${foreach k,${KEYS},"${k}=${${k}}"} # # Define GCCVERS, MAJOR_GCCVERS and MINOR_GCCVERS # These variables might be used in any package subdirectory Makefile # GCCVERS := $(word 3,$(shell gcc --version|grep GCC)) MAJOR_GCCVERS := $(shell gcc --version|grep GCC|awk '{print $$3}'|cut -d. -f1) MINOR_GCCVERS := $(shell gcc --version|grep GCC|awk '{print $$3}'|cut -d. -f2) export GCCVERS MAJOR_GCCVERS MINOR_GCCVERS # # R U L E S # # # - P A T T E R N S # %.cc: %.l $(LEX) -t $< > $(<:.l=.cc) %.cc: %.y $(YACC) -d -o $@ $(@:.cc=.y) mv "$(@:.cc=)".hh "$(@:.cc=)".h %_main.o: %_main.cc $(CXX) -c $(CXXFLAGS) $(CPPFLAGS) $< %.o: %.cc $(CXX) -c $(CXXFLAGS) $(CXXSHAREDFLAGS) $(CPPFLAGS) $< %.o: %.cpp $(CXX) -c $(CXXFLAGS) $(CXXSHAREDFLAGS) $(CPPFLAGS) $< %.o: %.c $(CC) -c $(CFLAGS) $(CXXSHAREDFLAGS) $(CPPFLAGS) $< m_%.cc m_%.cpp: %.h $(MOC) -o $@ $< %.o: %.f90 $(F90) -c $(F90FLAGS) $(F90INCFLAGS) $< %.o: %.f95 $(F90) -c $(F90FLAGS) $(F90INCFLAGS) $< %.o : %.f $(FC) -c $(FFLAGS) $(FINCFLAGS) $< %.prm: %.par $(SASBIN)/paramconv $*.par $@ # # Cancel implicit rules for ".mod" (used by m2c) # %: %.mod %.o: %.mod # # Make a target here as well as in all subdirectories. # The following complexity is because the Bourne shell's # "for" function does not accept an empty list. # %: %.here @if [ -n "$(SUBDIRS)" ]; then \ ARGS="$(SUBDIRS)"; \ for n in $$ARGS; do $(MAKE) -C $$n $@ || exit; done; \ fi # # Automatically generated source files. # # # The final perl tasks (without the .pl extension) are formed by # appending to the taskmain main.pl, the task themselves # # SAS_PERL is defined above from the variable PERL passed by the configure # $(PERLTASKS): $(SAS_DIR)/packages/taskmain/src/main.pl T=$@ ;\ PT=$(SAS_PERL);\ sed "s?-sasperl-?$$PT?g;s/-taskname-/$$T/g; s/-release-/$(RELEASE)/g; s/-version-/$(VERSION)/g; s/-aka-/$(AKA)/g" $(SAS_DIR)/packages/taskmain/src/main.pl > $@ ;\ cat $@.pl >> $@ ;\ chmod +x $@ # Python based SAS tasks are built from their respective .py plus the main.py # from taskmain. They do not need to set the she-bang to variable PYTHON as it is # found from configure because we use the approach to set the she-bang via the # /usr/bin/env shell built-in. $(PYTHONTASKS): $(SAS_DIR)/packages/taskmain/src/main.py T=$@ ;\ sed "s/-taskname-/$$T/g; s/-release-/$(RELEASE)/g; s/-version-/$(VERSION)/g; s/-aka-/$(AKA)/g" $(SAS_DIR)/packages/taskmain/src/main.py > $@ ;\ cat $@.py >> $@ ;\ chmod +x $@ # # The Fortran 95 c++ tasks are formed by appending to the taskmain task_c.cc # the tasks themselves # $(addsuffix _c.cc,$(FTASKS)): $(SAS_DIR)/packages/taskmain/src/task_c.cc T=$(subst _c.cc,,$@) ;\ sed "s/taskname/$$T/g" $(SAS_DIR)/packages/taskmain/src/task_c.cc | sed "s/taskproc/$$T_mod_MP_$$T/g" > $@ # # The C++ tasks are formed by appending to the taskmain task_f.cc # the tasks themselves # $(addsuffix _f.cc,$(CXXTASKS)): $(SAS_DIR)/packages/taskmain/src/task_f.cc T=$(subst _f.cc,,$@) ;\ sed "s/taskname/$$T/g" $(SAS_DIR)/packages/taskmain/src/task_f.cc | sed "s/taskproc/$$T_/g" > $@ # # Creation of task headers # $(TASKHEADERS): $(SAS_DIR)/packages/taskmain/src/main.cc $(SASBIN)/sastaskhdr_gfortran $(*F) $(VERSION) $(PACKAGE) $(RELEASE) > $@ $(SASBIN)/sastaskhimp $(*F) $(VERSION) $(PACKAGE) $(RELEASE) > $(*F)_h_imp.cc $(TASKMODS): $(SAS_DIR)/packages/taskmain/src/task_mod.f90 T=$(subst _f_mod.f90,,$@) ;\ sed "s/taskname/$$T/g" $(SAS_DIR)/packages/taskmain/src/task_mod.f90 > $@ $(TASKMAINS): $(SAS_DIR)/packages/taskmain/src/main.cc T=$(subst _main.cc,,$@) ;\ sed "s/taskname/$$T/g" $(SAS_DIR)/packages/taskmain/src/main.cc | sed "s/VERSION/$(VERSION)/g; s/RELEASE/$(RELEASE)/g; s/PACKAGE/$(PACKAGE)/g" > $@ # # Run the given test and report success or failure. # %_test: % @$(call echon,Testing $* ... ) @$(SASBINDEV)/runtestwrap $* < /dev/null > test.result 2>&1 && \ ( $(ECHO) passed; $(RM) test.result ) || ( $(ECHO) FAILED; cat test.result ) # # The PostScript target is _ps whereas a .ps.gz is made. This way the # documentation is always remade with make doc. This is needed because # there is no proper documentation dependency mechanism. The # dependency assures that the toplevel document is automatically # generated. latex reads from /dev/null to prevent it from hanging if # multiple errors are detected. bibtex is run with a - because it # generates an error if there is no citation in the document. This # could be a bit more sophisticated, other errors are now also not # caught. # # Note: See comments above where the variable PSTARGETS is set. # %_ps: %_tex latex $* < /dev/null > makedoc.log || ( cat makedoc.log ; exit 1 ) -bibtex $* < /dev/null > makedoc.log latex $* < /dev/null > makedoc.log || ( cat makedoc.log ; exit 1 ) latex $* < /dev/null > makedoc.log || ( cat makedoc.log ; exit 1 ) dvips -o $*.ps $* > makedoc.log 2>&1 || ( cat makedoc.log ; exit 1 ) gzip -f $*.ps # The same target that generates the ps.gz produces the .pdf file as well. %.ps.gz: %.tex latex $* < /dev/null > makedoc.log || ( cat makedoc.log ; exit 1 ) -bibtex $* < /dev/null > makedoc.log latex $* < /dev/null > makedoc.log || ( cat makedoc.log ; exit 1 ) latex $* < /dev/null > makedoc.log || ( cat makedoc.log ; exit 1 ) dvips -o $*.ps $* > makedoc.log 2>&1 || ( cat makedoc.log ; exit 1 ) # replced exit 1 by continue here to avoid break before html files and specially labels.pl # is produced, e.g. in cal, which is used by many other packages. dvipdf $* > makedoc.log 2>&1 || ( cat makedoc.log ; continue ) gzip -f $*.ps # # Generate the toplevel LaTeX document that includes the package documentation. # Use a dummy target so that the file is also created when it already existed. # %_tex: sed -e "s/DOC/$*/" -e "s/TYPE/$(RELEASETYPE)/" < \ $(SAS_DIR)/packages/sas/doc/lib/$(TEXFORM).tex | $(SASBIN)/texcombine | \ $(SASBIN)/fixdoc -type=$(RELEASETYPE) $* $(VERSION) $(PACKAGE) $(RELEASE) > $*.tex %.tex: %_description.tex $(SAS_DIR)/packages/sas/doc/lib/*.tex sed -e "s/DOC/$*/" -e "s/TYPE/$(RELEASETYPE)/" < \ $(SAS_DIR)/packages/sas/doc/lib/$(TEXFORM).tex | $(SASBIN)/texcombine | \ $(SASBIN)/fixdoc -type=$(RELEASETYPE) $* $(VERSION) $(PACKAGE) $(RELEASE) > $*.tex # # Provide the relative path to SAS_DIR to latex2html via an environment # variable. # # Some versions of latex2html seem to forget a final # '\n'. This breaks the grep '^Testing' checks, and reports a test # failure. This happens only for packages that have one test. # # It should be: # latex2html output # Testing testname # # But it is: # latex2html outputTesting testname # # Forces the creation of the TeX file because that file is needed to # generate the HTML. # # Modern versions of latex2html use pdflatex instead of latex plus dvi to generate images # from those we want to include in the html document. However, pdflatex does not work. # In order to keep the old system that used latex + dvi instead of pdflatex, we have # included the switch -nouse_pdftex in the latex2html command. %_html: %.tex $(PSTARGETS) SASRELDIR=$(RELATDIR) ;\ export SASRELDIR ;\ latex2html -nouse_pdftex -init_file $(SAS_DIR)/packages/sas/doc/lib/latex2html.init $* > /dev/null $(ECHO) "" mkpkgidx -t . > /dev/null || (rm -f $*/index.pl ; exit 1) pointer=$*/ChangeLog ; \ target=$(RELATDIR)/packages/$(PACKAGE)/ChangeLog ; \ if [ -f $$target -a \( ! -h $$pointer \) ] ; then \ $(LN_S) ../$$target $$pointer ; \ fi %_makedir: @if [ ! -d $* ]; then $(MKDIR) $*; fi # # T A R G E T S # # Targets that make an implicit clobber should not expect to write to # files that will be deleted by the clobber. # This explains the funny file suffixes, and the explicit use of $(RM) # in some of the rules below. # The @grep should be done before the make complete, as some complete # steps require the build/check.txt files. all: $(MAKE) build | tee build.tmp_ @grep "[-+][-+]" build.tmp_ > build.txt $(RM) build.tmp_ $(MAKE) complete $(SASBINDEV)/htmlReport build.txt 2 > build.html @if (`grep -- - build.txt > /dev/null`); then \ $(ECHO) "Build failed"; \ exit 1; \ else \ $(ECHO) "Build succeeded"; \ fi incheck: @$(RM) *.tmp_ @$(MAKE) runincheck | tee check.tmp_ @grep "[-+][-+]" check.tmp_ > check.txt @$(RM) check.tmp_ @$(MAKE) complete @$(SASBINDEV)/htmlReport check.txt 1 > check.html @if (`grep -- - check.txt > /dev/null`); then \ $(ECHO) "Check gave errors"; \ exit 1; \ else \ $(ECHO) "Check succeeded"; \ fi check: @$(RM) *.tmp_ @$(MAKE) runcheck | tee check.tmp_ @grep "[-+][-+]" check.tmp_ > check.txt @$(RM) check.tmp_ @$(MAKE) complete @$(SASBINDEV)/htmlReport check.txt > check.html @if (`grep -- - check.txt > /dev/null`); then \ $(ECHO) "Check gave errors"; \ exit 1; \ else \ $(ECHO) "Check succeeded"; \ fi info: @echo --- Information on the selected variables - @echo @echo Working directory=\"$(PWD)\" @echo REFERDIR=\"$(REFERDIR)\" @echo RELATDIR=\"$(RELATDIR)\" @echo FTASKS=\"$(FTASKS)\" @echo CXXTASKS=\"$(CXXTASKS)\" @echo PERLTASKS=\"$(PERLTASKS)\" @echo PYTHONTASKS=\"$(PYTHONTASKS)\" @echo LIBS=\"$(LIBS)\" @echo COMBILIBS=\"$(COMBILIBS)\" @echo LIBFILES=\"$(LIBFILES)\" @echo COMBILIBFILES=\"$(COMBILIBFILES)\" @echo TARGETS=\"$(TARGETS)\" @echo LINKS=\"$(LINKS)\" @echo CLOBBERFILES=\"$(CLOBBERFILES)\" @echo CLEANFILES=\"$(CLEANFILES)\" @echo CLOBBERDIRS=\"$(CLOBBERDIRS)\" @echo CLEANDIRS=\"$(CLEANDIRS)\" @echo LIBBASES=\"$(LIBBASES)\" @echo TASKS=\"$(TASKS)\" @echo NEEDTASKMAIN=\"$(NEEDTASKMAIN)\" @echo LIBDIR=\"$(LIBDIR)\" @echo LDLIBS=\"$(LDLIBS)\" @echo INTERFACES=\"$(INTERFACES)\" @echo USEDLIBS=\"$(USEDLIBS)\" @echo SHARED=\"$(SHARED)\" @echo RELEASE=\"$(RELEASE)\" @echo VERSION=\"$(VERSION)\" @echo MAJOR_VERSION=\"$(MAJOR_VERSION)\" @echo SO=\"$(SO)\" @echo SO_VERSION=\"$(SO_VERSION)\" @echo SO_FULL_EXT=\"$(SO_FULL_EXT)\" @echo PKGDIR=\"$(PKGDIR)\" @echo PACKAGE=\"$(PACKAGE)\" @echo OPTIMIZATION=\"$(OPTIMIZATION)\" @echo EXTPERLMODS=\"$(EXTPERLMODS)\" @echo EXTPELDIR=\"$(EXTPERLDIR)\" @echo EXTPERLSCRIPT=\"$(EXTPERLSCRIPT)\" # # Show key=val, for all keys specified by variable KEYS (see above) # infokey.here: @for n in ${KEYVALS} ; do echo "$$n" ; done # # To upgrade the parameter files # upgradeparfile.here: upgradeparam # # Provide an empty rule for complete. In the toplevel Makefile it will # depend on some other rules so that operations are performed at the end # of the build. complete: bin.here: $(TARGETS) doc.here: $(DOCTARGETS) ps.here: $(PSTARGETS) html.here: $(HTMLTARGETS) data.here: @if [ -n "$(DATASCRIPTS)" ]; then \ ARGS="$(DATASCRIPTS)"; \ for n in $$ARGS; do \ ./$$n; \ done; \ fi # # Create directories and symbolic links. If INTERFACES is defined, delete old # links in 'include' directory (which would prevent INTERFACES working properly). # links.here: make_dirs check_required_dirs $(LINKS) ifdef INTERFACES @if [ -n "$(strip $(BINS)$(LIBS)$(DEVBINS))" ]; then \ ARGS="$(BINS) $(LIBS) $(DEVBINS)"; \ cd $(INCDIR); \ for n in $$ARGS; \ do (test -h $$n && $(RM) $$n || true); done; \ fi endif check_required_dirs: @result=0 ;\ for d in $(LIBDIR) $(PERLLIBDIR) $(PYTHONLIBDIR) $(PYTHONLIBDISTSDIR) $(PYTHONLIBPYSASDIR) $(INCDIR) $(BINDIR) $(DEVBINDIR) $(CONFIGDIR) $(DOCDIR) $(DATADIR) $(DATADIRTMP) $(ODFDIR) ; do \ if [ ! -d $$d ] ; then\ echo WARNING $$d does not exist. ;\ result=1 ;\ fi ;\ done ;\ if [ $$result -ne 0 ] ; then \ echo ERROR: One of more required directories could not be found. This may prevent some of the symbolic links from being created correctly. This may also mean that you are in a directory that has nothing to do with the SAS, or that SAS_PATH is incorrectly configured. If you are in the right directory, you can create the missing directories by hand. Or type 'make required_dirs'. ;\ exit 1 ;\ fi required_dirs: @for d in $(LIBDIR) $(PERLLIBDIR) $(PYTHONLIBDIR) $(PYTHONLIBDISTSDIR) $(PYTHONLIBPYSASDIR) $(INCDIR) $(BINDIR) $(DEVBINDIR) $(CONFIGDIR) $(DOCDIR) $(DATADIR) $(DATADIRTMP) $(ODFDIR) ; do \ if [ ! -d $$d ] ; then\ echo Creating $$d ;\ mkdir $$d || exit 1;\ fi \ done ;\ echo -n "Setting up Python environment ... " ;\ $(SASBIN)/pyset.py ;\ echo "done." # # Build the libraries with an empty VPATH, since otherwise make will # try to overwrite the library in any of the directories in VPATH. # libs.here: @if [ -n "$(LIBFILES)" ]; then $(MAKE) VPATH= $(LIBFILES); fi combilibs.here: @if [ -n "$(COMBILIBFILES)" ]; then $(MAKE) $(COMBILIBFILES); fi # # Soft links for VERSIONED shared libraries # depending on the platform # ifeq ($(SO),$(SO_FULL_EXT)) # No versions # # libFOO.so -> PackageDir/libFOO.so # $(LIBDIR)/lib%.$(SO): @cd $(LIBDIR) && \ (test -h $(@F) || $(LN_S) ../$(REFERDIR)/$(@F) $(@F)) else # # Versioned libraries # # # On Linux $(SO) = so # # We need two soft links in LIBDIR # # libFOO.so -> libFOO.so.M.m # libFOO.so.M.m -> YourPackageDir/libFOO.so.M.m # ifeq (so,$(SO)) $(LIBDIR)/lib%.$(SO): @cd $(LIBDIR) && \ (test -h $(@F) || $(LN_S) $(@F).$(SO_VERSION) $(@F)) $(LIBDIR)/lib%.$(SO_FULL_EXT): @cd $(LIBDIR) && \ (test -h $(@F) || $(LN_S) ../$(REFERDIR)/$(@F) $(@F)) endif # Mac OS X $(SO) = dylib # # We need two soft links in LIBDIR # # libFOO.dylib -> libFOO.M.m.dylib # LibFOO.M.m.dylib -> YourPackageDir/libFOO.M.m.dylib # # But notice that lib%.$(SO) in LIBDIR matches both libFOO.M.n.dylib and # libFOO.dylib, so we need to reverse the order to find the two following targets # otherwise the second target will never be done # ifeq (dylib,$(SO)) $(LIBDIR)/lib%.$(SO_FULL_EXT): @cd $(LIBDIR) && \ (test -h $(@F) || $(LN_S) ../$(REFERDIR)/$(@F) $(@F)) $(LIBDIR)/lib%.$(SO): @cd $(LIBDIR) && \ (test -h $(@F) || $(LN_S) $(subst .dylib,,$(@F)).$(SO_VERSION).$(SO) $(@F)) endif endif # # Links for static libraries # $(LIBDIR)/lib%.a: @(cd $(LIBDIR); test -h lib$*.a || $(LN_S) ../$(REFERDIR)/lib$*.a .) # # Links for perl modules close to the perl task # $(PERLLIBDIR)/%.pl: @(cd $(PERLLIBDIR); test -h $*.pl || $(LN_S) ../../$(REFERDIR)/$*.pl .) # # Links for python modules close to the python task $(PYTHONLIBDIR)/%.py: @(cd $(PYTHONLIBDIR); test -h $*.py || $(LN_S) ../../$(REFERDIR)/$*.py .) # # Link to directory, when INTERFACES is not defined # $(INCDIR)/%\/: @(cd $(INCDIR); test -h $* || $(LN_S) ../$(REFERDIR) $*) # # Link to individual files, when INTERFACES is defined # $(INCDIR)/%: @(cd $(INCDIR); \ test -h $(notdir $*) || $(LN_S) ../$(REFERDIR)/$(notdir $*) . ) $(DEVBINDIR)/%: @(cd $(DEVBINDIR); test -h $* || $(LN_S) ../../$(REFERDIR)/$* .) $(BINDIR)/%: @(cd $(BINDIR); test -h $* || $(LN_S) ../$(REFERDIR)/$* .) $(CONFIGDIR)/%.par: @(cd $(CONFIGDIR); test -h $*.par || $(LN_S) ../$(REFERDIR)/$*.par .) $(CONFIGDIR)/%: @(cd $(CONFIGDIR); test -h $* || $(LN_S) ../$(REFERDIR)/$* .) # # test ! -r is needed as a compatibility measure for make files that have DOCS = a/a.html # $(DOCDIR)/%.html: @(cd $(DOCDIR); test -h $*.html || test ! -r ../$(REFERDIR)/$*.html || $(LN_S) ../$(REFERDIR)/$*.html .) $(DOCDIR)/%: @(cd $(DOCDIR); test -h $* || $(LN_S) ../$(REFERDIR)/$* .) $(DATADIR)/%: @(cd $(DATADIR); test -h $* || $(LN_S) ../../$(REFERDIR)/$* .) $(PERLLIBDIR)/%: @(cd $(PERLLIBDIR); test -h $* || $(LN_S) ../../$(REFERDIR)/$* .) $(PYTHONLIBDIR)/%.py: @(cd $(PYTHONLIBDIR); test -h $*.py || $(LN_S) ../../$(REFERDIR)/$*.py .) $(ODFDIR)/%: @(cd $(ODFDIR); test -h $* || $(LN_S) ../../$(REFERDIR)/$* .) make_dirs: $(MKDIRS:=_makedir) # # These rules should come after the rules to generate the links. # Use the dependencies ($^) instead of $*_OBJS, since then we can add # the wrappers for task libraries by adding them to the dependencies. # The make depend stage determines the contents of libraries and executables. # # # combilibs rules must come before the normal lib ones. # # filter-out is needed in case the library being built is also in the USEDLIBS line. # $(addprefix lib,$(addsuffix .a,$(COMBILIBS))): $(RM) -fr $(COMBIDIR)$@ && $(MKDIR) $(COMBIDIR)$@ && \ cd $(COMBIDIR)$@ && \ for l in $(subst .$(SO),.a,$^); do $(AR) x $$l ; done && \ $(AR) cur $@ *.o && $(RANLIB) $@ && $(MV) $@ .. $(addprefix lib,$(addsuffix .$(SO_FULL_EXT),$(COMBILIBS))): $(RM) -fr $(COMBIDIR)$@ && $(MKDIR) $(COMBIDIR)$@ && \ cd $(COMBIDIR)$@ && \ for l in $(subst .$(SO),.a,$^); do $(AR) x $$l ; done && \ $(CXX) $(SHARED_LIBS_FLAGS) -o $@ *.o $(addprefix -l,$(filter-out $*,$(USEDLIBS))) $(LIBS_LDLIBS) && $(MV) $@ .. @test $@ = lib$*.$(SO) || ( test -h lib$*.$(SO) || $(LN_S) $@ lib$*.$(SO) ) lib%.a: $(AR) cur $@ $^ $(RANLIB) $@ lib%.$(SO_FULL_EXT): $(CXX) $(SHARED_LIBS_FLAGS) -o $@ $^ $(addprefix -l,$(filter-out $*,$(USEDLIBS))) $(LIBS_LDLIBS) @test $@ = lib$*.$(SO) || ( test -h lib$*.$(SO) || $(LN_S) $@ lib$*.$(SO) ) # # Compile an executable. # Convert any library in the dependencies back to a -l option so that no # absolute path to the library is linked into the executable. # # Here use $+ instead of $^ because we want to preserve duplicates and # preserve their order. # $(BINS) $(DEVBINS) $(TESTBINS) $(NEEDTASKMAIN): $(CXX) $(LDFLAGS) -o $@ $(shell $(SASBIN)/libtominl $+) $(LDLIBS) # # In the two following targets make sure that there is no trailing /. # On RedHat 8.0 rm symlink/ fails (rm thinks it is a directory). But # we use the final / as part of one of the pattern rules, so it cannot # be removed there. So we get rid of it here before invoking rm. # clean.here: @$(RM) $(CLEANFILES:%\/=%) @$(RM) -r $(CLEANDIRS) clobber.here: @$(RM) $(CLEANFILES:%\/=%) $(CLOBBERFILES:%\/=%) @$(RM) -r $(CLEANDIRS) $(CLOBBERDIRS) tests.here: $(TESTBINS) # # Use an intermediate target to enforce doing the tests even if the subdir # test exists. # test: dotest # # run all the tests in this and lower directories, bail out if one # of them failed # dotest: @$(MAKE) runtests | tee test_log @grep FAILED test_log > /dev/null 2>&1 && $(ECHO) "ERROR: one of the tests failed" || exit 0 # # Run all the tests, do not bail out on a failure. Serialize the tests; they # should not run in parallel (some use the same output file). # runtests.here: $(TESTBINS) $(TESTS:=_test) # # Do everything that is needed before make depend can be done. # make_dirs instead of $(MKDIRS) ensures that we can create directories with the # same name as one of the targets (doc, test). # prepare.here: make_dirs $(TASKHEADERS) $(TASKHEADIMPS) $(CXXTASKWRAPPERS) $(TASKMODS) $(FTASKWRAPPERS) $(PERLTASKWRAPPERS) links.here # # Generation of dependencies. # # Its generation is serialized since they are written to the same file # named Make.depends # depend.here: prepare.here @$(ECHO) "# Make.depends" > Make.depends @if [ -n "$(BINS)$(TESTBINS)$(DEVBINS)" ]; then \ ARGS="$(BINS) $(TESTBINS) $(DEVBINS)" ;\ for n in $$ARGS; do $(MAKE) $${n}_BDEPEND || exit; done; \ fi @if [ -n "$(COMBILIBS)" ]; then \ ARGS="$(COMBILIBS)"; \ for n in $$ARGS; do $(MAKE) $${n}_CLDEPEND || exit; done; \ fi @if [ -n "$(CXXTASKS)" ]; then \ ARGS="$(CXXTASKS)"; \ for n in $$ARGS; do $(MAKE) $${n}_TCDEPEND || exit; done; \ fi @if [ -n "$(PERLTASKS)" ]; then \ ARGS="$(PERLTASKS)"; \ for n in $$ARGS; do $(MAKE) $${n}_TPDEPEND || exit; done; \ fi @if [ -n "$(PYTHONTASKS)" ]; then \ ARGS="$(PYTHONTASKS)"; \ for n in $$ARGS; do $(MAKE) $${n}_TPYDEPEND || exit; done; \ fi @if [ -n "$(FTASKS)" ]; then \ ARGS="$(FTASKS)"; \ for n in $$ARGS; do $(MAKE) $${n}_TFDEPEND || exit; done; \ fi @if [ -n "$(LIBS)" ]; then \ ARGS="$(LIBS)"; \ for n in $$ARGS; do $(MAKE) $${n}_LDEPEND || exit; done; \ fi @if [ -n "$(wildcard *.f90)" ]; then \ $(F90DEPEND) *.f90 >> Make.depends; \ fi @if [ -n "$(wildcard *.f95)" ]; then \ $(F90DEPEND) *.f95 >> Make.depends; \ fi @if [ -n "$(wildcard *.c)" ]; then \ $(CDEPEND) *.c >> Make.depends; \ fi @if [ -n "$(wildcard *.cc)" ]; then \ $(CXXDEPEND) *.cc >> Make.depends; \ fi %_BDEPEND: @echo Dependencies for $* @if [ -z "$($*_OBJS)" -a -z "$($*_QOBJS)" ]; then $(ECHO) Missing $*_OBJS or $*_QOBJS for binary $*; exit 1; fi @$(ECHO) "$*: $(addsuffix .o,$($*_OBJS))" >> Make.depends @$(ECHO) "$*: $(addsuffix .o,$($*_QOBJS)) $(addprefix m_,$(addsuffix .o,$($*_QOBJS)))" >> Make.depends @$(ECHO) "$*: $(addprefix -l,$(USEDLIBS))" >> Make.depends %_CLDEPEND: @echo Dependencies for $* @if [ -z "$($*_LIBS)" ]; then $(ECHO) Missing $*_LIBS for combilib $*; exit 1; fi @$(ECHO) "lib$*.a lib$*.$(SO_FULL_EXT): $(addprefix -l,$($*_LIBS))" >> Make.depends %_TFDEPEND: @echo Dependencies for $* @if [ -z "$($*_OBJS)" ]; then $(ECHO) Missing $*_OBJS for Fortran task $*; exit 1; fi @$(ECHO) "$*: $*_main.o -l$*" >> Make.depends @$(ECHO) "$*_c.o: $*_c.cc $*.h" >> Make.depends @$(ECHO) "$*_h_imp.o: $*_h_imp.cc $*.h" >> Make.depends @$(ECHO) "lib$*.a lib$*.$(SO_FULL_EXT): $*_h_imp.o $*_c.o $(addsuffix .o,$($*_OBJS))" >> Make.depends @$(ECHO) "lib$*.a lib$*.$(SO_FULL_EXT): $(addsuffix .o,$($*_QOBJS)) $(addprefix m_,$(addsuffix .o,$($*_QOBJS)))" >> Make.depends @$(ECHO) "$*: $(addprefix -l,$(USEDLIBS))" >> Make.depends %_TCDEPEND: @echo Dependencies for $* @if [ -z "$($*_OBJS)" -a -z "$($*_QOBJS)" ]; then $(ECHO) Missing $*_OBJS or $*_QOBJS for C++ task $*; exit 1; fi @$(ECHO) "$*: $*_main.o -l$*" >> Make.depends @$(ECHO) "$*_h_imp.o: $*_h_imp.cc $*.h" >> Make.depends @$(ECHO) "lib$*.a lib$*.$(SO_FULL_EXT): $*_h_imp.o $*_f_mod.o $*_f.o $(addsuffix .o,$($*_OBJS))" >> Make.depends @$(ECHO) "lib$*.a lib$*.$(SO_FULL_EXT): $(addsuffix .o,$($*_QOBJS)) $(addprefix m_,$(addsuffix .o,$($*_QOBJS)))" >> Make.depends @$(ECHO) "$*: $(addprefix -l,$(USEDLIBS))" >> Make.depends %_TPDEPEND: @echo Dependencies for $* @$(ECHO) "$*: $*.pl $(SAS_DIR)/packages/taskmain/src/main.pl" >> Make.depends %_TPYDEPEND: @echo Dependencies for $* @$(ECHO) "$*: $*.py $(SAS_DIR)/packages/taskmain/src/main.py" >> Make.depends %_LDEPEND: @echo Dependencies for $* @if [ -z "$($*_OBJS)" -a -z "$($*_QOBJS)" ]; then $(ECHO) Missing $*_OBJS or $*_QOBJS for library $*; exit 1; fi @$(ECHO) "lib$*.a lib$*.$(SO_FULL_EXT): $(addsuffix .o,$($*_OBJS))" >> Make.depends @$(ECHO) "lib$*.a lib$*.$(SO_FULL_EXT): $(addsuffix .o,$($*_QOBJS)) $(addprefix m_,$(addsuffix .o,$($*_QOBJS)))" >> Make.depends # # Target to generate a package in the form package-version.tgz, as well as checking/tagging the local git repo if present # dist: @$(RM) *.tmp_ @$(SASBIN)/chkdist || exit 1 @if [ ! -r VERSION ] ; then exit ; fi @if [ -d ../../.git ]; then \ echo Tagging $(PACKAGE)-$(VERSION) in the local git repository; \ git tag $(PACKAGE)-$(VERSION) || \ (echo "If tag already exists, and this is an error, remove it with 'git tag -d $(PACKAGE)-$(VERSION)' and try again." && exit 1); \ fi @( cd ..; find $(PACKAGE) | grep CVS > tmp%; tar cfX - tmp% $(PACKAGE) | gzip > $(PACKAGE)-$(VERSION).tgz; rm tmp% ; echo The distribution can be found in ../$(PACKAGE)-$(VERSION).tgz ) # # Target to make external perl modules required by a perl task. # # This is controlled by means of the EXTPERLMODS variable which # provides the list of external perl modules. # # They must be placed in a subdirectory of the top direcctory # of the package defined in variable EXTPERLDIR. # # The modules are built by means of a specific shell script # which is identified by means of the variable EXTPERLSCRIPT. # .PHONY: extperlmods extperlmods: # If EXTPERLMODS is not null, checks for EXTPERLDIR and EXTPERLSCRIPT ifneq ($(EXTPERLMODS),) ifeq ($(EXTPERLDIR),) @$(ECHO) Undefined EXTPERLDIR variable in $(shell basename $(PWD))/Makefile exit 1 endif ifeq ($(EXTPERLSCRIPT),) @$(ECHO) Undefined EXTPERLSCRIPT variable in $(shell basename $(PWD))/Makefile exit 1 endif ifeq ($(EXTPERLDIR),$(shell basename $(PWD))) @(/bin/bash ./$(EXTPERLSCRIPT)) endif endif # # Target to provide a mechanism of package uploading, as well as # pushing changes from a local git repo to the main repo. # # This target depends on commit in case anything else needs to be # committed. # # We do a git check first as part of the "dist" target, so that if it # fails for some reason it needs to be resolved before the package # upload. Note that before we can push the changes to the main # repository, we first need to do a "git pull". In case there are # changes to other unrelated packages, we do a "git stash" before the # pull followed by "git stash pop" after the push to revert those # changes. However, if the "git pull" brought in some changes to one # of these locally changed packages, you may get a merge conflict that # needs to be resolved when the stash is re-applied. The # re-application of the stash will not be fatal so that uploadsas may # continue. Go and fix the files that "git stash pop" complained # about, and then run "git stash drop" to remove the broken stash from # the internal stack. Of course, the initial "git pull" may also # reveal conflicts if two developers are working on the same package # at the same time. This conflict will be fatal, requiring a # resolution before things can continue. # # Use SASBIN instead of SASBINDEV so one can upload package sas itself # upload: commit dist @if [ -d ../../.git ]; then \ branch=`git rev-parse --abbrev-ref HEAD`; \ if [ "$$branch" != "master" ]; then \ echo "Error: working copy of git repository is on branch $$branch instead of master!"; \ exit 1; \ fi; \ istagged=`git show-ref $(PACKAGE)-$(VERSION)`; \ if [ -z "$$istagged" ]; then \ echo "ERROR: somehow $(PACKAGE)-$(VERSION) was not tagged during make dist"; \ exit 1; \ fi; \ echo ; \ echo "*** Pushing package changes to the main git repository ***"; \ echo ; \ pkg=`basename $$PWD`; \ pkgversion=`cat VERSION`;\ needstash=`git status --porcelain -uno | grep -v "\/$$pkg\/"`; \ if [ -n "$$needstash" ]; then \ echo " - Stash unrelated changes -"; \ git stash save "Stashed to upload $$pkg-$$pkgversion" || exit 1; \ fi; \ echo " - Pull changes from remote -"; \ git pull || exit 1; \ echo " - Push our updates to remote -"; \ git push || exit 1; \ echo " - Push tags to remote -"; \ git push --tags || exit 1; \ if [ -n "$$needstash" ]; then \ echo " - Pop stashed changes -"; \ git stash pop || ( echo "git stash pop failed. Please review your git status" ; exit 1) \ fi; \ fi @$(SASBIN)/uploadsas ../$(PACKAGE)-$(VERSION).tgz # # Target to provide a mechanism to commit to the git repo. # # Since moving to git from CVS, the main difference is that changes # are only committed to the local repository. The synchronization with # the remote master is part of the "upload" target. Tagging is now # part of the "dist" target. # # Commits are made to the local master branch. By default only modified # files in the current package are committed. Files that weren't previously # in the index need to be added with "git add". commit: @if [ ! -d ../../.git ]; then \ echo Not a git repo, nothing to do. ; \ else \ branch=`git rev-parse --abbrev-ref HEAD` ; \ if [ "$$branch" != "master" ]; then \ echo "ERROR: currently working on branch $$branch. Fix this." ;\ echo "ERROR: Switch back to master and merge if needed:" ;\ echo "ERROR: $$ git checkout master; git merge $$branch" ;\ exit 1 ; \ fi ; \ untracked=`git ls-files --others --exclude-standard .` ; \ if [ "$$untracked" != "" ]; then \ echo "ERROR: package contains untracked files: ";\ echo "$$untracked" ;\ echo "ERROR: Fix this using: ";\ echo "ERROR: $$ git add [all new files/directories]" ;\ echo "ERROR: or delete them (e.g., make clobber) ";\ exit 1 ; \ fi ; \ docommits=`git status --porcelain .` ; \ if [ "$$docommits" != "" ]; then \ echo "Going to commit your changes ..."; \ pkg=`basename $$PWD` ; \ git add -u .; \ pkgversion=`cat VERSION`; \ git commit -m "$$pkg-$$pkgversion: Committed through make" || exit 1; \ else \ echo "No changes to commit." ; \ fi; \ fi # # Deprecated: old target to generate a branch in CVS # branch: @echo '--- DEPRECATED ---' @echo 'The branch target is no longer used since moving to git from cvs.' # # A target to see the list of packages to be built # pkglist: @$(ECHO) $(PKGLIST) # # The following targets share a number of functions # OK := + ERR := - buildlog := build_log buildlog2 := $(buildlog)_second check_head = echo [depchk][chkdist][mkdep][bin][fulldoc][mktests][hastests][tests][retests] incheck_head = echo [depchk][chkdist][mkdep][bin][psdoc][mktests][hastests][tests][retests] build_head = echo [depchk][chkdist][mkdep][bin][fulldoc] date_stamp = $(call echon,"$(PACKAGE) $(VERSION) `date +%H:%M` ") dependency_check = $(SASBIN)/depchk 1> $(buildlog) 2>&1 && $(call echon,$(OK)) || $(call echon,$(ERR)) distribution_check = $(SASBIN)/chkdist $(1) 1>> $(buildlog) 2>&1 && $(call echon,$(OK)) || $(call echon,$(ERR)) make_depend = $(MAKE) depend 1>> $(buildlog) 2>&1 && $(call echon,$(OK)) || $(call echon,$(ERR)) make_bin = $(MAKE) bin 1>> $(buildlog) 2>&1 && $(call echon,$(OK)) || $(call echon,$(ERR)) make_ps = $(MAKE) ps 1>> $(buildlog) 2>&1 && $(call echon,$(OK)) || $(call echon,$(ERR)) make_tests = $(MAKE) tests 1>> $(buildlog) 2>&1 && $(call echon,$(OK)) || $(call echon,$(ERR)) make_doc = $(MAKE) doc 1>> $(buildlog) 2>&1 && $(call echon,$(OK)) || $(call echon,$(ERR)) make_test_g = $(MAKE) test 1>> $(1) 2>&1 make_test = $(call make_test_g,$(buildlog)) make_second_test = $(call make_test_g,$(buildlog2)) make_clean = $(MAKE) clean 1>> $(buildlog) 2>&1 make_clobber = $(MAKE) clobber 1>> $(buildlog) 2>&1 has_tests = grep '^Testing' $(buildlog) > /dev/null 2>&1 && $(call echon,$(OK)) || $(call echon,$(ERR)) has_failed_tests_g = grep FAILED $(1) > /dev/null 2>&1 && $(call echon,$(ERR)) || $(call echon,$(OK)) has_failed_tests = $(call has_failed_tests_g,$(buildlog)) has_failed_second_tests = $(call has_failed_tests_g,$(buildlog2)) second_test = if [ -r $(SAS_DIR)/second.test ] ; then . $(SAS_DIR)/second.test 1>> $(buildlog) 2>&1 ; $(RM) -f $(buildlog2) ;\ $(call make_second_test) ; $(call has_failed_second_tests) ; else echo X ; fi # # Target to produce incremental builds where no clean or clobber is made. # runincheck.here: @if [ -r DEPEND -a -r VERSION ] ; then \ $(call incheck_head) ;\ $(call date_stamp) ;\ $(call dependency_check) ;\ $(call distribution_check,inc) ;\ $(call make_depend) ;\ $(call make_bin) ;\ if [ $(FULLDOC) = "yes" ] ; then \ $(call make_doc) ;\ else \ $(call make_ps) ;\ fi ;\ $(call make_tests) ;\ if [ $(RUNTESTS) = "yes" ] ; then \ $(call make_test) ;\ $(call has_tests) ;\ $(call has_failed_tests) ;\ $(call second_test) ;\ else \ echo "XXX" ;\ fi \ else \ $(MAKE) make_dirs links.here ;\ touch Make.depends ;\ fi @echo # # The standard check target to build each package # runcheck.here: @if [ -r DEPEND -a -r VERSION ] ; then \ $(call check_head) ;\ $(call date_stamp) ;\ $(call make_clobber) ;\ $(call dependency_check) ;\ $(call distribution_check) ;\ $(call make_depend) ;\ $(call make_bin) ;\ $(call make_doc) ;\ $(call make_tests) ;\ $(call make_test) ;\ $(call has_tests) ;\ $(call has_failed_tests) ;\ $(call second_test) ;\ $(call make_clean) ;\ else \ $(MAKE) make_dirs links.here ;\ touch Make.depends ;\ fi @echo # # Build without tests # build.here: @if [ -r DEPEND -a -r VERSION ] ; then \ $(call build_head) ;\ $(call date_stamp) ;\ $(call make_clobber) ;\ $(call dependency_check) ;\ $(call distribution_check) ;\ $(call make_depend) ;\ $(call make_bin) ;\ $(call make_doc) ;\ $(call make_clean) ;\ else \ $(MAKE) make_dirs links.here ;\ touch Make.depends ;\ fi @echo # # Target to check every package # distcheck.here: @if [ -r DEPEND -a -r VERSION ] ; then \ $(SASBIN)/chkdist ;\ else \ $(ECHO) You can do this only in the top-level package directory ;\ fi # # Target to check cross package dependencies # depcheck.here: @if [ -r DEPEND -a -r VERSION ] ; then \ $(SASBIN)/depchk ;\ else \ $(ECHO) You can do this only in the top-level package directory ;\ fi # # Target to ensure Make.depends is included # ifeq ("$(wildcard Make.depends)","") bin tests test: @$(ECHO) Missing Make.depends - first do \'make depend\' @exit 1 else include Make.depends endif # # After all is done, check some things and replace some # rules with error messages if something is wrong. # # Checks whether SAS_DIR and SAS_PATH are OK and config.h has been # produced. # ifeq ("$(SAS_DIR)","") depend bin tests test doc all check incheck: @$(ECHO) "SAS_DIR is undefined. First source sas-setup.[c]sh" @exit 1 else ifeq ("$(SASDIRS)","") depend bin tests test doc all check incheck: @$(ECHO) "SAS_PATH is not defined. First source sas-setup.[c]sh" @exit 1 else ifeq ("$(TOPDIR)","") depend bin tests test doc all check incheck: @$(ECHO) "The current directory is not a subdirectory of SAS_PATH." @$(ECHO) "You should first source sas-setup.[c]sh. If you already did so," @$(ECHO) "then set SAS_PATH to include all paths that contain SAS packages" @$(ECHO) "and source sas-setup.[c]sh again." @$(ECHO) " pwd=$(PWD)" @$(ECHO) " SAS_DIR=$(SAS_DIR)" @$(ECHO) " SAS_PATH=$(SAS_PATH)" @exit 1 else ifeq ("$(wildcard $(SAS_DIR)/config.h)","") depend bin tests test doc all check incheck: @$(ECHO) Missing config.h - first run ./configure in $$SAS_DIR @exit 1 endif endif endif endif