1#!/bin/sh
2
3#~ Copyright 2002-2019 Rene Rivera.
4#~ Distributed under the Boost Software License, Version 1.0.
5#~ (See accompanying file LICENSE_1_0.txt or copy at
6#~ http://www.boost.org/LICENSE_1_0.txt)
7
8# Reset the toolset.
9B2_TOOLSET=
10B2_OS=
11
12# Run a command, and echo before doing so. Also checks the exit status and quits
13# if there was an error.
14echo_run ()
15{
16    echo "$@"
17    $@
18    r=$?
19    if test $r -ne 0 ; then
20        exit $r
21    fi
22}
23
24# Print an error message, and exit with a status of 1.
25error_exit ()
26{
27    echo "
28${@}
29
30You can specify the toolset as the argument, i.e.:
31    ./build.sh gcc
32
33Toolsets supported by this script are:
34    acc, clang, como, gcc, intel-darwin, intel-linux, kcc, kylix, mipspro,
35    pathscale, pgi, qcc, sun, sunpro, tru64cxx, vacpp
36
37For any toolset you can override the path to the compiler with the CXX
38environment variable. You can also use additional flags for the compiler
39with the CXXFLAGS environment variable.
40
41A special toolset; cxx, is available which is used as a fallback when a more
42specific toolset is not found and the cxx command is detected. The 'cxx'
43toolset will use the CXX, CXXFLAGS, and LIBS environment variables, if present.
44
45Similarly, the cross-cxx toolset is available for cross-compiling by using the
46BUILD_CXX, BUILD_CXXFLAGS, and BUILD_LDFLAGS environment variables to compile
47binaries that will be executed on the build system. This allows CXX etc. to be
48set for cross-compilers to be propagated to subprocesses.
49"
50    exit 1
51}
52
53# Check that a command is in the PATH.
54test_path ()
55{
56    if `command -v command 1>/dev/null 2>/dev/null`; then
57        command -v $1 1>/dev/null 2>/dev/null
58    else
59        hash $1 1>/dev/null 2>/dev/null
60    fi
61}
62
63# Check that the OS name, as returned by "uname", is as given.
64test_uname ()
65{
66    if test_path uname; then
67        test `uname` = $*
68    fi
69}
70
71# Try and guess the toolset to bootstrap the build with...
72guess_toolset ()
73{
74    if test_uname Darwin ; then B2_TOOLSET=clang
75    elif test_uname IRIX ; then B2_TOOLSET=mipspro
76    elif test_uname IRIX64 ; then B2_TOOLSET=mipspro
77    elif test_uname OSF1 ; then B2_TOOLSET=tru64cxx
78    elif test_uname QNX && test_path QCC ; then B2_TOOLSET=qcc
79    elif test_uname Linux && test_path xlC_r; then
80       if /usr/bin/lscpu | grep Byte | grep Little > /dev/null 2>&1 ; then
81          # Little endian linux
82          B2_TOOLSET=xlcpp
83       else
84          #Big endian linux
85          B2_TOOLSET=vacpp
86       fi
87    elif test_uname AIX && test_path xlC_r; then B2_TOOLSET=vacpp
88    elif test_uname FreeBSD && test_path freebsd-version && test_path clang++; then B2_TOOLSET=clang
89    elif test_path g++ ; then B2_TOOLSET=gcc
90    elif test_path clang++ ; then B2_TOOLSET=clang
91    elif test_path icc ; then B2_TOOLSET=intel-linux
92    elif test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then
93        B2_TOOLSET=intel-linux
94        B2_TOOLSET_ROOT=/opt/intel/cc/9.0
95    elif test -r /opt/intel_cc_80/bin/iccvars.sh ; then
96        B2_TOOLSET=intel-linux
97        B2_TOOLSET_ROOT=/opt/intel_cc_80
98    elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then
99        B2_TOOLSET=intel-linux
100        B2_TOOLSET_ROOT=/opt/intel/compiler70/ia32/
101    elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then
102        B2_TOOLSET=intel-linux
103        B2_TOOLSET_ROOT=/opt/intel/compiler60/ia32/
104    elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then
105        B2_TOOLSET=intel-linux
106        B2_TOOLSET_ROOT=/opt/intel/compiler50/ia32/
107    elif test_path pgc++ ; then B2_TOOLSET=pgi
108    elif test_path pathCC ; then B2_TOOLSET=pathscale
109    elif test_path como ; then B2_TOOLSET=como
110    elif test_path KCC ; then B2_TOOLSET=kcc
111    elif test_path bc++ ; then B2_TOOLSET=kylix
112    elif test_path aCC ; then B2_TOOLSET=acc
113    elif test_uname HP-UX ; then B2_TOOLSET=acc
114    elif test -r /opt/SUNWspro/bin/cc ; then
115        B2_TOOLSET=sunpro
116        B2_TOOLSET_ROOT=/opt/SUNWspro/
117    # Test for some common compile command as the default fallback.
118    elif test_path $CXX ; then B2_TOOLSET=cxx
119    elif test_path cxx ; then
120        B2_TOOLSET=cxx
121        CXX=cxx
122    elif test_path cpp ; then
123        B2_TOOLSET=cxx
124        CXX=cpp
125    elif test_path CC ; then
126        B2_TOOLSET=cxx
127        CXX=CC
128    fi
129    if test "$B2_TOOLSET" = "" ; then
130        error_exit "Could not find a suitable toolset."
131    fi
132}
133
134check_debug_build ()
135{
136    while test $# -gt 0
137    do
138        case "$1" in
139            --debug) return 0 ;;
140        esac
141        shift
142    done
143    return 1
144}
145
146# The one option we support in the invocation
147# is the name of the toolset to force building
148# with.
149case "$1" in
150    --guess-toolset) guess_toolset ; echo "$B2_TOOLSET" ; exit 1 ;;
151    -*) guess_toolset ;;
152    ?*) B2_TOOLSET=$1 ; shift ;;
153    *) guess_toolset ;;
154esac
155case $B2_TOOLSET in
156
157    gcc)
158        CXX=${CXX:=g++}
159        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
160        # Check whether it's MinGW GCC, which has Windows headers and none of POSIX ones.
161        machine=$(${CXX} -dumpmachine 2>/dev/null)
162        if [ $? -ne 0 ]; then
163            echo "B2_TOOLSET is gcc, but the 'gcc' command cannot be executed."
164            echo "Make sure 'gcc' is in PATH, or use a different toolset."
165            exit 1
166        fi
167        case $machine in
168        *mingw*)
169        # MinGW insists that its bin directory be in PATH.
170        if test -r ${B2_TOOLSET_ROOT}bin/gcc ; then
171            export PATH=${B2_TOOLSET_ROOT}bin:$PATH
172        fi
173        B2_CXX="${CXX} -x c++ -std=c++11"
174        B2_CXXFLAGS_RELEASE="-O2 -s"
175        B2_CXXFLAGS_DEBUG="-O0 -g"
176        B2_OS="NT"
177        ;;
178
179        *cygwin*)
180        B2_CXX="${CXX} -x c++ -std=gnu11"
181        B2_CXXFLAGS_RELEASE="-O2 -s"
182        B2_CXXFLAGS_DEBUG="-O0 -g"
183        ;;
184
185        *)
186        B2_CXX="${CXX} -x c++ -std=c++11"
187        B2_CXXFLAGS_RELEASE="-O2 -s"
188        B2_CXXFLAGS_DEBUG="-O0 -g"
189        esac
190    ;;
191
192    intel-darwin)
193        CXX=${CXX:=icc}
194        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
195        B2_CXX="${CXX} -xc++"
196        B2_CXXFLAGS_RELEASE="-O3 -s"
197        B2_CXXFLAGS_DEBUG="-O0 -g -p"
198    ;;
199
200    intel-linux)
201        CXX=${CXX:=icc}
202        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
203        test_path ${CXX} >/dev/null 2>&1
204        if test $? ; then
205            echo "Found ${CXX} in environment"
206            B2_TOOLSET_ROOT=`echo ${CXX}| sed -e 's/bin.*\/icc//'`
207            # probably the most widespread
208            ARCH=intel64
209        else
210            echo "No intel compiler in current path"
211            echo "Look in a few old place for legacy reason"
212            if test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then
213                B2_TOOLSET_ROOT=/opt/intel/cc/9.0/
214            elif test -r /opt/intel_cc_80/bin/iccvars.sh ; then
215                B2_TOOLSET_ROOT=/opt/intel_cc_80/
216            elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then
217                B2_TOOLSET_ROOT=/opt/intel/compiler70/ia32/
218            elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then
219                B2_TOOLSET_ROOT=/opt/intel/compiler60/ia32/
220            elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then
221                B2_TOOLSET_ROOT=/opt/intel/compiler50/ia32/
222            fi
223        fi
224        if test -r ${B2_TOOLSET_ROOT}bin/iccvars.sh ; then
225            # iccvars does not change LD_RUN_PATH. We adjust LD_RUN_PATH here in
226            # order not to have to rely on ld.so.conf knowing the icc library
227            # directory. We do this before running iccvars.sh in order to allow a
228            # user to add modifications to LD_RUN_PATH in iccvars.sh.
229            if test -z "${LD_RUN_PATH}"; then
230                LD_RUN_PATH="${B2_TOOLSET_ROOT}lib"
231            else
232                LD_RUN_PATH="${B2_TOOLSET_ROOT}lib:${LD_RUN_PATH}"
233            fi
234            export LD_RUN_PATH
235            . ${B2_TOOLSET_ROOT}bin/iccvars.sh $ARCH
236        fi
237        B2_CXX="${CXX} -xc++"
238        B2_CXXFLAGS_RELEASE="-O3 -s"
239        B2_CXXFLAGS_DEBUG="-O0 -g -p"
240    ;;
241
242    vacpp)
243        CXX=${CXX:=xlC_r}
244        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
245        B2_CXX="${CXX}"
246        B2_CXXFLAGS_RELEASE="-O3 -s -qstrict -qinline"
247        B2_CXXFLAGS_DEBUG="-g -qNOOPTimize -qnoinline -pg"
248    ;;
249
250    xlcpp)
251        CXX=${CXX:=xlC_r}
252        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
253        B2_CXX="${CXX}"
254        B2_CXXFLAGS_RELEASE="-s -O3 -qstrict -qinline"
255        B2_CXXFLAGS_DEBUG="-g -qNOOPTimize -qnoinline -pg"
256    ;;
257
258    como)
259        CXX=${CXX:=como}
260        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
261        B2_CXX="${CXX}"
262        B2_CXXFLAGS_RELEASE="-O3 --inlining"
263        B2_CXXFLAGS_DEBUG="-O0 -g --no_inlining --long_long"
264    ;;
265
266    kcc)
267        CXX=${CXX:=KCC}
268        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
269        B2_CXX="KCC"
270        B2_CXXFLAGS_RELEASE="+K2 -s"
271        B2_CXXFLAGS_DEBUG="+K0 -g"
272    ;;
273
274    kylix)
275        CXX=${CXX:=bc++}
276        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
277        B2_CXX="bc++ -tC -q"
278        B2_CXXFLAGS_RELEASE="-O2 -vi -w-inl -s"
279        B2_CXXFLAGS_DEBUG="-Od -v -vi-"
280    ;;
281
282    mipspro)
283        CXX=${CXX:=CC}
284        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
285        B2_CXX="${CXX} -FE:template_in_elf_section -ptused"
286        B2_CXXFLAGS_RELEASE="-Ofast -g0 \"-INLINE:none\" -s"
287        B2_CXXFLAGS_DEBUG="-O0 -INLINE -g"
288    ;;
289
290    pathscale)
291        CXX=${CXX:=pathCC}
292        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
293        B2_CXX="${CXX}"
294        B2_CXXFLAGS_RELEASE="-O3 -inline -s"
295        B2_CXXFLAGS_DEBUG="-O0 -noinline -ggdb"
296    ;;
297
298    pgi)
299        CXX=${CXX:=pgc++}
300        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
301        B2_CXX="${CXX} -std=c++11"
302        B2_CXXFLAGS_RELEASE="-fast -s"
303        B2_CXXFLAGS_DEBUG="-O0 -gopt"
304    ;;
305
306    sun*)
307        CXX=${CXX:=CC}
308        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
309        if test -z "${B2_TOOLSET_ROOT}" -a -r /opt/SUNWspro/bin/CC ; then
310            B2_TOOLSET_ROOT=/opt/SUNWspro/
311        fi
312        if test -r "${B2_TOOLSET_ROOT}/bin/CC" ; then
313            PATH=${B2_TOOLSET_ROOT}bin:${PATH}
314            export PATH
315        fi
316        B2_CXX="${CXX}"
317        B2_CXXFLAGS_RELEASE="-xO4 -s"
318        B2_CXXFLAGS_DEBUG="-g"
319    ;;
320
321    clang*)
322        CXX=${CXX:=clang++}
323        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
324        B2_CXX="${CXX} -x c++ -O3 -std=c++11"
325        B2_TOOLSET=clang
326        B2_CXXFLAGS_RELEASE="-O3 -s"
327        B2_CXXFLAGS_DEBUG="-O0 -fno-inline -g"
328    ;;
329
330    tru64cxx)
331        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
332        B2_CXX="cc"
333        B2_CXXFLAGS_RELEASE="-O5 -inline speed -s"
334        B2_CXXFLAGS_DEBUG="-O0 -pg -g"
335    ;;
336
337    acc)
338        CXX=${CXX:=aCC}
339        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
340        B2_CXX="${CXX} -AA"
341        B2_CXXFLAGS_RELEASE="-O3 -s"
342        B2_CXXFLAGS_DEBUG="+d -g"
343    ;;
344
345    qcc)
346        CXX=${CXX:=QCC}
347        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
348        B2_CXX="${CXX}"
349        B2_CXXFLAGS_RELEASE="-O3 -Wc,-finline-functions"
350        B2_CXXFLAGS_DEBUG="O0 -Wc,-fno-inline -gstabs+"
351    ;;
352
353    cxx)
354        CXX=${CXX:=cxx}
355        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
356        B2_CXX="${CXX}"
357    ;;
358
359    cross-cxx)
360        CXX=${BUILD_CXX:=cxx}
361        CXXFLAGS=${BUILD_CXXFLAGS}
362        CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version}
363        B2_CXX="${CXX}"
364    ;;
365
366    *)
367        error_exit "Unknown toolset: $B2_TOOLSET"
368    ;;
369esac
370
371echo "###"
372echo "###"
373echo "### Using '$B2_TOOLSET' toolset."
374echo "###"
375echo "###"
376echo_run ${CXX} ${CXX_VERSION_OPT}
377echo "###"
378echo "###"
379B2_SOURCES="\
380 builtins.cpp \
381 class.cpp \
382 command.cpp \
383 compile.cpp \
384 constants.cpp \
385 cwd.cpp \
386 debug.cpp \
387 debugger.cpp \
388 execcmd.cpp \
389 filesys.cpp \
390 frames.cpp \
391 function.cpp \
392 glob.cpp\
393 hash.cpp \
394 hcache.cpp \
395 hdrmacro.cpp \
396 headers.cpp \
397 jam.cpp \
398 jambase.cpp \
399 jamgram.cpp \
400 lists.cpp \
401 make.cpp \
402 make1.cpp \
403 md5.cpp \
404 mem.cpp \
405 modules.cpp \
406 native.cpp \
407 object.cpp \
408 option.cpp \
409 output.cpp \
410 parse.cpp \
411 pathsys.cpp \
412 regexp.cpp \
413 rules.cpp \
414 scan.cpp \
415 search.cpp \
416 strings.cpp \
417 subst.cpp \
418 sysinfo.cpp \
419 timestamp.cpp \
420 variable.cpp \
421 w32_getreg.cpp \
422 modules/order.cpp \
423 modules/path.cpp \
424 modules/property-set.cpp \
425 modules/regex.cpp \
426 modules/sequence.cpp \
427 modules/set.cpp \
428 "
429case $B2_OS in
430    NT)
431    B2_SOURCES="${B2_SOURCES} execnt.cpp filent.cpp pathnt.cpp"
432    ;;
433
434    *)
435    B2_SOURCES="${B2_SOURCES} execunix.cpp fileunix.cpp pathunix.cpp"
436    ;;
437esac
438
439if check_debug_build "$@" ; then B2_CXXFLAGS="${B2_CXXFLAGS_DEBUG}"
440else B2_CXXFLAGS="${B2_CXXFLAGS_RELEASE} -DNDEBUG"
441fi
442echo_run ${B2_CXX} ${CXXFLAGS} ${B2_CXXFLAGS} ${B2_SOURCES} -o b2
443echo_run cp b2 bjam
444