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" 1>&2 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# Check that the given command runs. 72test_exec () 73{ 74 "$*" 1>/dev/null 2>/dev/null 75} 76 77# Check that the compiler can do C++11. 78test_cxx11 () 79{ 80 if ! test $NO_CXX11_CHECK ; then 81 case $1 in 82 gcc) ( ${CXX:=g++} -x c++ -std=c++11 check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 83 intel-darwin) ( ${CXX:=icc} -xc++ check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 84 intel-linux) ( ${CXX:=icc} -xc++ check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 85 vacpp) ( ${CXX:=xlC_r} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 86 xlcpp) ( ${CXX:=xlC_r} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 87 como) ( ${CXX:=como} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 88 kcc) ( ${CXX:=KCC} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 89 kylix) ( ${CXX:=bc++} -tC -q check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 90 mipspro) ( ${CXX:=CC} -FE:template_in_elf_section -ptused check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 91 pathscale) ( ${CXX:=pathCC} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 92 pgi) ( ${CXX:=pgc++} -std=c++11 check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 93 sun*) ( ${CXX:=CC} -std=c++11 check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 94 clang*) ( ${CXX:=clang++} -x c++ -std=c++11 check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 95 tru64cxx) ( ${CXX:=cc} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 96 acc) ( ${CXX:=aCC} -AA check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 97 qcc) ( ${CXX:=QCC} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 98 cxx) ( ${CXX:=cxx} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 99 cross-cxx) ( ${CXX:=cxx} check_cxx11.cpp && rm -f a.out ) 1>/dev/null 2>/dev/null ;; 100 *) test "0" = "1" ;; 101 esac 102 else 103 test $NO_CXX11_CHECK 104 fi 105} 106 107# Try and guess the toolset to bootstrap the build with... 108guess_toolset () 109{ 110 if test_uname Darwin && test_cxx11 clang ; then B2_TOOLSET=clang 111 elif test_uname IRIX && test_cxx11 mipspro ; then B2_TOOLSET=mipspro 112 elif test_uname IRIX64 && test_cxx11 mipspro ; then B2_TOOLSET=mipspro 113 elif test_uname OSF1 && test_cxx11 tru64cxx ; then B2_TOOLSET=tru64cxx 114 elif test_uname QNX && test_path QCC && test_cxx11 qcc ; then B2_TOOLSET=qcc 115 elif test_uname Linux && test_path xlC_r ; then 116 if /usr/bin/lscpu | grep Byte | grep Little > /dev/null 2>&1 ; then 117 # Little endian linux 118 B2_TOOLSET=xlcpp 119 else 120 #Big endian linux 121 B2_TOOLSET=vacpp 122 fi 123 elif test_uname AIX && test_path xlC_r && test_cxx11 vacpp ; then B2_TOOLSET=vacpp 124 elif test_uname FreeBSD && test_path freebsd-version && test_path clang++ && test_cxx11 clang ; then B2_TOOLSET=clang 125 elif test_path g++ && test_cxx11 gcc ; then B2_TOOLSET=gcc 126 elif test_path clang++ && test_cxx11 clang ; then B2_TOOLSET=clang 127 elif test_path icc && test_cxx11 intel-linux ; then B2_TOOLSET=intel-linux 128 elif test -r /opt/intel/cc/9.0/bin/iccvars.sh && test_cxx11 intel-linux ; then 129 B2_TOOLSET=intel-linux 130 B2_TOOLSET_ROOT=/opt/intel/cc/9.0 131 elif test -r /opt/intel_cc_80/bin/iccvars.sh && test_cxx11 intel-linux ; then 132 B2_TOOLSET=intel-linux 133 B2_TOOLSET_ROOT=/opt/intel_cc_80 134 elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh && test_cxx11 intel-linux ; then 135 B2_TOOLSET=intel-linux 136 B2_TOOLSET_ROOT=/opt/intel/compiler70/ia32/ 137 elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh && test_cxx11 intel-linux ; then 138 B2_TOOLSET=intel-linux 139 B2_TOOLSET_ROOT=/opt/intel/compiler60/ia32/ 140 elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh && test_cxx11 intel-linux ; then 141 B2_TOOLSET=intel-linux 142 B2_TOOLSET_ROOT=/opt/intel/compiler50/ia32/ 143 elif test_path pgc++ && test_cxx11 pgi ; then B2_TOOLSET=pgi 144 elif test_path pathCC && test_cxx11 pathscale ; then B2_TOOLSET=pathscale 145 elif test_path como && test_cxx11 como ; then B2_TOOLSET=como 146 elif test_path KCC && test_cxx11 kcc ; then B2_TOOLSET=kcc 147 elif test_path bc++ && test_cxx11 kylix ; then B2_TOOLSET=kylix 148 elif test_path aCC && test_cxx11 acc ; then B2_TOOLSET=acc 149 elif test_uname HP-UX ; then B2_TOOLSET=acc 150 elif test -r /opt/SUNWspro/bin/cc && test_cxx11 sunpro ; then 151 B2_TOOLSET=sunpro 152 B2_TOOLSET_ROOT=/opt/SUNWspro/ 153 # Test for some common compile command as the default fallback. 154 elif test_path $CXX ; then B2_TOOLSET=cxx 155 elif test_path cxx ; then 156 B2_TOOLSET=cxx 157 CXX=cxx 158 elif test_path cpp ; then 159 B2_TOOLSET=cxx 160 CXX=cpp 161 elif test_path CC ; then 162 B2_TOOLSET=cxx 163 CXX=CC 164 fi 165 if test "$B2_TOOLSET" = "" ; then 166 error_exit "Could not find a suitable toolset." 167 fi 168} 169 170check_debug_build () 171{ 172 while test $# -gt 0 173 do 174 case "$1" in 175 --debug) return 0 ;; 176 esac 177 shift 178 done 179 return 1 180} 181 182# The one option we support in the invocation 183# is the name of the toolset to force building 184# with. 185case "$1" in 186 --guess-toolset) NO_CXX11_CHECK=1 ; guess_toolset ; echo "$B2_TOOLSET" ; exit 1 ;; 187 -*) guess_toolset ;; 188 ?*) B2_TOOLSET=$1 ; shift ;; 189 *) guess_toolset ;; 190esac 191 192# We need a C++11 compiler. Check here and given some feedback about it. 193if ! test_cxx11 $B2_TOOLSET ; then 194 error_exit " 195A C++11 capable compiler is required for building the B2 engine. 196Toolset '$B2_TOOLSET' does not appear to support C++11. 197 198** Note, the C++11 capable compiler is _only_ required for building the B2 199** engine. The B2 build system allows for using any C++ level and any other 200** supported language and resource in your projects. 201" 202fi 203 204case $B2_TOOLSET in 205 206 gcc) 207 CXX=${CXX:=g++} 208 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 209 # Check whether it's MinGW GCC, which has Windows headers and none of POSIX ones. 210 machine=$(${CXX} -dumpmachine 2>/dev/null) 211 if test $? -ne 0 ; then 212 echo "B2_TOOLSET is gcc, but the 'gcc' command cannot be executed." 213 echo "Make sure 'gcc' is in PATH, or use a different toolset." 214 exit 1 215 fi 216 case $machine in 217 *mingw*) 218 # MinGW insists that its bin directory be in PATH. 219 if test -r ${B2_TOOLSET_ROOT}bin/gcc ; then 220 export PATH=${B2_TOOLSET_ROOT}bin:$PATH 221 fi 222 B2_CXX="${CXX} -x c++ -std=c++11" 223 B2_CXXFLAGS_RELEASE="-O2 -s" 224 B2_CXXFLAGS_DEBUG="-O0 -g" 225 B2_OS="NT" 226 ;; 227 228 *cygwin*) 229 B2_CXX="${CXX} -x c++ -std=gnu++11" 230 B2_CXXFLAGS_RELEASE="-O2 -s" 231 B2_CXXFLAGS_DEBUG="-O0 -g" 232 ;; 233 234 *) 235 B2_CXX="${CXX} -x c++ -std=c++11" 236 B2_CXXFLAGS_RELEASE="-O2 -s" 237 B2_CXXFLAGS_DEBUG="-O0 -g" 238 esac 239 ;; 240 241 intel-darwin) 242 CXX=${CXX:=icc} 243 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 244 B2_CXX="${CXX} -xc++" 245 B2_CXXFLAGS_RELEASE="-O3 -s" 246 B2_CXXFLAGS_DEBUG="-O0 -g -p" 247 ;; 248 249 intel-linux) 250 CXX=${CXX:=icc} 251 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 252 test_path ${CXX} >/dev/null 2>&1 253 if test $? ; then 254 echo "Found ${CXX} in environment" 255 B2_TOOLSET_ROOT=`echo ${CXX}| sed -e 's/bin.*\/icc//'` 256 # probably the most widespread 257 ARCH=intel64 258 else 259 echo "No intel compiler in current path" 260 echo "Look in a few old place for legacy reason" 261 if test -r /opt/intel/cc/9.0/bin/iccvars.sh ; then 262 B2_TOOLSET_ROOT=/opt/intel/cc/9.0/ 263 elif test -r /opt/intel_cc_80/bin/iccvars.sh ; then 264 B2_TOOLSET_ROOT=/opt/intel_cc_80/ 265 elif test -r /opt/intel/compiler70/ia32/bin/iccvars.sh ; then 266 B2_TOOLSET_ROOT=/opt/intel/compiler70/ia32/ 267 elif test -r /opt/intel/compiler60/ia32/bin/iccvars.sh ; then 268 B2_TOOLSET_ROOT=/opt/intel/compiler60/ia32/ 269 elif test -r /opt/intel/compiler50/ia32/bin/iccvars.sh ; then 270 B2_TOOLSET_ROOT=/opt/intel/compiler50/ia32/ 271 fi 272 fi 273 if test -r ${B2_TOOLSET_ROOT}bin/iccvars.sh ; then 274 # iccvars does not change LD_RUN_PATH. We adjust LD_RUN_PATH here in 275 # order not to have to rely on ld.so.conf knowing the icc library 276 # directory. We do this before running iccvars.sh in order to allow a 277 # user to add modifications to LD_RUN_PATH in iccvars.sh. 278 if test -z "${LD_RUN_PATH}"; then 279 LD_RUN_PATH="${B2_TOOLSET_ROOT}lib" 280 else 281 LD_RUN_PATH="${B2_TOOLSET_ROOT}lib:${LD_RUN_PATH}" 282 fi 283 export LD_RUN_PATH 284 . ${B2_TOOLSET_ROOT}bin/iccvars.sh $ARCH 285 fi 286 B2_CXX="${CXX} -xc++" 287 B2_CXXFLAGS_RELEASE="-O3 -s" 288 B2_CXXFLAGS_DEBUG="-O0 -g -p" 289 ;; 290 291 vacpp) 292 CXX=${CXX:=xlC_r} 293 CXX_VERSION_OPT=${CXX_VERSION_OPT:=-qversion} 294 B2_CXX="${CXX}" 295 B2_CXXFLAGS_RELEASE="-O3 -s -qstrict -qinline" 296 B2_CXXFLAGS_DEBUG="-g -qNOOPTimize -qnoinline -pg" 297 ;; 298 299 xlcpp) 300 CXX=${CXX:=xlC_r} 301 CXX_VERSION_OPT=${CXX_VERSION_OPT:=-qversion} 302 B2_CXX="${CXX}" 303 B2_CXXFLAGS_RELEASE="-s -O3 -qstrict -qinline" 304 B2_CXXFLAGS_DEBUG="-g -qNOOPTimize -qnoinline -pg" 305 ;; 306 307 como) 308 CXX=${CXX:=como} 309 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 310 B2_CXX="${CXX}" 311 B2_CXXFLAGS_RELEASE="-O3 --inlining" 312 B2_CXXFLAGS_DEBUG="-O0 -g --no_inlining --long_long" 313 ;; 314 315 kcc) 316 CXX=${CXX:=KCC} 317 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 318 B2_CXX="KCC" 319 B2_CXXFLAGS_RELEASE="+K2 -s" 320 B2_CXXFLAGS_DEBUG="+K0 -g" 321 ;; 322 323 kylix) 324 CXX=${CXX:=bc++} 325 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 326 B2_CXX="bc++ -tC -q" 327 B2_CXXFLAGS_RELEASE="-O2 -vi -w-inl -s" 328 B2_CXXFLAGS_DEBUG="-Od -v -vi-" 329 ;; 330 331 mipspro) 332 CXX=${CXX:=CC} 333 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 334 B2_CXX="${CXX} -FE:template_in_elf_section -ptused" 335 B2_CXXFLAGS_RELEASE="-Ofast -g0 \"-INLINE:none\" -s" 336 B2_CXXFLAGS_DEBUG="-O0 -INLINE -g" 337 ;; 338 339 pathscale) 340 CXX=${CXX:=pathCC} 341 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 342 B2_CXX="${CXX}" 343 B2_CXXFLAGS_RELEASE="-O3 -inline -s" 344 B2_CXXFLAGS_DEBUG="-O0 -noinline -ggdb" 345 ;; 346 347 pgi) 348 CXX=${CXX:=pgc++} 349 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 350 B2_CXX="${CXX} -std=c++11" 351 B2_CXXFLAGS_RELEASE="-fast -s" 352 B2_CXXFLAGS_DEBUG="-O0 -gopt" 353 ;; 354 355 sun*) 356 CXX=${CXX:=CC} 357 CXX_VERSION_OPT=${CXX_VERSION_OPT:=-V} 358 if test -z "${B2_TOOLSET_ROOT}" -a -r /opt/SUNWspro/bin/CC ; then 359 B2_TOOLSET_ROOT=/opt/SUNWspro/ 360 fi 361 if test -r "${B2_TOOLSET_ROOT}/bin/CC" ; then 362 PATH=${B2_TOOLSET_ROOT}bin:${PATH} 363 export PATH 364 fi 365 B2_CXX="${CXX} -std=c++11" 366 B2_CXXFLAGS_RELEASE="-xO4 -s" 367 B2_CXXFLAGS_DEBUG="-g" 368 ;; 369 370 clang*) 371 CXX=${CXX:=clang++} 372 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 373 B2_CXX="${CXX} -x c++ -std=c++11" 374 B2_TOOLSET=clang 375 B2_CXXFLAGS_RELEASE="-O3 -s" 376 B2_CXXFLAGS_DEBUG="-O0 -fno-inline -g" 377 ;; 378 379 tru64cxx) 380 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 381 B2_CXX="cc" 382 B2_CXXFLAGS_RELEASE="-O5 -inline speed -s" 383 B2_CXXFLAGS_DEBUG="-O0 -pg -g" 384 ;; 385 386 acc) 387 CXX=${CXX:=aCC} 388 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 389 B2_CXX="${CXX} -AA" 390 B2_CXXFLAGS_RELEASE="-O3 -s" 391 B2_CXXFLAGS_DEBUG="+d -g" 392 ;; 393 394 qcc) 395 CXX=${CXX:=QCC} 396 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 397 B2_CXX="${CXX}" 398 B2_CXXFLAGS_RELEASE="-O3 -Wc,-finline-functions" 399 B2_CXXFLAGS_DEBUG="O0 -Wc,-fno-inline -gstabs+" 400 ;; 401 402 cxx) 403 CXX=${CXX:=cxx} 404 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 405 B2_CXX="${CXX}" 406 ;; 407 408 cross-cxx) 409 CXX=${BUILD_CXX:=cxx} 410 CXXFLAGS=${BUILD_CXXFLAGS} 411 CXX_VERSION_OPT=${CXX_VERSION_OPT:=--version} 412 B2_CXX="${CXX}" 413 ;; 414 415 *) 416 error_exit "Unknown toolset: $B2_TOOLSET" 417 ;; 418esac 419 420echo " 421### 422### 423### Using '$B2_TOOLSET' toolset. 424### 425### 426" 427echo_run ${CXX} ${CXX_VERSION_OPT} 428echo " 429### 430### 431" 432B2_SOURCES="\ 433 builtins.cpp \ 434 class.cpp \ 435 command.cpp \ 436 compile.cpp \ 437 constants.cpp \ 438 cwd.cpp \ 439 debug.cpp \ 440 debugger.cpp \ 441 execcmd.cpp \ 442 filesys.cpp \ 443 frames.cpp \ 444 function.cpp \ 445 glob.cpp\ 446 hash.cpp \ 447 hcache.cpp \ 448 hdrmacro.cpp \ 449 headers.cpp \ 450 jam.cpp \ 451 jamgram.cpp \ 452 lists.cpp \ 453 make.cpp \ 454 make1.cpp \ 455 md5.cpp \ 456 mem.cpp \ 457 modules.cpp \ 458 native.cpp \ 459 object.cpp \ 460 option.cpp \ 461 output.cpp \ 462 parse.cpp \ 463 pathsys.cpp \ 464 regexp.cpp \ 465 rules.cpp \ 466 scan.cpp \ 467 search.cpp \ 468 jam_strings.cpp \ 469 startup.cpp \ 470 subst.cpp \ 471 sysinfo.cpp \ 472 timestamp.cpp \ 473 variable.cpp \ 474 w32_getreg.cpp \ 475 modules/order.cpp \ 476 modules/path.cpp \ 477 modules/property-set.cpp \ 478 modules/regex.cpp \ 479 modules/sequence.cpp \ 480 modules/set.cpp \ 481 " 482case $B2_OS in 483 NT) 484 B2_SOURCES="${B2_SOURCES} execnt.cpp filent.cpp pathnt.cpp" 485 ;; 486 487 *) 488 B2_SOURCES="${B2_SOURCES} execunix.cpp fileunix.cpp pathunix.cpp" 489 ;; 490esac 491 492if check_debug_build "$@" ; then B2_CXXFLAGS="${B2_CXXFLAGS_DEBUG}" 493else B2_CXXFLAGS="${B2_CXXFLAGS_RELEASE} -DNDEBUG" 494fi 495echo_run ${B2_CXX} ${CXXFLAGS} ${B2_CXXFLAGS} ${B2_SOURCES} -o b2 496echo_run cp b2 bjam 497