Added "conv-config.sh", which wraps "conv-mach.sh" and adds default
[charm.git] / src / scripts / charmc
1 #!/bin/sh
2 ##############################################################################
3 # charmc: Compiler for Converse/Charm/Charm++ programs
4 #
5 # Converted to Bourne Shell by Orion Sky Lawlor, 10/21/1999
6 #
7 # Initialize the main controlling variables, setup error handler
8 # ALL variables used by this script should be initialized here.
9 #
10 ##############################################################################
11
12 #Prepare aliases for the external commands we use--
13 # Note that adding /bin/ to everything breaks Cygwin32.
14 RM="rm -f"
15 CP="cp -p"
16 MV="mv"
17 LN="ln"
18 WC="wc"
19 SED="sed"
20
21 MACHTYPE=""
22 SEQUENTIAL=""
23 LANGUAGE=""
24 BALANCE="rand"
25 TRACEMODE=""
26 TRACE_OBJ=
27 MEMORY="default"
28 VERBOSE=""
29 DEBUG_SCRIPT=""
30 SAVE=""
31 PURIFY=""
32 SKIPLINK=""
33 OVERRIDE_CC=""
34 OVERRIDE_CXX=""
35 OVERRIDE_F90=""
36 OVERRIDE_LD=""
37 OVERRIDE_LDXX=""
38 #Generic options, passed to everything
39 OPTS=""
40 #Specific options
41 OPTS_CPP=""
42 OPTS_LDRO="" 
43 OPTS_CC=""
44 OPTS_CXX="" 
45 OPTS_F90=""
46 OPTS_LD=""  
47 OPTS_LDXX=""
48
49 OBJECT=""
50 POST_LANGUAGE=""
51 POST_LIBRARIES=""    
52 PRE_LIBRARIES=""  
53 USE_F90_LIBRARIES="0"  
54 COPIES=""        
55 MODCOPIES=""        
56 MODULES=""
57 BALANCER=""
58 FILES=""       
59 OBJECTFILES=""  
60 DELETE=""    
61 MAINOBJ=""   
62 GENCPM=""
63 OPTIMIZE_MODE=""
64 USE_RELIABLE_CC=""
65 USE_FASTEST_CC=""
66 PROG_EXT=""
67
68 ####################################################################
69 #
70 #  Utility routines used below
71 #
72 ###################################################################
73
74 # PrintUsage: prints a helpful command-line usage message and quits
75 # Args: any additional messages
76 printUsage() {
77     echo "Usage: charmc [ flags ] <files>"
78     echo
79     echo "  flags:"
80     echo "        -o <target> -g -O"
81     echo "        -D<define> -I<include path> -L<lib path> -l<library> -s"
82     echo "        -machine <mach> -seq -langage <lang> "
83     echo "        -balance <mode> -tracemode <mode> -memory <mode>"
84     echo "        -modules <comma-separated list of C++ modules>"
85     echo "        -verbose -save -purify -cp <dest> -gen-cpm <package>"
86     echo "        -use-reliable-cc -use-fastest-cc"
87     echo "        -cc <new cc> -c++ <new CC>  -ld <new ld> -ld++ <new LD>"
88     echo "        -cpp-option <opt> -ldro-option <opt> -cc-option <opt>"
89     echo "        -c++-option <opt> -ld-option <opt> -ld++-option <opt>"
90     echo "        -pg <opt>"
91     echo
92     echo "  Charmc compiles C, C++, f77, f90, Converse, Converse++, Charm, "
93     echo "and Charm++ programs.  The flags generally match those of cc or f77."
94     echo "Version 5.0, Parallel Programming Lab, UIUC, 1999"
95     echo $*
96     exit 1
97 }
98
99 # End blows away the temporary files (unless SAVE is true) and exits
100 # Args: <exit code>
101 End() {
102     if [ -z "$SAVE" ]
103         then
104         for FILE in `echo $FILES`
105         do
106                         BASE=`stripExtention $FILE`
107                         TMP=`basename $FILE`".TMP"
108             $RM $TMP.P.C $TMP.cpp $TMP.space $TMP.xlat $TMP.o
109             $RM $TMP.c $TMP.c.0.h $TMP.c.1.h $TMP.c.2.h
110             $RM $TMP.i $TMP.$CMK_CPP_SUFFIX
111         done
112         $RM core $DELETE
113     fi
114     exit $1
115 }
116
117 # This procedure prints an error message and exits.
118 # ("1>&2" redirects the echo output to stderr).
119 # Args: written to stderr
120 Abort() {
121         echo "Fatal Error by charmc in directory "`pwd` 1>&2
122         echo "   $*" 1>&2
123         echo "charmc exiting..." 1>&2
124         End 1
125 }
126
127 # Instead of an ECHO_CMD variable, I define a procedure Do,
128 # which (possibly) echos, runs, and tests the errors of the given command.
129 # Args: executed as given
130 DoNoErrCheck() {
131         [ -n "$VERBOSE" ] && echo "charmc: Executing $*" 1>&2
132         $*
133 }
134 Do() {
135         DoNoErrCheck $*
136         Do_res=$?
137 # The UNIX result code better be zero, or we die
138         [ $Do_res -eq 0 ] || Abort "Command $* returned error code $Do_res"
139 }
140
141 # This procedure removes the extention (the ".c" in "./main.c") from
142 # its first argument, and prints the result. Unlike the builtin command
143 # basename, it keeps the directory path.
144 # Args: <name to strip>
145 stripExtention() {
146         se_base=`echo $1 | awk -F/ '{print $NF}'`
147         se_strip=`echo $se_base | awk -F. '{ORS="";print $1;for (i=2;i<NF;i++) print "."$i}'`
148         se_ret=`echo $1 | awk -F/ '{ORS="";for (i=1;i<NF;i++) print $i"/"}'`"$se_strip"
149         echo $se_ret
150 }
151
152 # GetExtention returns the extention on the given file name
153 # or "" if none.  (e.g. "./bob/snack.c" returns ".c")
154 # Args: <name to find extention of>
155 getExtention() {
156         se_base=`echo $1 | awk -F/ '{print $NF}'`
157         se_ret=`echo $se_base | awk -F. '{if (NF<=1) print ""; else print "."$NF}'`
158         echo $se_ret
159 }
160
161 Debugf() {
162         [ -n "$VERBOSE" ] && echo "charmc>" $@
163 }
164
165 Debug() {
166     if [ -n "$DEBUG_SCRIPT" ]
167     then
168         echo 
169         echo "------- Charmc Debugging info: $* -------"
170         echo "CHARMBIN=$CHARMBIN"
171         echo "CHARMINC=$CHARMINC"
172         echo "CHARMLIB=$CHARMLIB"
173         echo "FILES=$FILES"
174         echo "DELETE=$DELETE"
175         echo "OBJECT=$OBJECT"
176         echo "LANGUAGE=$LANGUAGE"
177 #       echo "Working directory="`pwd`
178     fi
179 }
180
181 # Return success if $1 is not in any of the other arguments
182 notInList() {
183         search=$1
184         shift
185         while [ $# -gt 0 ]
186         do
187                 if [ "$search" = "$1" ]
188                 then
189                         # It's already in there-- fail
190                         return 1
191                 fi
192                 shift
193         done
194         # It's missing--succeed
195         return 0
196 }
197
198 # Add arguments to our modules list, avoiding duplicates
199 AddModules() {
200     for M in $*
201     do
202       notInList $M $MODULES && MODULES="$MODULES $M"
203     done
204 }
205
206 # TEMP_BASE is appended with this script's process ID (PID),
207 # so multiple charmcs can run in parallel without overwriting
208 # each other's temporary files.
209 TEMP_BASE="/tmp/charmc_tmp.$$"
210
211 ##############################################################################
212 #
213 # Parse the arguments
214 #
215 # Don't do any analysis in here, just the parsing.
216 #
217 ##############################################################################
218
219 [ $# -eq 0 ] && printUsage "Error: No arguments given."
220
221 processArgs() {
222 while [ ! $# -eq 0 ]
223 do
224         arg="$1"
225         shift
226
227         case "$arg" in
228         "-machine")
229                 MACHTYPE="$1"
230                 shift
231                 ;;
232
233         "-seq")
234                 SEQUENTIAL=true
235                 ;;
236
237         "-language")
238                 # Parse out some fake languages (that are actually modules)
239                 case "$1" in
240                 "ampi") AddModules ampi ;;
241                 "ampif") AddModules ampif ;;
242                 "fem") AddModules fem ;;
243                 "femf") AddModules fem ; USE_F90_LIBRARIES="1" ;;
244                 "mblock") AddModules mblock ;;
245                 "mblockf") AddModules mblock ; USE_F90_LIBRARIES="1" ;;
246                 *) 
247                         LANGUAGE="$1"
248                         POST_LANGUAGE=1
249                         ;;
250                 esac
251                 shift
252                 ;;
253
254         "-module"|"-modules")
255                 AddModules `echo $1 | sed -e 's/,/ /g'`
256                 shift
257                 ;;
258
259         "-balancer")
260                 test -n "$BALANCER" && Abort "More than one -balancer specified!"
261                 BALANCER="$1"
262                 AddModules $1
263                 shift
264                 ;;
265
266         "-balance")
267                 BALANCE="$1"
268                 shift
269                 ;;
270
271         "-queue")
272                 echo "Warning: -queue currently being ignored."
273                 shift
274                 ;;
275
276         "-memory")
277                 MEMORY="$1"
278                 shift
279                 ;;
280
281         "-tracemode")
282                 TRACEMODE="$TRACEMODE $1"
283                 shift
284                 ;;
285
286         "-verbose")
287                 echo "Verbose mode set"
288                 VERBOSE=true
289                 ;;
290
291         "-debug-script")
292                 echo "Will give excessive charmc debugging output..."
293                 DEBUG_SCRIPT=true
294                 ;;
295
296         "-save")
297                 SAVE=true
298                 ;;
299
300         "-purify")
301                 PURIFY=true
302                 ;;
303
304         "-use-reliable-cc")
305                 USE_RELIABLE_CC=1
306                 ;;
307
308         "-use-fastest-cc")
309                 USE_FASTEST_CC=1
310                 ;;
311
312         "-cc")
313                 OVERRIDE_CC="$1"
314                 shift
315                 ;;
316
317         "-c++")
318                 OVERRIDE_CXX="$1"
319                 shift
320                 ;;
321
322         "-f90")
323                 OVERRIDE_F90="$1"
324                 shift
325                 ;;
326
327         "-ld")
328                 OVERRIDE_LD="$1"
329                 shift
330                 ;;
331
332         "-ld++")
333                 OVERRIDE_LDXX="$1"
334                 shift
335                 ;;
336
337         "-cpp-option")
338                 OPTS_CPP="$OPTS_CPP $1"
339                 shift
340                 ;;
341
342         "-ldro-option")
343                 OPTS_LDRO="$OPTS_LDRO $1"
344                 shift
345                 ;;
346
347         "-cc-option")
348                 OPTS_CC="$OPTS_CC $1"
349                 shift
350                 ;;
351
352         "-c++-option")
353                 OPTS_CXX="$OPTS_CXX $1"
354                 shift
355                 ;;
356
357         "-f90-option")
358                 OPTS_F90="$OPTS_F90 $1"
359                 shift
360                 ;;
361
362         "-ld-option")
363                 OPTS_LD="$OPTS_LD $1"
364                 shift
365                 ;;
366
367         "-ld++-option")
368                 OPTS_LDXX="$OPTS_LDXX $1"
369                 shift
370                 ;;
371
372         "-rpath")
373                 OPTS_LDXX="$OPTS_LDXX -rpath $1"
374                 shift
375                 ;;
376         "-fortran"|"-flib"|"-flibs")
377                 USE_F90_LIBRARIES="1" 
378                 ;;
379         "-M"|"-E"|"-P"|"-S")
380 # Run preprocessor/assembler only
381                 SKIPLINK="yes"
382                 OPTS="$OPTS $arg"
383                 ;;
384         "-c")
385 # This is ignored.
386                 ;;
387
388         "-o")
389                 OBJECT=$1
390                 shift
391                 ;;
392
393         "-cp")
394                 COPIES="$1 $COPIES"
395                 shift
396                 ;;
397
398         "-cpmod")
399                 MODCOPIES="$1 $MODCOPIES"
400                 shift
401                 ;;
402
403         "-gen-cpm")
404                 GENCPM="$GENCPM $1"
405                 shift
406                 ;;
407
408         -D*|-I*)
409                 OPTS_CPP="$OPTS_CPP $arg"
410                 ;;
411
412         -LANG*)
413                 echo "passing unrecognized option $arg to all compilers and linkers"
414                 OPTS="$OPTS $arg"
415                 ;;
416         -L*)
417                 OPTS_LD="$OPTS_LD $arg"
418                 ;;
419
420         "-O")
421                 OPTIMIZE_MODE=true
422                 ;;
423
424         "-NO")
425                 OPTIMIZE_MODE=false
426                 ;;
427         
428         "-pg"|"-g"|-W*|-O*)
429                 OPTS="$OPTS $arg"
430                 ;;
431
432         -l*)
433                 if [ -n "$POST_LANGUAGE" ]
434                 then
435                         POST_LIBRARIES="$POST_LIBRARIES $arg"
436                 else
437                         PRE_LIBRARIES="$PRE_LIBRARIES $arg"
438                 fi
439                 ;;
440
441         -s)
442                 OPTS_LD="$OPTS_LD   $arg"
443                 ;;
444
445         -h|--help)
446                 printUsage
447                 ;;
448         -*|+*)
449                 echo "passing unrecognized option $arg to all compilers and linkers"
450                 OPTS="$OPTS  $arg"
451                 ;;
452         *.*)
453                 [ -n "$VERBOSE" ] && echo "Adding file $arg..."
454                 FILES="$FILES $arg"
455                 ;;
456 # Default
457         *)
458                 printUsage  "Error: Unrecognized argument $arg"
459                 ;;
460         esac
461 done
462 }
463
464
465 # Process original command-line arguments
466 processArgs $@
467
468
469 ##############################################################################
470 #
471 # The following section identifies CHARMBIN, the charm binary-directory.
472 #
473 ##############################################################################
474
475 ORIGDIR=`pwd`
476
477 # Try to find CHARMBIN by looking in directory where charmc is
478
479 if [ -z "$CHARMBIN" ]
480 then
481         SCRIPT=$0
482         CHARMBIN=`dirname $SCRIPT`
483 #       CHARMBIN=`cd $CHARMBIN; pwd`
484 # NOTE: this script no longer tries to follow soft links
485 # to find the "original" charmc-- if this is bad, 
486 # translate these lines to Bourne shell from C shell:
487 # -------------------- Begin C Shell ------------------------->
488 #    if ($SCRIPT:h != $SCRIPT:t) then
489 #        cd $SCRIPT:h
490 #        set SCRIPT=$SCRIPT:t
491 #    else
492 #        foreach dir ($path)
493 #            if (-x $dir/$SCRIPT && ! -d $dir/$SCRIPT) then
494 #                cd $dir
495 #                break
496 #            endif
497 #        end
498 #    endif
499 #    while (x`find $SCRIPT -type l -print` == x$SCRIPT)
500 #        set SCRIPT=`ls -al ./$SCRIPT:t | sed -e "s@.*-> @@"`
501 #        if ($SCRIPT:h != $SCRIPT:t) then
502 #            cd $SCRIPT:h
503 #            set SCRIPT=$SCRIPT:t
504 #        endif
505 #    end
506 #    set CHARMBIN=`pwd`
507 # <------------------ End C Shell -----------------------------
508 fi
509
510 FIRST_THREE=`uname -s | awk '{print substr($1,1,3)}' `
511 if [ "$FIRST_THREE" = "CYG" ]
512 then
513 # Running on a windows system-- append .exe to file names
514         PROG_EXT=".exe"
515 fi
516
517 CHARMLIB="$CHARMBIN/../lib"
518 CHARMINC="$CHARMBIN/../include"
519
520
521 ##############################################################################
522 #
523 # Load module dependencies.
524 #
525 ##############################################################################
526
527 PROCESSED_MODULES=""
528
529 # Look up and add the dependencies for module $1
530 findModuleDep() {
531         M=$1
532         notInList $M $PROCESSED_MODULES || return
533         PROCESSED_MODULES="$PROCESSED_MODULES $M"
534         
535         dep=""
536 # fixme: should search everything in the -L library paths:
537         for dir in `echo . $CHARMLIB`
538         do
539                 d="$dir/libmodule$M.dep"
540                 [ -r "$d" ] && dep=$d
541         done
542         if [ -r "$dep" ]
543         then
544                 # Add the module dependencies in this file
545                 # Debugf "Adding module" $M "dependencies from" $dep
546                 deps=`cat $dep`
547                 Debugf "Module" $M "adds dependencies:" $deps
548                 processArgs $deps
549         fi
550 }
551
552 # Repeat the module-dependency search until we find no
553 #  new modules:
554 START_MODULES=""
555 while [ "$START_MODULES" != "$MODULES" ]
556 do
557         Debugf "----------- Module dependency search ------------"
558         START_MODULES="$MODULES"
559         for m in $MODULES
560         do
561                 findModuleDep $m
562         done
563 done
564
565 Debugf "----------- Module dependency search complete ------------"
566
567
568
569 ##############################################################################
570 #
571 # Load machine-specific configuration data, then handle overrides to it.
572 #
573 ##############################################################################
574
575
576 Debug "About to read machine config script"
577 Debug "Read config script, setting defaults..."
578
579 [ ! -r $CHARMINC/conv-config.sh ] && Abort "Cannot find conv-config.sh in $CHARMINC"
580 . $CHARMINC/conv-config.sh $CHARMINC
581
582 Debug "Setting vars..."
583
584 if [ -n "$USE_RELIABLE_CC" ]
585 then
586         CMK_CC="$CMK_CC_RELIABLE"
587 fi
588
589 if [ -n "$USE_FASTEST_CC" ]
590 then
591     CMK_CC="$CMK_CC_FASTEST"
592 fi
593
594 if [ -n "$CMK_F90_MODINC" ]
595 then
596     CMK_CF90_MODINC="$CMK_F90_MODINC"
597 else
598     CMK_CF90_MODINC="-M"
599 fi
600
601 if [ -n "$CMK_F90_USE_MODDIR" ]
602 then
603     CMK_CF90="$CMK_CF90 $CMK_CF90_MODINC$CHARMINC "
604 fi
605
606 if [ -n "$SEQUENTIAL" ]
607 then
608     CMK_CC="$CMK_SEQ_CC -DCMK_SEQUENTIAL=1 "
609     CMK_LD="$CMK_SEQ_LD"
610     CMK_CXX="$CMK_SEQ_CXX -DCMK_SEQUENTIAL=1 " 
611     CMK_CF90="$CMK_SEQ_F90 " 
612     CMK_LDXX="$CMK_SEQ_LDXX" 
613     CMK_AR="$CMK_SEQ_AR"
614     CMK_RANLIB="$CMK_SEQ_RANLIB"
615 fi
616
617 if [ -n "$OVERRIDE_CC" ]
618 then
619     CMK_CC="$OVERRIDE_CC $CMK_CC "
620 fi
621 Debug "set 2"
622 if [ -n "$OVERRIDE_CXX" ]
623 then
624     CMK_CXX="$OVERRIDE_CXX $CMK_CXX "
625 fi
626
627 if [ -n "$OVERRIDE_F90" ]
628 then
629     CMK_CF90="$OVERRIDE_F90 $CMK_CF90 "
630 fi
631
632 if [ -n "$OVERRIDE_LD" ]
633 then
634     CMK_LD="$OVERRIDE_LD $CMK_LD"
635 fi
636
637 if [ -n "$PURIFY" ]
638 then
639     CMK_LD="purify $CMK_LD"
640     CMK_LDXX="purify $CMK_LDXX"
641 fi
642
643 if [ -n "$OVERRIDE_LDXX" ]
644 then
645     CMK_LDXX="$OVERRIDE_LDXX $CMK_LDXX"
646 fi
647
648 Debug "set 4"
649 if [ -n "$OPTIMIZE_MODE" ]
650 then
651     OPTS_CC="$CMK_C_OPTIMIZE $OPTS_CC"
652     OPTS_CXX="$CMK_CXX_OPTIMIZE $OPTS_CXX"
653     OPTS_F90="$CMK_F90_OPTIMIZE $OPTS_F90"
654     OPTS_LD="$CMK_C_OPTIMIZE $OPTS_LD"
655     OPTS_LDXX="$CMK_CXX_OPTIMIZE $OPTS_LDXX"
656 fi
657
658 #Add generic options to the compiler- and linker-options
659 OPTS_CC="$OPTS $OPTS_CC"
660 OPTS_CXX="$OPTS $OPTS_CXX"
661 OPTS_F90="$OPTS $OPTS_F90"
662 OPTS_LD="$OPTS $OPTS_LD"
663 OPTS_LDXX="$OPTS $OPTS_LDXX"
664
665 # There's really no analog for this in the Bourne shell: 
666 #  -------- C Shell ------> onintr failure
667 # Luckily, it's irrelevant as long as nobody sends us a ^Z.
668
669 ##############################################################################
670 #
671 # Check for valid choice of LANGUAGE
672 #
673 ##############################################################################
674 Debug "Checking language..."
675
676 if [ -z "$LANGUAGE" ]
677 then
678     LANGUAGE="charm++"
679     [ -n "$SEQUENTIAL" ] && LANGUAGE=c
680 fi
681
682 case "$LANGUAGE" in
683 "c"|"C"|"c++"|"C++")
684         [ -z "$SEQUENTIAL" ] && Abort "Language $LANGUAGE is for sequential programs"
685         ;;
686 esac
687
688 ########################################################################
689 #
690 # We've parsed and verified the command-line parameters.
691 # Now we prepare routines to clean up and exit.
692 # None of these routines ever returns-- they all just exit.
693 #
694 ########################################################################
695
696
697 Copyobj() {
698         for COPY in `echo $COPIES`
699         do
700                 if [ "a$COPY" != "a$OBJECT" ] 
701                 then
702                         [ -d $COPY ] && COPY="$COPY/"
703                         if [ "a$PROG_EXT" != "a" -a -r "$OBJECT$PROG_EXT" ] ; then
704                                 echo "Appending $PROG_EXT to object file name"
705                                 OBJECT="$OBJECT$PROG_EXT"
706                         fi
707                         [ ! -d $COPY ] && DoNoErrCheck $RM $COPY 
708                         Do $CP $OBJECT $COPY
709                 fi
710         done
711         Success
712 }
713
714 Copymod() {
715         for COPY in `echo $MODCOPIES`
716         do
717                 if [ "a$COPY" != "a$OBJECT" ] 
718                 then
719                         [ -d $COPY ] && COPY="$COPY/"
720                         if [ -n "$CMK_MOD_NAME_ALLCAPS" ] ; then
721                           OBJECT=`echo $OBJECT | tr "a-z" "A-Z"`
722                         fi
723                         if [ -r "$OBJECT.$CMK_MOD_EXT" ] ; then
724                           echo "Appending .$CMK_MOD_EXT to object file name"
725                           OBJECT="$OBJECT.$CMK_MOD_EXT"
726                         fi
727                         [ ! -d $COPY ] && DoNoErrCheck $RM $COPY 
728                         Do $CP $OBJECT $COPY
729                 fi
730         done
731         Success
732 }
733
734 Success() {
735         End 0
736 }
737
738
739 ##############################################################################
740 #
741 # Preprocess the GEN-CPM files
742 #
743 ##############################################################################
744
745 Debug "Preprocessing GEN-CPM files"
746
747 for FILE in `echo $GENCPM`
748 do
749 # This used to be "$FILE:r", which strips the extention
750         BASE=`stripExtention $FILE`
751         TMP=`basename $FILE`".TMP"
752         DELETE="$DELETE $TMP.c $TMP.i"
753         DoNoErrCheck $RM $BASE.cpm.h $TMP.c
754         Do touch $BASE.cpm.h
755         Do $LN -f -s $FILE $TMP.c
756         Do $CMK_CPP_C $OPTS_CC $OPTS_CPP -I$CHARMINC $TMP.c > $TMP.i
757         Do $CHARMBIN/conv-cpm $TMP.i $BASE.cpm.h
758 done
759
760 ##############################################################################
761 #
762 # Compile all specified files
763 #
764 # All temporary files named *.TMP.* for easy cleanup.
765 #
766 ##############################################################################
767
768 Debug "About to compile..."
769
770 for FILE in `echo $FILES`
771 do
772         BASE=`stripExtention \`basename $FILE\``
773         TMP=`basename $FILE`".TMP"
774         FILE_EXT=`getExtention $FILE`
775         if [ "$FILE_EXT" != ".o" -a "$FILE_EXT" != ".M" -a "$FILE_EXT" != ".ci" ]
776         then
777                 [ $VERBOSE ] && echo "Compiling $FILE"
778                 DoNoErrCheck $RM $BASE.o $BASE.f.o
779         fi
780         BASEO="$BASE.o"
781         DESTO="-o $BASEO"
782         if [ ! -z "$SKIPLINK" ] 
783         then
784                 DESTO=""
785         fi
786         NU_OBJ=""
787         case "$FILE" in
788         *.ci)
789                 if [ "$LANGUAGE" = "f90charm" ]
790                 then
791                     Do $CHARMBIN/charmxi -f90 $CMK_XIOPTS $FILE
792                 else
793                     Do $CHARMBIN/charmxi $CMK_XIOPTS $FILE
794                 fi
795                 ;;
796         *.c|*.s)
797                 Do $CMK_CC $OPTS_CPP $OPTS_CC -I$CHARMINC -c $FILE $DESTO
798                 NU_OBJ=$BASEO
799                 ;;
800         *.C|*.cc|*.cxx|*.cpp|*.c++)
801                 Do $CMK_CXX $OPTS_CPP $OPTS_CXX -I$CHARMINC -c $FILE $DESTO
802                 NU_OBJ=$BASEO
803                 ;;
804         *.f|*.F)
805                 Do $CMK_CF90_FIXED $OPTS_CPP $OPTS_F90 -I$CHARMINC -c $FILE $DESTO
806                 NU_OBJ=$BASEO
807                 ;;
808         *.f90|*.F90)
809                 Do $CMK_CF90 $OPTS_CPP $OPTS_F90 -I$CHARMINC -c $FILE $DESTO
810                 NU_OBJ=$BASEO
811                 ;;
812         *.fc|*.FC)
813                 Abort "I'm not yet smart enough to compile $FILE"
814                 ;;
815         *.o|*.a)
816                 OBJECTFILES="$OBJECTFILES $FILE"
817                 ;;
818         *.M|*.mod)
819                 OBJECT="$BASE"
820                 Copymod
821                 Success
822                 ;;
823         *)
824                 Abort "file with unrecognized extension $FILE"
825         esac
826 # Handle new object files
827         if [ -n "$NU_OBJ" -a -n "$OBJECT" ] 
828         then
829                 if [ "$OBJECT" != "$BASE.o" ]
830                 then
831                         DELETE="$DELETE $NU_OBJ"
832                 fi
833                 OBJECTFILES="$OBJECTFILES $NU_OBJ"
834         fi
835 done
836
837 ##############################################################################
838 #
839 #                        POSSIBLY, SKIP LINK-STEP
840 #
841 # 1. No $OBJECT may be specified at all --- its just a compilation.
842 # 2. If $OBJECT is a ".a" file, a library is created from $OBJECTFILES.
843 # 3. If $OBJECT is a ".o" file, then an "LDRO" is created from $OBJECTFILES.
844 # 4. Language may be sequential.  Do a quick and easy linkage.
845 #
846 #               in any of these cases, the full link step is skipped.
847 #
848 ##############################################################################
849
850 if [ -z "$OBJECT" -o ! -z "$SKIPLINK" ] 
851 then
852 # We have no target object, or are playing preprocessor tricks-- just end
853         Debugf "No target object-- finished"
854         Success
855 fi
856
857 Debug "About to link..."
858
859 case "$OBJECT" in
860 *.o)
861         Debugf "Converting $FILES to $OBJECTFILES"
862         nFiles=`echo $FILES | wc -w`
863         nObj=`echo $OBJECTFILES | wc -w`
864         if [ $nFiles -eq 1 -a $nObj -eq 1 ] 
865         then
866 # One source file, one .o: just move the .o
867                 if [ $OBJECT != $OBJECTFILES ]
868                 then
869                         Debugf "Moving .o to destination"
870                         DoNoErrCheck $RM $OBJECT
871                         Do $MV $OBJECTFILES $OBJECT
872                 fi
873         else
874 # Multiple source files, one .o: make shared library
875                 Debugf "Running ldro..."
876                 DoNoErrCheck $RM $OBJECT
877                 Do $CMK_LDRO $OBJECT $OPTS_LD $OPTS_LDRO $OBJECTFILES
878         fi
879         Copyobj
880         ;;
881 *.a)
882         DoNoErrCheck $RM $OBJECT
883         Do $CMK_AR $OBJECT $OBJECTFILES
884         Do $CMK_RANLIB $OBJECT
885         Copyobj
886         ;;
887 esac
888 # If the above case returns, we're not creating a .o or .a file,
889 # so linking is needed.
890
891 ############ Determine the language and libraries ##########
892
893 # Parse out the real languages
894 case "$LANGUAGE" in
895 "charm++f")
896         LANGUAGE="charm++"
897         USE_F90_LIBRARIES="1"
898         ;;
899 "f90charm")
900         PRE_LIBRARIES="$PRE_LIBRARIES -lf90charm "
901         POST_LIBRARIES="$POST_LIBRARIES $CMK_F90LIBS"
902         ;;
903 "bluegene")
904         PRE_LIBRARIES="$PRE_LIBRARIES -lconv-bluegene"
905         ;;
906 "ckbluegene")
907         POST_LIBRARIES="$POST_LIBRARIES -lbluegene"
908         ;;
909 "bgcharm++")
910         PRE_LIBRARIES="$PRE_LIBRARIES -lconv-bluegene"
911         ;;
912 esac
913 [ -r $CHARMLIB/libconv-utilf.a ] || USE_F90_LIBRARIES="0"
914
915 if [ $USE_F90_LIBRARIES = "1" ]
916 then
917         POST_LIBRARIES="$POST_LIBRARIES -lconv-utilf $CMK_F90LIBS"
918         if [ -z "$SEQUENTIAL" -a ! -z "$CMK_F90OBJS" ] 
919         then
920           for f90obj in $CMK_F90OBJS
921           do
922             OBJECTFILES="$OBJECTFILES $CHARMLIB/$f90obj"
923           done
924         fi
925 fi
926
927 # Add the modules to the link list
928 LINK_MODULES=""
929 for module in $MODULES; do
930     LINK_MODULES="$LINK_MODULES -lmodule$module"
931 done
932 PRE_LIBRARIES="$LINK_MODULES $PRE_LIBRARIES"
933
934 # check if we're linking a sequential object
935 case "$LANGUAGE" in
936 "c"|"C"|"f90"|"f77")
937         Do $CMK_SEQ_LD $OPTS_LD -o $OBJECT $OBJECTFILES \
938                 -L$CHARMLIB $PRE_LIBRARIES $CMK_SEQ_LIBS $POST_LIBRARIES
939         Copyobj
940         ;;
941 "c++"|"C++")
942         Do $CMK_SEQ_LDXX $OPTS_LD -o $OBJECT $OBJECTFILES \
943                 -L$CHARMLIB $PRE_LIBRARIES $CMK_SEQ_LIBS $POST_LIBRARIES
944         Copyobj
945         ;;
946 esac
947
948 ##############################################################################
949 #
950 # Some quick consistency checks prior to full link-step
951 #
952 # Check for valid choice of TRACEMODE
953 # Check for valid choice of BALANCE
954 # Check for compatibility among BALANCE and TRACEMODE
955 #
956 ##############################################################################
957
958 Debug "About to check TRACEMODE=$TRACEMODE and BALANCE=$BALANCE..."
959
960 # Check for valid choice of TRACEMODE
961
962 [ -r $CHARMLIB/libtrace-projections.a ] || Abort "trace libraries not installed.  Is Charm++ built properly?"
963
964 if [ x"$TRACEMODE" != x ]
965 then
966 for trace in $TRACEMODE; do
967 [ ! -r "$CHARMLIB/libtrace-$trace.a" ] && Abort "charmc : No such tracemode $trace"
968 TRACE_OBJ="$TRACE_OBJ -ltrace-$trace"
969 done
970 fi
971
972 # Check for valid choice of BALANCE
973 if [ "$TRACEMODE" = replay ]
974 then
975         [ "$BALANCE" != replay ] && echo "Ignoring -balance $BALANCE, incompatible with -tracemode replay"
976     BALANCE=replay
977 fi
978
979 if test x$LANGUAGE = x"bgcharm++"
980 then 
981     BALANCE=bluegene
982 fi
983
984 BAL_EXT=`getExtention $BALANCE`
985 if [ -z "$BAL_EXT" ]
986 then
987 # Balance has no extention-- is a library reference
988     BAL_OBJ="$CHARMLIB/libldb-$BALANCE.o"
989 else
990 # Balance has some extention-- must be a .o or .a file
991     BAL_OBJ="$BALANCE"
992 fi
993
994 Debug "Finished with BAL_OBJ=$BAL_OBJ, TRACEMODE=$TRACEMODE..."
995
996 if [ ! -r "$BAL_OBJ" ]
997 then
998         if [ "$BALANCE" = "$BAL_OBJ" ]
999         then
1000                 Abort "Could not find load balancer object $BAL_OBJ"
1001         else
1002                 (cd $CHARMLIB ; ls -al libldb-*)
1003                 Abort "Unknown load balancer $BALANCE / $BAL_OBJ"
1004         fi
1005 fi
1006
1007
1008 # Check for valid choice of MEMORY
1009
1010 MEM_OBJ="$CHARMLIB/libmemory-$MEMORY.o"
1011
1012 [ ! -r $MEM_OBJ ] && Abort "charmc : No such memory mode $MEMORY"
1013
1014 ################# Build the module initialization function ##################
1015 modInitName="moduleinit"
1016 modInitSrc="$modInitName.C"
1017 modInitObj="$modInitName.o"
1018 DoNoErrCheck $RM $modInitSrc $modInitObj > /dev/null 2>&1
1019 for module in $MODULES; do
1020     echo "extern void _register$module(void);" >> $modInitSrc
1021 done
1022 for trace in $TRACEMODE; do
1023     if test $trace = "summary" || test $trace = "all"
1024     then
1025       echo "  extern void _registerTraceSummary();" >> $modInitSrc
1026     fi
1027 done
1028 if test -n "$BALANCER"
1029 then
1030     echo "extern void LBSetDefaultCreate(void (*fn)(void));" >> $modInitSrc
1031     echo "extern void Create$BALANCER();" >> $modInitSrc
1032 fi
1033 echo "void _registerExternalModules(char **argv) {" >> $modInitSrc
1034 for module in $MODULES; do
1035     [ -n "$VERBOSE" ] && echo "Adding registration for module $module"
1036     echo "  _register$module();" >> $modInitSrc
1037 done
1038 for trace in $TRACEMODE; do
1039     if test $trace = "summary" || test $trace = "all"
1040     then
1041       echo "  _registerTraceSummary();" >> $modInitSrc
1042     fi
1043 done
1044 if test -n "$BALANCER"
1045 then
1046     [ -n "$VERBOSE" ] && echo "Adding load balancer for $BALANCER"
1047     echo "  LBSetDefaultCreate(Create$BALANCER);" >> $modInitSrc
1048 fi
1049 echo "}" >> $modInitSrc
1050
1051 # creating projections
1052 echo "void _createTraces(char **argv) {" >> $modInitSrc
1053 for trace in $TRACEMODE; do
1054     [ -n "$VERBOSE" ] && echo "Adding registration for trace $trace"
1055     echo "extern void _createTrace$trace(char **argv);" >> $modInitSrc
1056     echo "_createTrace$trace(argv);" >> $modInitSrc
1057 done
1058 echo "}" >> $modInitSrc
1059
1060 Do $CMK_CXX $OPTS_CPP $OPTS_CXX -c $modInitSrc -o $modInitObj
1061
1062 ###############################################################################
1063 #
1064 #                               Finally, LINK
1065 #
1066 ###############################################################################
1067
1068 Debug "About to perform final link..."
1069
1070 LANG_LIBS="-L$CHARMLIB -I$CHARMINC $BAL_OBJ $OBJECTFILES $modInitObj $PRE_LIBRARIES"
1071 CORE_LIBS="$LINK_MODULES -lconv-core -lconv-util $TRACE_OBJ $MEM_OBJ "
1072
1073 case "$LANGUAGE" in
1074 "charm"|"charm++"|"f90charm"|"ckbluegene"|"bgcharm++")
1075         Do $CMK_LDXX $OPTS_LD $OPTS_LDXX -o $OBJECT \
1076                 $LANG_LIBS -lck -lconv-cplus-y $CORE_LIBS -lm $CMK_LIBS $POST_LIBRARIES
1077         ;;
1078 "converse")
1079         Do $CMK_LD $OPTS_LD -o $OBJECT \
1080                 $LANG_LIBS -lconv-cplus-n $CORE_LIBS -lm $CMK_LIBS $POST_LIBRARIES
1081         ;;
1082 "converse++"|"bluegene")
1083         Do $CMK_LDXX $OPTS_LD $OPTS_LDXX -o $OBJECT \
1084                 $LANG_LIBS -lconv-cplus-y $CORE_LIBS -lm $CMK_LIBS $POST_LIBRARIES
1085         ;;
1086 *)
1087         Abort "Unrecognized choice of language $LANGUAGE"
1088         ;;
1089 esac
1090
1091 ########################################################################
1092 #
1093 # Copy conv-host to user directory if it is present in installation.
1094 #
1095 ########################################################################
1096
1097 targ=charmrun$CMK_POST_EXE
1098 convhost=conv-host$CMK_POST_EXE
1099
1100 if [ -x $CHARMBIN/$targ ]
1101 then
1102         DoNoErrCheck $RM $targ
1103         Do $CP $CHARMBIN/$targ $targ
1104         [ ! -f $convhost ] && Do $LN -f -s $targ $convhost
1105 fi
1106
1107
1108 DoNoErrCheck $RM $modInitSrc $modInitObj > /dev/null 2>&1
1109
1110 Copyobj
1111
1112