6a5fe4cd3d7ee07581dea3d1103091f6bd5e204e
[nit.git] / bin / gccx
1 #!/bin/sh
2 # This file is part of NIT ( http://www.nitlanguage.org ).
3 #
4 # Copyright 2008 Jean Privat <jean@pryen.org>
5 #
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
9 #
10 #     http://www.apache.org/licenses/LICENSE-2.0
11 #
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
17
18 # Separately recompile a bunch of c files then link them
19
20 OPTS="-g" # option for compiler call
21 objs="" # List of .o files
22 CC="gcc --ansi --pedantic -Wall -Wextra -Wformat-security -Wcast-align -Wno-uninitialized -Wno-unused-variable -Wno-unused-label -Wno-unused-parameter -Wno-missing-field-initializers" # Default compiler call
23 ext="_savo _sav" # Default flavor to reuse
24 out="a.out"  # Default output binary filename
25 dir="" # Default tmp dir
26 nolibgc="true" # Disable boehm libgc?
27 CKSUM="cksum" # Tool that perfors checksum. cksum seems to be very portable
28 recompile="false"
29
30 usage()
31 {
32         e=`basename "$0"`
33         cat<<END
34 Usage: $e [options] modulename [options for module execution]
35 -R          Force full recompilation
36 -O          Compile with optimizations
37 -i          Use the intel compiler instead of gcc
38 -I path     Add a include directory
39 -o name     Call name the executable
40 -d          Create temporary files in a specific directory
41 -nolibgc    Do not include libgc
42 -v          Verbose (show compilation steps)
43 -vv         Verbose+ (show gcc calls)
44 -h          This help
45 END
46 }
47
48 test_libgc() {
49 cat > .tmp.c <<END
50 #include <stdlib.h>
51 #include <gc/gc.h>
52 int main(void) {
53         void *r = GC_malloc(1);
54                 return r == NULL;
55         }
56 END
57 gcc .tmp.c -lgc -o .tmp.bin 2> /dev/null
58 res=$?
59 rm .tmp.c
60 if [ $res = 0 ]; then
61         ./.tmp.bin
62         res=$?
63         rm .tmp.bin
64 fi
65 return $res
66 }
67
68 stop=false
69 verbose=false
70 vverbose=false
71 while [ $stop = false ]; do
72         case $1 in 
73                 -R) recompile=true; shift;;
74                 -O) OPTS="$OPTS -O2" ext="_savo"; shift;;
75                 -i) CC="/opt/intel/cc/10.1.015/bin/icc -O2" ext="_savi"; shift;;
76                 -I) OPTS="$OPTS -I $2"; shift; shift;;
77                 -o) out="$2"; shift; shift;;
78                 -d) dir="$2/"; shift; shift;;
79                 --nolibgc) nolibgc=true; shift;;
80                 -x) OPTS="$OPTS $2"; shift; shift;;
81                 -vv) vverbose=true; verbose=true; shift;;
82                 -v) verbose=true; shift;;
83                 -h|"") usage; exit;;
84                 *) stop=true
85         esac
86 done
87
88 if [ $nolibgc != true ] && test_libgc; then
89         OPTS="$OPTS -DWITH_LIBGC -lgc"
90 fi
91
92 for i in "$@"; do
93         j=`basename "$i" .c`
94         transformed=`echo "$i" | sed "
95                 /\.nit_compile\/.*_sep\.c/s/\.nit_compile\/\(.*\)\._sep\.c/Module \1/
96                 /\.nit_compile\/.*_glob\.c/s/\.nit_compile\/\(.*\)\._glob\.c/Module \1/
97                 /\.nit_compile[1-9]\/.*_sep\.c/s/\.nit_compile[1-9]\/\(.*\)\._sep\.c/Module \1/
98                 /\.nit_compile[1-9]\/.*_glob\.c/s/\.nit_compile[1-9]\/\(.*\)\._glob\.c/Module \1/
99                 /\/nit_main\.c/s/.*\/nit_main\.c/Main/
100                 /\.nit_compile\/.*\._tables\.c/s/.*/Tables/
101                 /\.nit_compile[1-9]\/.*\._tables\.c/s/.*/Tables/
102                 /\/\/.*_nit\.c/s/.*\/\/\(.*\)_nit.c/Native \1/
103                 s/.*\/gc.c/Garbage Collector/
104                 s/.*\/gc_static_objects_list.c/Garbage Collector object list/
105         "`
106
107         found="false"
108         # We remove starting # to be path independent (after preprocess, there are the only # remainings)
109         cksum=`gcc -E $OPTS $i 2> /dev/null | grep -v "^#" | $CKSUM`
110         for e in $ext; do
111                 o="$dir$j.$e.o"
112                 cksumfile="$dir$j.$e.cksum"
113                 if [ -f "$cksumfile" -a -f "$o" -a "x$recompile" != "xtrue" ]; then
114                         cksumtry=`cat $cksumfile`
115                         if [ "x$cksum" = "x$cksumtry" ]; then
116                                 if [ $vverbose = true  ] ; then
117                                         echo "* $transformed up-to-date"
118                                 fi
119                                 found=true
120                                 break
121                         fi
122                 fi
123         done
124         if [ $found = false ]; then
125                 if [ $verbose = true  ] ; then
126                         if [ $vverbose = true  ] ; then
127                                 echo "* $CC $OPTS -c $i -o $o" >&2
128                         else
129                                 echo "* $transformed"
130                         fi
131                 fi
132                 if $CC $OPTS -c $i -o $o; then
133                         echo "$cksum" > "$cksumfile"
134                 else
135                         exit 1
136                 fi
137         fi
138         objs="$objs $o"
139 done
140
141 if [ $vverbose = true  ] ; then
142         echo "* $CC $OPTS -lm $objs -o $out" >&2
143 fi
144 $CC $OPTS -lm $objs -o "$out"