1#! /bin/sh
2### ##########################################################################
3### MALOC = < Minimal Abstraction Layer for Object-oriented C >
4### Copyright (C) 1994-- Michael Holst
5###
6### This library is free software; you can redistribute it and/or
7### modify it under the terms of the GNU Lesser General Public
8### License as published by the Free Software Foundation; either
9### version 2.1 of the License, or (at your option) any later version.
10###
11### This library is distributed in the hope that it will be useful,
12### but WITHOUT ANY WARRANTY; without even the implied warranty of
13### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14### Lesser General Public License for more details.
15###
16### You should have received a copy of the GNU Lesser General Public
17### License along with this library; if not, write to the Free Software
18### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19###
20### rcsid="$Id: mk,v 1.2 2010/08/09 19:02:08 fetk Exp $"
21### ##########################################################################
22
23##############################################################################
24# Purpose: Master mk script for managing the code MC.
25#
26# Notes:
27#
28# (1) The following UNIX tools need to be present for this script to
29#     function correctly:
30#
31#         - sh (a bourne-compatible shell with an implementation of functions)
32#         - pwd (a builtin or utility to identify the current directory)
33#         - sed (the standard stream editor)
34#         - awk (the standard awkward unix tool)
35#         - make (a standard unix make utility with no required extensions)
36#         - cc (an ANSI C-Compiler, employing an ANSI C-Preprocessor)
37#
38#     The "tgz" option also requires:
39#
40#         - touch (a standard unix file utility)
41#         - tar (the standard unix tape archive utility)
42#         - gzip (the GNU Project's compress/decompress utility)
43#
44# (2) In order to use the auto-config option, the following environment
45#     variable is assumed to be pre-defined by the shell (or the user):
46#
47#         - OSTYPE (Linux, IRIX, IRIX64, NeXT, etc)
48#
49#     I rely on the OSTYPE environment variable rather than some UNIX
50#     utility like "uname" to determine the OS and hardware because
51#     uname and related utilities does not exist on some UNIX platforms
52#     (e.g., NeXT).  OSTYPE is pre-defined by bash, tcsh, etc, so if you
53#     use a modern shell, this should just work for you.  If not, you
54#     will need to define OSTYPE yourself, or simply use the manual
55#     configuration option.
56#
57# (3) If your bourne-compatible shell doesn't support functions, then you
58#     can't build MC using this tool.  Your best options are (1) install
59#     "bash" (the "Bourne Again SHell", the GNU Project's bourne-compatible
60#     shell, implementing a superset of the standard Bourne shell), or
61#     (2) install "ksh" (the "Korn shell").  Both of these powerful shells
62#     are available for free on the internet, and can be installed on nearly
63#     any platform (UNIX, WindowsXX, OS/2, BeOS, NeXT, ...).
64#
65# Author:  Michael Holst
66##############################################################################
67
68##############################################################################
69# Required UNIX support tools for this shell script
70##############################################################################
71
72# Make environment
73SH="sh"
74PWD="pwd"
75SED="sed"
76AWK="awk"
77MAKE="make"
78
79# Extended tgz make environment
80TOUCH="touch"
81TAR="tar"
82GZIP="gzip"
83
84# Make arguments (PARAMAKE may be inherited from the shell)
85MK_MAKARG="-s ${PARAMAKE}"
86
87##############################################################################
88# Routine: getMkLibs()
89# Purpose: Define the list of libraries to build.
90#          Note that things will be built following the list order.
91##############################################################################
92getMkLibs() {
93    MK_LIBS="ef vnm glw vor vblas vslu vgl vto vgm vmc bin" ;
94}
95
96##############################################################################
97# Routine: make_ef()
98# Purpose: Build the ElectricFence library "libef.a"
99##############################################################################
100libs_ef() { LIBDIRS="src/ef tst/ef" ; }
101make_ef() {
102    CMD="$1"
103    ARG="$2"
104    if [ "${CMD}" = "killMakefile" ]; then
105        exec_lib "ef" "${CMD}" "${ARG}"
106    elif [ "${MC_EF}" = "yes" ]; then
107        exec_lib "ef" "${CMD}" "${ARG}"
108    fi
109}
110
111##############################################################################
112# Routine: make_glw()
113# Purpose: Build the OpenGL library "libGLw.a"
114##############################################################################
115libs_glw() { LIBDIRS="src/glw tst/glw" ; }
116make_glw() {
117    CMD="$1"
118    ARG="$2"
119    if [ "${CMD}" = "killMakefile" ]; then
120        exec_lib "glw" "${CMD}" "${ARG}"
121    elif [ ! "${XLDL}" = "" ]; then
122        exec_lib "glw" "${CMD}" "${ARG}"
123    fi
124}
125
126##############################################################################
127# Routine: make_vblas()
128# Purpose: Build the MC library "libvblas.a"
129##############################################################################
130libs_vblas() { LIBDIRS="src/vblas tst/vblas" ; }
131make_vblas() {
132    CMD="$1"
133    ARG="$2"
134    exec_lib "vblas" "${CMD}" "${ARG}" ;
135}
136
137##############################################################################
138# Routine: make_vslu()
139# Purpose: Build the MC library "libvslu.a"
140##############################################################################
141libs_vslu() { LIBDIRS="src/vslu tst/vslu" ; }
142make_vslu() {
143    CMD="$1"
144    ARG="$2"
145    exec_lib "vslu" "${CMD}" "${ARG}" ;
146}
147
148##############################################################################
149# Routine: make_vnm()
150# Purpose: Build the MC library "libvnm.a"
151##############################################################################
152libs_vnm() { LIBDIRS="src/vnm tst/vnm" ; }
153make_vnm() {
154    CMD="$1"
155    ARG="$2"
156    exec_lib "vnm" "${CMD}" "${ARG}" ;
157}
158
159##############################################################################
160# Routine: make_vor()
161# Purpose: Build the MC library "libvor.a"
162##############################################################################
163libs_vor() { LIBDIRS="src/vor tst/vor" ; }
164make_vor() {
165    CMD="$1"
166    ARG="$2"
167    exec_lib "vor" "${CMD}" "${ARG}" ;
168}
169
170##############################################################################
171# Routine: make_vto()
172# Purpose: Build the MC library "libvto.a"
173##############################################################################
174libs_vto() { LIBDIRS="src/vto tst/vto" ; }
175make_vto() {
176    CMD="$1"
177    ARG="$2"
178    exec_lib "vto" "${CMD}" "${ARG}" ;
179}
180
181##############################################################################
182# Routine: make_vgl()
183# Purpose: Build the MC library "libvgl.a"
184##############################################################################
185libs_vgl() { LIBDIRS="src/vgl tst/vgl" ; }
186make_vgl() {
187    CMD="$1"
188    ARG="$2"
189    if [ "${CMD}" = "killMakefile" ]; then
190        exec_lib "vgl" "${CMD}" "${ARG}"
191    elif [ "${MC_GL}" = "yes" ]; then
192        exec_lib "vgl" "${CMD}" "${ARG}"
193    fi
194}
195
196##############################################################################
197# Routine: make_vgm()
198# Purpose: Build the MC library "libvgm.a"
199##############################################################################
200libs_vgm() { LIBDIRS="src/vgm tst/vgm" ; }
201make_vgm() {
202    CMD="$1"
203    ARG="$2"
204    exec_lib "vgm" "${CMD}" "${ARG}" ;
205}
206
207##############################################################################
208# Routine: make_vmc()
209# Purpose: Build the MC library "libvmc.a"
210##############################################################################
211libs_vmc() { LIBDIRS="src/vmc tst/vmc" ; }
212make_vmc() {
213    CMD="$1"
214    ARG="$2"
215    exec_lib "vmc" "${CMD}" "${ARG}" ;
216}
217
218##############################################################################
219# Routine: make_bin()
220# Purpose: Build the MC work binaries.
221##############################################################################
222libs_bin() { LIBDIRS="work/bin" ; }
223make_bin() {
224    CMD="$1"
225    ARG="$2"
226    exec_lib "bin" "${CMD}" "${ARG}" ;
227}
228
229##############################################################################
230# Routine: exec_lib()
231# Purpose: Execute command with argument in directories ${LIBDIRS}.
232#          The first argument represents a library function name to use.
233#          (This function name then defines LIBDIR for use.)
234#          The second argument represents the command to execute.
235#          The third argument represents the arguments for the command.
236##############################################################################
237exec_lib() {
238    MI_LIB="$1"
239    MI_CMD="$2"
240    MI_ARG="$3"
241    "libs_${MI_LIB}"
242    for thelib in ${LIBDIRS}; do
243        "${MI_CMD}" "${thelib}" "${MI_ARG}"
244    done
245}
246
247##############################################################################
248# Routine: printMenu()
249# Purpose: Generate and print short "usage" menu.
250##############################################################################
251printMenu() {
252    echo "${PR}"
253    echo "${PR}        ${MK_NAME} -- MaKe Utility"\
254                       "for Configuring and Building MC."
255    echo "${PR}"
256    echo "${PR} Usage: ./${MK_NAME}                "\
257                       " (Print this info but take no action)"
258    echo "${PR}        ./${MK_NAME} go     [OS]    "\
259                       " (Do: config->clean->dep->build     )"
260    echo "${PR}        ./${MK_NAME} config [OS]    "\
261                       " (Configure the package             )"
262    echo "${PR}        ./${MK_NAME} clean  [OS]    "\
263                       " (rm -f *.o                         )"
264    echo "${PR}        ./${MK_NAME} dep    [OS]    "\
265                       " (makedepend                        )"
266    echo "${PR}        ./${MK_NAME} build  [OS]    "\
267                       " (Build the package                 )"
268    echo "${PR}        ./${MK_NAME} brkdep [OS]    "\
269                       " (breakdepend                       )"
270    echo "${PR}        ./${MK_NAME} rclean [OS|all]"\
271                       " (Total cleanup of OS or of all     )"
272    echo "${PR}        ./${MK_NAME} tgz            "\
273                       " (Make tgz file after doing rclean  )"
274    echo "${PR}        ./${MK_NAME} info           "\
275                       " (Print additional usage information)"
276    echo "${PR}"
277}
278
279##############################################################################
280# Routine: printInfo()
281# Purpose: Generate and print "usage" menu.
282##############################################################################
283printInfo() {
284    echo "${PR}"
285    echo "${PR} Info:  If you do not supply the optional OS argument,"\
286                       "${MK_NAME} tries"
287    echo "${PR}        to determine your platform by looking at the OSTYPE    "
288    echo "${PR}        environment variable (predefined by most UNIX shells). "
289    echo "${PR}        You can influence this choice by resetting the OSTYPE  "
290    echo "${PR}        variable yourself, or by giving the OS argument.       "
291    echo "${PR}"
292    echo "${PR}        ${MK_NAME} then looks for a config file in"\
293                       "<mc/cnf/platform>.  "
294    echo "${PR}        If none is found, ${MK_NAME} uses a generic UNIX/X"\
295                       "config file."
296    echo "${PR}        You can add a new platform by copying the generic file "
297    echo "${PR}        to your new (uniquely named) file in the directory     "
298    echo "${PR}        <mc/cnf/platform>, and editing the file as needed.  "
299    echo "${PR}"
300    echo "${PR} Config files currently in <mc/cnf/platform> for selecting OS: "
301    echo "${PR}"
302    PLATFORMS=`ls -1 ${MC_CONFIG}/platform \
303             | ${SED} -e "s./..g" | ${SED} -e "s.CVS..g"`;
304    for platform in ${PLATFORMS}; do
305        . ${MC_CONFIG}/platform/${platform}
306        echo "${PR}        ${platform}"\
307             "   (${PLATFORM}, EF=${EFENCE}, OPENGL=${OPENGL})"
308    done
309    echo "${PR}"
310}
311
312##############################################################################
313# Routine: getConfig()
314# Purpose: Do an auto- or manual-configuration.
315#          If no arguments given, try an auto-configuration is based on the
316#          OSTYPE environment variable.
317#          If one argument is given, try a manual configuration based on
318#          that argument.
319#          After this routine exits, the platform is at least well-defined.
320##############################################################################
321getConfig() {
322
323    # Auto configuration
324    if [ $# -eq 0 ]; then
325        MC_OS=${OSTYPE}
326        MYOSKEY="OSTYPE"
327
328    # Manual configuration
329    elif [ $# -eq 1 ]; then
330        MC_OS=$1
331        MYOSKEY="OS"
332    fi
333
334    # Check for a valid platform
335    if [ -f "${MC_CONFIG}/platform/${MC_OS}" ]; then
336        echo "${PR} Platform <${MC_OS}> WAS found from <${MYOSKEY}>."
337    else
338        # Attempt to map MC_OS to more canonical names
339        case ${MC_OS} in
340            NeXT*)        MC_OS="next" ;;
341            next*)        MC_OS="next" ;;
342            Rhapsody*)    MC_OS="rhapsody" ;;
343            rhapsody*)    MC_OS="rhapsody" ;;
344            Solaris*)     MC_OS="sunos" ;;
345            solaris*)     MC_OS="sunos" ;;
346            SunOS*)       MC_OS="sunos" ;;
347            sunos*)       MC_OS="sunos" ;;
348            *BSD)         MC_OS="bsd" ;;
349            *bsd)         MC_OS="bsd" ;;
350            Linux)        MC_OS="linux" ;;
351            linux)        MC_OS="linux" ;;
352            IRIX)         MC_OS="irix" ;;
353            Irix)         MC_OS="irix" ;;
354            irix)         MC_OS="irix" ;;
355            IRIX64)       MC_OS="irix64" ;;
356            Irix64)       MC_OS="irix64" ;;
357            irix64)       MC_OS="irix64" ;;
358            Irix6)        MC_OS="irix" ;;
359            irix6)        MC_OS="irix" ;;
360            osf*)         MC_OS="osf1" ;;
361            OSF*)         MC_OS="osf1" ;;
362        esac
363        if [ -f "${MC_CONFIG}/platform/${MC_OS}" ]; then
364            echo "${PR} Platform <${MC_OS}> WAS found from <${MYOSKEY}>."
365        else
366            echo "${PR} Platform <${MC_OS}> WAS NOT found from <${MYOSKEY}>. "\
367                  "Using <generic>."
368            MC_OS="generic"
369        fi
370    fi
371
372    # Finally, read in the correct config file
373    . ${MC_CONFIG}/platform/${MC_OS}
374    MC_PL="${PLATFORM}"
375    MC_EF="${EFENCE}"
376    MC_GL="${OPENGL}"
377
378    # Define the library path (now that MC_OS is defined)
379    MC_LIB="${MC_ROOT}/lib/${MC_OS}"
380}
381
382##############################################################################
383# Routine: genConfig()
384# Purpose: Given a valid configuration, generate all of the makefiles.
385#          We ASSUME that getConfig() has already been called, so that the
386#          appropriate platform file has already been read in, and the
387#          following variables (among others) are already well-defined:
388#
389#              MC_OS, MC_PL, MC_EF, MC_GL, MC_LIB
390#
391#          After this routine exits, the platform is configured and ready
392#          to clean/dep/build/etc.
393##############################################################################
394genConfig() {
395    # Read in the current (assumed valid) configuration file
396    echo "${PR} Configuring with <${MC_OS}> platform config file."
397    echo "${PR} Platform is  = <${MC_PL}>"
398    echo "${PR} EF libraries = <${MC_EF}>"
399    echo "${PR} GL libraries = <${MC_GL}>"
400
401    # Generate the premake.${MC_OS} file
402    echo "# DO NOT EDIT -- automatically built from config file <${MC_OS}>" \
403                                      > ${MC_CONFIG}/premake.${MC_OS}
404    echo ""                          >> ${MC_CONFIG}/premake.${MC_OS}
405    echo "    PLATFORM=${PLATFORM}"  >> ${MC_CONFIG}/premake.${MC_OS}
406    echo ""                          >> ${MC_CONFIG}/premake.${MC_OS}
407    echo "       MC_OS=${MC_OS}"     >> ${MC_CONFIG}/premake.${MC_OS}
408    echo "     MC_ROOT=${MC_ROOT}"   >> ${MC_CONFIG}/premake.${MC_OS}
409    echo "    MC_TOOLS=${MC_TOOLS}"  >> ${MC_CONFIG}/premake.${MC_OS}
410    echo "   MC_CONFIG=${MC_CONFIG}" >> ${MC_CONFIG}/premake.${MC_OS}
411    echo "      MC_BIN=${MC_BIN}"    >> ${MC_CONFIG}/premake.${MC_OS}
412    echo "      MC_INC=${MC_INC}"    >> ${MC_CONFIG}/premake.${MC_OS}
413    echo "      MC_LIB=${MC_LIB}"    >> ${MC_CONFIG}/premake.${MC_OS}
414    echo ""                          >> ${MC_CONFIG}/premake.${MC_OS}
415    echo "    CPPFLAGS=${CPPFLAGS}"  >> ${MC_CONFIG}/premake.${MC_OS}
416    echo "          CC=${CC}"        >> ${MC_CONFIG}/premake.${MC_OS}
417    echo "          FC=${FC}"        >> ${MC_CONFIG}/premake.${MC_OS}
418    echo "          PC=${PC}"        >> ${MC_CONFIG}/premake.${MC_OS}
419    echo "      CFLAGS=${CFLAGS}"    >> ${MC_CONFIG}/premake.${MC_OS}
420    echo "      FFLAGS=${FFLAGS}"    >> ${MC_CONFIG}/premake.${MC_OS}
421    echo "      PFLAGS=${PFLAGS}"    >> ${MC_CONFIG}/premake.${MC_OS}
422    echo "       CWARN=${CWARN}"     >> ${MC_CONFIG}/premake.${MC_OS}
423    echo "       FWARN=${FWARN}"     >> ${MC_CONFIG}/premake.${MC_OS}
424    echo "       PWARN=${PWARN}"     >> ${MC_CONFIG}/premake.${MC_OS}
425    echo "        XINC=${XINC}"      >> ${MC_CONFIG}/premake.${MC_OS}
426    echo "        XLIB=${XLIB}"      >> ${MC_CONFIG}/premake.${MC_OS}
427    echo "        XLDL=${XLDL}"      >> ${MC_CONFIG}/premake.${MC_OS}
428    echo "        GINC=${GINC}"      >> ${MC_CONFIG}/premake.${MC_OS}
429    echo "        GLIB=${GLIB}"      >> ${MC_CONFIG}/premake.${MC_OS}
430    echo "        GLDL=${GLDL}"      >> ${MC_CONFIG}/premake.${MC_OS}
431    echo "        MINC=${MINC}"      >> ${MC_CONFIG}/premake.${MC_OS}
432    echo "        MLIB=${MLIB}"      >> ${MC_CONFIG}/premake.${MC_OS}
433    echo "        MLDL=${MLDL}"      >> ${MC_CONFIG}/premake.${MC_OS}
434    echo "        OINC=${OINC}"      >> ${MC_CONFIG}/premake.${MC_OS}
435    echo "        OLIB=${OLIB}"      >> ${MC_CONFIG}/premake.${MC_OS}
436    echo "        OLDL=${OLDL}"      >> ${MC_CONFIG}/premake.${MC_OS}
437    echo "      ARCLIB=${ARCLIB}"    >> ${MC_CONFIG}/premake.${MC_OS}
438    echo "      RANLIB=${RANLIB}"    >> ${MC_CONFIG}/premake.${MC_OS}
439    echo "          RM=${RM}"        >> ${MC_CONFIG}/premake.${MC_OS}
440    echo "       BKDEP=${BKDEP}"     >> ${MC_CONFIG}/premake.${MC_OS}
441    echo "       MKDEP=${MKDEP}"     >> ${MC_CONFIG}/premake.${MC_OS}
442    echo ""                          >> ${MC_CONFIG}/premake.${MC_OS}
443
444    # Generate the postmake.${MC_OS} file
445    echo ""                              > ${MC_CONFIG}/postmake.${MC_OS}
446    echo "dep:"                         >> ${MC_CONFIG}/postmake.${MC_OS}
447    echo "	\${MKDEP} Makefile -Y \${CPPFLAGS} -I\${MC_INC} \${SRC}" \
448                                        >> ${MC_CONFIG}/postmake.${MC_OS}
449    echo "brkdep:"                      >> ${MC_CONFIG}/postmake.${MC_OS}
450    echo "	\${BKDEP} Makefile"         >> ${MC_CONFIG}/postmake.${MC_OS}
451    echo "clean:"                       >> ${MC_CONFIG}/postmake.${MC_OS}
452    echo "	\${RM} \${CLEANABLE}"       >> ${MC_CONFIG}/postmake.${MC_OS}
453    echo ""                             >> ${MC_CONFIG}/postmake.${MC_OS}
454    echo "# DO NOT DELETE THIS LINE -- make depend depends on it." \
455                                        >> ${MC_CONFIG}/postmake.${MC_OS}
456    echo ""                             >> ${MC_CONFIG}/postmake.${MC_OS}
457
458    # Make the MC_LIB subdirectory if it does not yet exist
459    if [ ! -d "${MC_LIB}" ]; then
460        mkdir ${MC_LIB}
461    fi
462}
463
464##############################################################################
465# Routine: chkConfig()
466# Purpose: Check to see if the package has been configured by genConfig().
467#          We key on existence of the MC_LIB directory (created by genConfig).
468#          The first argument is the option the user wants to execute.
469##############################################################################
470chkConfig() {
471    CC_ARG1="$1"
472    if [ ! -d "${MC_LIB}" ]; then
473        echo "${PR} ERROR: use <config> (at least once) before <${CC_ARG1}>."
474        mkExit "1" "chkConfig"
475    fi
476}
477
478##############################################################################
479# Routine: killMakefile()
480# Purpose: Kill an arch-dependent subdirectory (containing a makefile) in
481#          directory specified by the first argument, where the name of the
482#          arch-dependent subdirectory to kill is given by the second argument.
483#          If no agument given, remove all the arch-dependent subdirectories.
484##############################################################################
485killMakefile() {
486    KMF_DIR="$1"
487    KMF_OS="$2"
488    echo "${PR} Removing <${KMF_OS}> arch files and mk script in <${KMF_DIR}>."
489    cd ${MC_ROOT}/${KMF_DIR}
490    if [ "${KMF_OS}" = "ALL" ]; then
491        rm -rf arch ; rm -f mk mk.*
492    else
493        rm -rf arch/${KMF_OS} ; rm -f mk.${KMF_OS}
494    fi
495}
496
497##############################################################################
498# Routine: makeMakefile()
499# Purpose: Generate a makefile in directory specified by the first argument.
500#          We also leave behind a useful script for calling make.
501##############################################################################
502makeMakefile() {
503    MMF_ARG="$1"
504    echo "${PR} Generating Makefile for <${MMF_ARG}/arch/${MC_OS}>"
505
506    # Move to the directory
507    cd ${MC_ROOT}/${MMF_ARG}
508
509    # Leave behind a make script and a local version of ${MK_NAME}.
510    if [ "${MC_CWD}" = "${MC_ROOT}" ]; then
511
512        # Leave behind a make script called "mk.${MC_OS}"
513        echo "#! /bin/sh"                      > mk.${MC_OS}
514        echo "cd arch/${MC_OS} ; ${MAKE} \$@" >> mk.${MC_OS}
515        chmod u+x mk.${MC_OS}
516
517        # Leave behind local version of ${MK_NAME}
518        # (With a hard-wired MC_ROOT and a verbose make).
519        cat ${MC_CWD}/${MK_NAME} | ${AWK} " \
520                \$1 ~  /^ *MC_ROOT=/   { print \"MC_ROOT=${MC_ROOT}\" } \
521                \$1 ~  /^ *MK_MAKARG=/ { print \"MK_MAKARG=\${PARAMAKE}\" } \
522                \$1 !~ /^ *MC_ROOT=/ && \$1 !~ /^ *MK_MAKARG=/ { print \$0 } \
523            " > ${MK_NAME}
524        chmod u+x ${MK_NAME}
525    fi
526
527    # Get the list of source and header files while we are here
528    FILES=`ls -1 *.cc *.c *.h *.f 2>/dev/null \
529         | ${SED} -e "s./..g" | ${SED} -e "s.CVS..g"`;
530
531    # Make the "arch"itecture subdirectory if it does not yet exist
532    if [ ! -d "arch" ]; then
533        mkdir arch
534    fi
535    cd arch
536
537    # Remove MS_OS subdirectory and all contents, then recreate
538    rm -rf ${MC_OS}
539    mkdir ${MC_OS}
540    cd ${MC_OS}
541
542    # Create the symbolic links to the source and headers
543    for file in ${FILES}; do
544        ln -s ../../${file} ${file}
545    done
546
547    # Generate the makefile
548    cat ${MC_CONFIG}/premake.${MC_OS} > Makefile
549    cat ../../Makefile.mk | ${AWK} "!/^ *#+/ { print \$0 }" >> Makefile
550    cat ${MC_CONFIG}/postmake.${MC_OS} >> Makefile
551}
552
553##############################################################################
554# Routine: callMake()
555# Purpose: Do a make in the directory specified by the first argument.
556#          The second argument gives the optional target for the make.
557##############################################################################
558callMake() {
559    ML_DIR="$1"
560    ML_TGT="$2"
561    echo "${PR} Handling directory <${ML_DIR}/arch/${MC_OS}>"
562    cd ${MC_ROOT}/${ML_DIR}
563    ./mk.${MC_OS} ${MK_MAKARG} ${ML_TGT}
564}
565
566##############################################################################
567# Routine: doAll()
568# Purpose: Do something in all MK_LIBS directories.
569#          The first argument specifies the something to do.
570#          The second argument gives the argument for the something.
571##############################################################################
572doAll() {
573    DA_CMD="$1"
574    DA_ARG="$2"
575    getMkLibs
576    for lib in ${MK_LIBS}; do
577        "make_${lib}" "${DA_CMD}" "${DA_ARG}"
578    done
579}
580
581##############################################################################
582# Routine: mkExit()
583# Purpose: Exit with some error condition.
584#          The first argument has the error code.
585#          The second argument is the name of the function calling mkExit.
586##############################################################################
587mkExit() {
588    MKE_ERR="$1"
589    MKE_FUN="$2"
590    # echo "${PR} Exiting (called from ${MKE_FUN}) with error "${MKE_ERR})."
591    exit
592}
593
594##############################################################################
595# Initialization
596##############################################################################
597
598# Grab the arguments
599MK_CMD="$1"
600MK_OS="$2"
601
602# MC I/O prompt
603MK_NAME=`echo "$0" | ${SED} -e "s:./::g"`;
604if [ $# -eq 0 ]; then
605    PR="[${MK_NAME}]:"
606else
607    PR="[${MK_NAME} $@]:"
608fi
609
610# Define ROOT and CONFIG Paths
611MC_ROOT=`${PWD}`
612MC_TOOLS="${MC_ROOT}/cnf/tools"
613MC_CONFIG="${MC_ROOT}/cnf"
614MC_BIN="${MC_ROOT}/work/bin"
615MC_INC="${MC_ROOT}/inc"
616
617# Deal with the current working directory and the subroot piece
618# The subroot piece satisfies:  MC_CWD=MC_ROOT/MC_SUBROOT
619MC_CWD=`${PWD}`
620MC_SUBROOT=`echo "" | \
621   ${AWK} "{ printf(\"%s\",substr(\"${MC_CWD}\",length(\"${MC_ROOT}\")+2)) }"`
622
623# Identify the library name in case we are in a subdirectory
624MC_LIBNAME=""
625getMkLibs
626for lib in ${MK_LIBS}; do
627   VAL=`echo ""|${AWK} "{printf(\"%s\",index(\"${MC_SUBROOT}\",\"${lib}\"))}"`
628   if [ ${VAL} -gt 0 ]; then
629       MC_LIBNAME="${lib}"
630   fi
631done
632
633# Some minmal checking for correctness of the paths
634if [ ! "${MC_CWD}" = "${MC_ROOT}" ]; then
635    MK_ERROR=0
636
637    # Make sure the three paths agree with each other
638    if [ ! "${MC_CWD}" = "${MC_ROOT}/${MC_SUBROOT}" ]; then
639        MK_ERROR=1
640    fi
641
642    # Make sure we have a proper library name if we are in a subdirectory
643    if [ "${MC_LIBNAME}" = "" ]; then
644        MK_ERROR=1
645    fi
646
647    # Do some helpful debug I/O if necessary
648    if [ ${MK_ERROR} -gt 0 ]; then
649        echo "${PR} There is some problem with the path settings."
650        echo "${PR}     MC_CWD=<${MC_CWD}>"
651        echo "${PR}    MC_ROOT=<${MC_ROOT}>"
652        echo "${PR} MC_SUBROOT=<${MC_SUBROOT}>"
653        echo "${PR} MC_LIBNAME=<${MC_LIBNAME}>"
654        mkExit "${MK_ERROR}" "main"
655    fi
656fi
657
658##############################################################################
659# Do it
660##############################################################################
661
662# Decode the first argument
663case ${MK_CMD} in
664    go) # <config/clean/dep/build> all at once
665        echo "${PR} Doing config->clean->dep->build."
666        getConfig ${MK_OS}
667        ./${MK_NAME} config ${MK_OS}
668        ./${MK_NAME} clean  ${MK_OS}
669        ./${MK_NAME} dep    ${MK_OS}
670        ./${MK_NAME} build  ${MK_OS} ;;
671
672    config) # <auto|manual configuration>
673        echo "${PR} Doing a configuration."
674        getConfig ${MK_OS}
675        genConfig
676        if [ "${MC_SUBROOT}" = "" ]; then
677            doAll "makeMakefile"
678        else
679            "make_${MC_LIBNAME}" "makeMakefile"
680        fi ;;
681
682    clean) # <clean up object files and binaries>
683        echo "${PR} Doing a make clean."
684        getConfig ${MK_OS}
685        chkConfig "clean"
686        if [ "${MC_SUBROOT}" = "" ]; then
687            doAll "callMake" "clean"
688        else
689            "make_${MC_LIBNAME}" "callMake" "clean"
690        fi ;;
691
692    dep) # <build all dependencies in the makefiles>
693        echo "${PR} Doing a make depend."
694        getConfig ${MK_OS}
695        chkConfig "dep"
696        if [ "${MC_SUBROOT}" = "" ]; then
697            doAll "callMake" "dep"
698        else
699            "make_${MC_LIBNAME}" "callMake" "dep"
700        fi ;;
701
702    build) # <build the libraries>
703        echo "${PR} Doing package build."
704        getConfig ${MK_OS}
705        chkConfig "build"
706        if [ "${MC_SUBROOT}" = "" ]; then
707            doAll "callMake" "default"
708        else
709            "make_${MC_LIBNAME}" "callMake" "default"
710        fi ;;
711
712    brkdep) # <remove dependencies in the makefiles>
713        echo "${PR} Doing a break depend."
714        getConfig ${MK_OS}
715        chkConfig "brkdep"
716        if [ "${MC_SUBROOT}" = "" ]; then
717            doAll "callMake" "brkdep"
718        else
719            "make_${MC_LIBNAME}" "callMake" "brkdep"
720        fi ;;
721
722    rclean) # <clean up everything>
723
724        # Allow rclean only in the root directory.
725        if [ "${MC_SUBROOT}" = "" ]; then
726            echo "${PR} Doing a make REAL clean."
727
728            # Clean out all platform build directories and support files.
729            if [ "${MK_OS}" = "all" ]; then
730
731                echo "${PR} Removing <ALL> arch files and mk scripts."
732                doAll "killMakefile" "ALL"
733
734                echo "${PR} Removing <ALL> archive libraries."
735                cd ${MC_ROOT}/lib
736                THELIBS=`ls -1 | ${SED} -e "s./..g" | ${SED} -e "s.CVS..g"`;
737                for lib in ${THELIBS}; do
738                    rm -rf ${lib}
739                done
740
741                echo "${PR} Removing <ALL> premake and postmake files."
742                cd ${MC_CONFIG} ; rm -f premake.* postmake.*
743
744                echo "${PR} Removing <ALL> executables."
745                cd ${MC_BIN}    ; rm -f core   2>/dev/null
746                cd ${MC_BIN}    ; rm -f   go.* 2>/dev/null
747
748            # One particular platform specified, so clean only that platform.
749            else
750
751                # Get the actuall platform OS to cleanup.
752                getConfig ${MK_OS}
753
754                echo "${PR} Removing <${MC_OS}> arch files and mk scripts."
755                doAll "killMakefile" "${MC_OS}"
756
757                echo "${PR} Removing <${MC_OS}> archive libraries."
758                cd ${MC_ROOT}/lib ; rm -rf ${MC_OS}
759
760                echo "${PR} Removing <${MC_OS}> premake and postmake files."
761                cd ${MC_CONFIG} ; rm -f premake.${MC_OS} postmake.${MC_OS}
762
763                echo "${PR} Removing <${MC_OS}> executables."
764                cd ${MC_BIN}    ; rm -f core          2>/dev/null
765                cd ${MC_BIN}    ; rm -f   go.${MC_OS} 2>/dev/null
766            fi
767
768        # Do not allow rclean in the subdirectories.
769        else
770            echo "${PR} You can do <rclean> only from the root directory."
771        fi ;;
772
773    tgz) # <build a gzipped tar archive of the package>
774
775        # Allow tgz only in the root directory.
776        if [ "${MC_SUBROOT}" = "" ]; then
777
778            ./${MK_NAME} rclean all
779            echo "${PR} Forming gzipped tar archive."
780            cd ${MC_ROOT}/../
781            ${TOUCH} mc.tgz
782            mv -f mc.tgz mc.tgz_OLD
783            ${TAR} cf mc.tar mc
784            ${GZIP} -v mc.tar
785            mv mc.tar.gz mc.tgz
786
787        # Do not allow tgz in the subdirectories.
788        else
789            echo "${PR} You can do <tgz> only from the root directory."
790        fi ;;
791
792    info) # <print more information about usage>
793        printInfo ;;
794
795    *) # <print a short usage menu>
796        printMenu ;;
797esac
798
799mkExit "0" "main"
800
801