Compiling SaC programs using the generic Makefiles

After downloading the sac repository you should set up the environment variable SACBASE to point to the top level directory of the repository. This enables all subdirectories to find the generic makefiles located in the subdirectory named Makefiles. With these you can call 'make' in any subdirectory of the repository. This will build all executables within the corresponding file-tree on and below the directory it is called at.

In case something goes wrong, here some possible sources of problems:

  • If you get an error message such as

Makefile:41: /Makefiles/Makefile_template.prg: No such file or directory
make: *** No rule to make target `/Makefiles/Makefile_template.prg'.  Stop.
you either forgot to set and export SACBASE or you set it to the wrong path. Whatever you set it to, it expects the file Makefile_template.prg to be found in $(SACBASE)/Makefiles/.

  • If your Makefiles fail for another reason, the next best place to check is the file $(SACBASE)/Makefiles/Makefile.Config. It contains the setup variables that are possibly specific to your system. Please do make adjustments as seen necessary.
  • If your makefiles still fail, you may have to look into the details below on customising your Makefile or on understanding the generic Makefiles.

Adding new sac-files/directories

If you add a new sac source file into an existing directory, in principle, nothing needs to be done. The local Makefile will just pick up the target and build the corresponding executable. If you want a multi-threaded version to be built as well, you should make sure that the variable MAKE_MT_ALSO is defined in the local Makefile. If you want the new file to be excluded from make in general, you should put the source file name (with its suffix) into the make variable EXCLUDE_FILES, if you want to exclude it from building the multi-threaded version only, add the filename to EXCLUDE_FILES_FOR_MT.

Please be Aware

  • If your file depends on a module or a class that is not in the standard library, you need to ensure the compiler will find that library, either through sac2crc, SAC2CFLAGS, or within $(LIBTARGETDIR).
  • If the module or class is locally available and you want make to be aware of that dependency you have to provide that dependency manually. For example you could add a line such as
    mandelbrot_simple: seq/libFractal_tier1Mod$(SHARED_LIB_EXT)
    Note here, that $(LIBTARGETDIR)/host/ have to be omited.

If you add a new directory, you want to literally copy $(SACBASE)/Makefiles/Makefile_template.prg as Makefile into your new directory. You then un-comment the include of $(SACBASE)/Makefiles/Makefile_template.prg and you elide all the includes that follow. Finally, you want to make sure that the Makefile in the parent directory is extended by the new directory name within its variable SUBDIRS.

Most of the customization is self-evident when looking at $(SACBASE)/Makefiles/Makefile_template.prg:

#######################################################################################
#
# Makefile template for programming
# =================================
# This template is made for all those directories where .sac-files
# are to be compiled only.
#
# The easiest way to use it is to copy the next few lines into a file
# "Makefile" and to adjust the parameters as needed:
#
#######################################################################################
#
# General Setup:
#
ifndef SAC2CFLAGS
SAC2CFLAGS = -O3 -check tb
endif
 
#
# Setup for Makefile.standard:
#
# EXCLUDE_FILES               = error.sac
# EXCLUDE_FILES_FOR_MT        = error.sac
# MAKE_MT_ALSO                = yes
# TARGETDIR                   = .
# LIBTARGETDIR                = .
# INCTARGETDIR                = .
# LIBSRCDIR                   = .
# SUBDIRS                     =
 
#
# Setup for Makefile.versions:
#
# VERSDIR                     = .
 
#
# Setup for Makefile.check:
#
# CHECKLOGFILE                = $(HOME)/sac/CHECKLOG
# CHECKDIR                    = .checkdir
# RT_FLAGS                    =
# INPSDIR                     = .
#
#######################################################################################
#
# include $(SACBASE)/Makefiles/Makefile_template.prg
#
#######################################################################################

You can modify all parameters of the generic Makefile in your local copy of the template:

variable effect remark
SAC2CFLAGS compiler flags to be used as default values bear in mind that SAC2C can come from a recursive call of make
EXCLUDE_FILES files/modules/classes not to be compiled at all
TARGETDIR path from src to executables
LIBTARGETDIR path from src to where compiled sac modules/classes should go bear in mind that you will find the actual libraries at $(LIBTARGETDIR)/tree/host and $(LIBTARGETDIR)/host/<target>/ where <target> is seq or mt-pth or similar!
SUBDIRS directories to propagate make into
MAKE_MT_ALSO set this one to automatically build mt-versions in addition to the sequential ones
EXCLUDE_FILES_FOR_MT files/modules/classes not to be compiled when building the mt_pth versions
VERSDIR where to expect version files see description below :-)

Sometimes, you want to build multiple versions with varying compiler parameters. This can be achieved easily by providing a version file.

Assuming you have a file foo.sac which you want to compile with various settings. All you need to do to achieve that, you add a file foo.vers in your $(VERSDIR). That file should contain lines of the form <suffix> : <sac2c-options> For example, it could be

syshmgr : -noPHM -noWLUR -DMY_FLAG
mt      : -maxlur 20 -target mt_pth
        : -maxlur 20
Such a setup would not only define a new target foo_sysshmgr but it would also override the standard flag settings for the sequential version and for the multi-threaded version. So in total, it would call sac2c three times:

  • sac2c -noPHM -noWLUR -DMY_FLAG -o foo_sysshmgr foo.sac
  • sac2c -maxlur 20 -target mt_pth -o foo_mt foo.sac
  • sac2c -maxlur 20 -o foo foo.sac

Understanding the generic Makefiles

For the time being (Nov 2016), our template Makefile Makefile_template.prg includes two generic Makefiles, Makefile.standard and Makefile.versions.

Makefile.standard contains the target detection mechanism as well as the basic pattern based build rules for sac-files/ modules and classes. It also provides the basic MAKE_MT_ALSO support, the subdirectory traversal support, as well as the generic clean targets.

Makefile.vers provides the support for version files to customise the creation of multiple executables from a single source file.