1# 2# Copyright (C) 2011 The Android Open Source Project 3# 4# Licensed under the Apache License, Version 2.0 (the "License"); 5# you may not use this file except in compliance with the License. 6# You may obtain a copy of the License at 7# 8# http://www.apache.org/licenses/LICENSE-2.0 9# 10# Unless required by applicable law or agreed to in writing, software 11# distributed under the License is distributed on an "AS IS" BASIS, 12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13# See the License for the specific language governing permissions and 14# limitations under the License. 15# 16# This file contains various shell function definitions that can be 17# used to either build a static and shared libraries from sources, or 18# generate a Makefile to do it in parallel. 19# 20 21_BUILD_TAB=$(echo " " | tr ' ' '\t') 22 23builder_command () 24{ 25 if [ -z "$_BUILD_MK" ]; then 26 if [ "$VERBOSE2" = "yes" ]; then 27 echo "$@" 28 fi 29 "$@" 30 else 31 echo "${_BUILD_TAB}${_BUILD_HIDE}$@" >> $_BUILD_MK 32 fi 33} 34 35 36builder_log () 37{ 38 if [ "$_BUILD_MK" ]; then 39 echo "${_BUILD_TAB}${_BUILD_HIDE}echo $@" >> $_BUILD_MK 40 else 41 log "$@" 42 fi 43} 44 45# $1: Build directory 46# $2: Optional Makefile name 47builder_begin () 48{ 49 _BUILD_DIR_NEW= 50 _BUILD_DIR=$1 51 if [ ! -d "$_BUILD_DIR" ]; then 52 mkdir -p "$_BUILD_DIR" 53 fail_panic "Can't create build directory: $_BUILD_DIR" 54 _BUILD_DIR_NEW=true 55 else 56 rm -rf "$_BUILD_DIR/*" 57 fail_panic "Can't cleanup build directory: $_BUILD_DIR" 58 fi 59 _BUILD_TARGETS= 60 _BUILD_PREFIX= 61 _BUILD_MK=$2 62 if [ -n "$_BUILD_MK" ]; then 63 log "Creating temporary build Makefile: $_BUILD_MK" 64 rm -f $_BUILD_MK && 65 echo "# Auto-generated by $0 - do not edit!" > $_BUILD_MK 66 echo ".PHONY: all" >> $_BUILD_MK 67 echo "all:" >> $_BUILD_MK 68 fi 69 # HIDE is used to hide the Makefile output, unless --verbose --verbose 70 # is used. 71 if [ "$VERBOSE2" = "yes" ]; then 72 _BUILD_HIDE="" 73 else 74 _BUILD_HIDE=@ 75 fi 76 77 builder_begin_module 78} 79 80# $1: Variable name 81# out: Variable value 82_builder_varval () 83{ 84 eval echo "\$$1" 85} 86 87_builder_varadd () 88{ 89 local _varname="$1" 90 local _varval="$(_builder_varval $_varname)" 91 shift 92 if [ -z "$_varval" ]; then 93 eval $_varname=\"$@\" 94 else 95 eval $_varname=\$$_varname\" $@\" 96 fi 97} 98 99 100builder_set_prefix () 101{ 102 _BUILD_PREFIX="$@" 103} 104 105builder_begin_module () 106{ 107 _BUILD_CC= 108 _BUILD_CXX= 109 _BUILD_AR= 110 _BUILD_C_INCLUDES= 111 _BUILD_CFLAGS= 112 _BUILD_CXXFLAGS= 113 _BUILD_LDFLAGS_BEGIN_SO= 114 _BUILD_LDFLAGS_END_SO= 115 _BUILD_LDFLAGS_BEGIN_EXE= 116 _BUILD_LDFLAGS_END_EXE= 117 _BUILD_LDFLAGS= 118 _BUILD_BINPREFIX= 119 _BUILD_DSTDIR= 120 _BUILD_SRCDIR=. 121 _BUILD_OBJECTS= 122 _BUILD_STATIC_LIBRARIES= 123 _BUILD_SHARED_LIBRARIES= 124 _BUILD_COMPILER_RUNTIME_LDFLAGS=-lgcc 125} 126 127builder_set_binprefix () 128{ 129 _BUILD_BINPREFIX=$1 130 _BUILD_CC=${1}gcc 131 _BUILD_CXX=${1}g++ 132 _BUILD_AR=${1}ar 133} 134 135builder_set_binprefix_llvm () 136{ 137 _BUILD_BINPREFIX=$1 138 _BUILD_CC=${1}clang 139 _BUILD_CXX=${1}clang++ 140 _BUILD_AR=${2}ar 141} 142 143builder_set_builddir () 144{ 145 _BUILD_DIR=$1 146} 147 148builder_set_srcdir () 149{ 150 _BUILD_SRCDIR=$1 151} 152 153builder_set_dstdir () 154{ 155 _BUILD_DSTDIR=$1 156} 157 158builder_ldflags () 159{ 160 _builder_varadd _BUILD_LDFLAGS "$@" 161} 162 163builder_ldflags_exe () 164{ 165 _builder_varadd _BUILD_LDFLAGS_EXE "$@" 166} 167 168builder_cflags () 169{ 170 _builder_varadd _BUILD_CFLAGS "$@" 171} 172 173builder_cxxflags () 174{ 175 _builder_varadd _BUILD_CXXFLAGS "$@" 176} 177 178builder_c_includes () 179{ 180 _builder_varadd _BUILD_C_INCLUDES "$@" 181} 182 183# $1: optional var to hold the original cflags before reset 184builder_reset_cflags () 185{ 186 local _varname="$1" 187 if [ -n "$_varname" ] ; then 188 eval $_varname=\"$_BUILD_CFLAGS\" 189 fi 190 _BUILD_CFLAGS= 191} 192 193# $1: optional var to hold the original cxxflags before reset 194builder_reset_cxxflags () 195{ 196 local _varname="$1" 197 if [ -n "$_varname" ] ; then 198 eval $_varname=\"$_BUILD_CXXFLAGS\" 199 fi 200 _BUILD_CXXFLAGS= 201} 202 203# $1: optional var to hold the original c_includes before reset 204builder_reset_c_includes () 205{ 206 local _varname="$1" 207 if [ -n "$_varname" ] ; then 208 eval $_varname=\"$_BUILD_C_INCLUDES\" 209 fi 210 _BUILD_C_INCLUDES= 211} 212 213builder_compiler_runtime_ldflags () 214{ 215 _BUILD_COMPILER_RUNTIME_LDFLAGS=$1 216} 217 218builder_link_with () 219{ 220 local LIB 221 for LIB; do 222 case $LIB in 223 *.a) 224 _builder_varadd _BUILD_STATIC_LIBRARIES $LIB 225 ;; 226 *.so) 227 _builder_varadd _BUILD_SHARED_LIBRARIES $LIB 228 ;; 229 *) 230 echo "ERROR: Unknown link library extension: $LIB" 231 exit 1 232 esac 233 done 234} 235 236builder_sources () 237{ 238 local src srcfull obj cc cflags text 239 if [ -z "$_BUILD_DIR" ]; then 240 panic "Build directory not set!" 241 fi 242 if [ -z "$_BUILD_CC" ]; then 243 _BUILD_CC=${CC:-gcc} 244 fi 245 if [ -z "$_BUILD_CXX" ]; then 246 _BUILD_CXX=${CXX:-g++} 247 fi 248 for src in "$@"; do 249 srcfull=$_BUILD_SRCDIR/$src 250 if [ ! -f "$srcfull" ]; then 251 echo "ERROR: Missing source file: $srcfull" 252 exit 1 253 fi 254 obj=$src 255 cflags="" 256 for inc in $_BUILD_C_INCLUDES; do 257 cflags=$cflags" -I$inc" 258 done 259 cflags=$cflags" -I$_BUILD_SRCDIR" 260 case $obj in 261 *.c) 262 obj=${obj%%.c} 263 text="C" 264 cc=$_BUILD_CC 265 cflags="$cflags $_BUILD_CFLAGS" 266 ;; 267 *.cpp) 268 obj=${obj%%.cpp} 269 text="C++" 270 cc=$_BUILD_CXX 271 cflags="$cflags $_BUILD_CXXFLAGS" 272 ;; 273 *.cc) 274 obj=${obj%%.cc} 275 text="C++" 276 cc=$_BUILD_CXX 277 cflags="$cflags $_BUILD_CXXFLAGS" 278 ;; 279 *.S|*.s) 280 obj=${obj%%.$obj} 281 text="ASM" 282 cc=$_BUILD_CC 283 cflags="$cflags $_BUILD_CFLAGS" 284 ;; 285 *) 286 echo "Unknown source file extension: $obj" 287 exit 1 288 ;; 289 esac 290 291 # Source file path can include ../ path items, ensure 292 # that the generated object do not back up the output 293 # directory by translating them to __/ 294 obj=$(echo "$obj" | tr '../' '__/') 295 296 # Ensure we have unwind tables in the generated machine code 297 # This is useful to get good stack traces 298 cflags=$cflags" -funwind-tables" 299 300 obj=$_BUILD_DIR/$obj.o 301 if [ "$_BUILD_MK" ]; then 302 echo "$obj: $srcfull" >> $_BUILD_MK 303 fi 304 builder_log "${_BUILD_PREFIX}$text: $src" 305 builder_command mkdir -p $(dirname "$obj") 306 builder_command $NDK_CCACHE $cc -c -o "$obj" "$srcfull" $cflags 307 fail_panic "Could not compile ${_BUILD_PREFIX}$src" 308 _BUILD_OBJECTS=$_BUILD_OBJECTS" $obj" 309 done 310} 311 312builder_static_library () 313{ 314 local lib libname 315 libname=$1 316 if [ -z "$_BUILD_DSTDIR" ]; then 317 panic "Destination directory not set" 318 fi 319 lib=$_BUILD_DSTDIR/$libname 320 lib=${lib%%.a}.a 321 if [ "$_BUILD_MK" ]; then 322 _BUILD_TARGETS=$_BUILD_TARGETS" $lib" 323 echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK 324 fi 325 if [ -z "${_BUILD_AR}" ]; then 326 _BUILD_AR=${AR:-ar} 327 fi 328 builder_log "${_BUILD_PREFIX}Archive: $libname" 329 rm -f "$lib" 330 builder_command ${_BUILD_AR} crsD "$lib" "$_BUILD_OBJECTS" 331 fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!" 332} 333 334builder_host_static_library () 335{ 336 local lib libname 337 libname=$1 338 if [ -z "$_BUILD_DSTDIR" ]; then 339 panic "Destination directory not set" 340 fi 341 lib=$_BUILD_DSTDIR/$libname 342 lib=${lib%%.a}.a 343 if [ "$_BUILD_MK" ]; then 344 _BUILD_TARGETS=$_BUILD_TARGETS" $lib" 345 echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK 346 fi 347 if [ -z "$BUILD_AR" ]; then 348 _BUILD_AR=${AR:-ar} 349 fi 350 builder_log "${_BUILD_PREFIX}Archive: $libname" 351 rm -f "$lib" 352 builder_command ${_BUILD_AR} crsD "$lib" "$_BUILD_OBJECTS" 353 fail_panic "Could not archive ${_BUILD_PREFIX}$libname objects!" 354} 355 356builder_shared_library () 357{ 358 local lib libname suffix libm 359 libname=$1 360 suffix=$2 361 armeabi_v7a_float_abi=$3 362 363 if [ -z "$suffix" ]; then 364 suffix=".so" 365 fi 366 libm="-lm" 367 if [ "$armeabi_v7a_float_abi" = "hard" ]; then 368 libm="-lm_hard" 369 fi 370 lib=$_BUILD_DSTDIR/$libname 371 lib=${lib%%${suffix}}${suffix} 372 if [ "$_BUILD_MK" ]; then 373 _BUILD_TARGETS=$_BUILD_TARGETS" $lib" 374 echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK 375 fi 376 builder_log "${_BUILD_PREFIX}SharedLibrary: $libname" 377 378 # Important: -lgcc must appear after objects and static libraries, 379 # but before shared libraries for Android. It doesn't hurt 380 # for other platforms. 381 # Also $libm must come before -lc because bionic libc 382 # accidentally exports a soft-float version of ldexp. 383 builder_command ${_BUILD_CXX} \ 384 -Wl,-soname,$(basename $lib) \ 385 -Wl,-shared \ 386 $_BUILD_LDFLAGS_BEGIN_SO \ 387 $_BUILD_OBJECTS \ 388 $_BUILD_STATIC_LIBRARIES \ 389 $_BUILD_COMPILER_RUNTIME_LDFLAGS \ 390 $_BUILD_SHARED_LIBRARIES \ 391 $libm -lc \ 392 $_BUILD_LDFLAGS \ 393 $_BUILD_LDFLAGS_END_SO \ 394 -o $lib 395 fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname" 396} 397 398# Same as builder_shared_library, but do not link the default libs 399builder_nostdlib_shared_library () 400{ 401 local lib libname suffix 402 libname=$1 403 suffix=$2 404 if [ -z "$suffix" ]; then 405 suffix=".so" 406 fi 407 lib=$_BUILD_DSTDIR/$libname 408 lib=${lib%%${suffix}}${suffix} 409 if [ "$_BUILD_MK" ]; then 410 _BUILD_TARGETS=$_BUILD_TARGETS" $lib" 411 echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK 412 fi 413 builder_log "${_BUILD_PREFIX}SharedLibrary: $libname" 414 415 builder_command ${_BUILD_CXX} \ 416 -Wl,-soname,$(basename $lib) \ 417 -Wl,-shared \ 418 $_BUILD_LDFLAGS_BEGIN_SO \ 419 $_BUILD_OBJECTS \ 420 $_BUILD_STATIC_LIBRARIES \ 421 $_BUILD_SHARED_LIBRARIES \ 422 $_BUILD_LDFLAGS \ 423 $_BUILD_LDFLAGS_END_SO \ 424 -o $lib 425 fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname" 426} 427 428builder_host_shared_library () 429{ 430 local lib libname 431 libname=$1 432 lib=$_BUILD_DSTDIR/$libname 433 lib=${lib%%.so}.so 434 if [ "$_BUILD_MK" ]; then 435 _BUILD_TARGETS=$_BUILD_TARGETS" $lib" 436 echo "$lib: $_BUILD_OBJECTS" >> $_BUILD_MK 437 fi 438 builder_log "${_BUILD_PREFIX}SharedLibrary: $libname" 439 440 if [ -z "$_BUILD_CXX" ]; then 441 _BUILD_CXX=${CXX:-g++} 442 fi 443 444 # Important: -lgcc must appear after objects and static libraries, 445 # but before shared libraries for Android. It doesn't hurt 446 # for other platforms. 447 builder_command ${_BUILD_CXX} \ 448 -shared -s \ 449 $_BUILD_OBJECTS \ 450 $_BUILD_STATIC_LIBRARIES \ 451 $_BUILD_SHARED_LIBRARIES \ 452 $_BUILD_LDFLAGS \ 453 -o $lib 454 fail_panic "Could not create ${_BUILD_PREFIX}shared library $libname" 455} 456 457builder_host_executable () 458{ 459 local exe exename 460 exename=$1 461 exe=$_BUILD_DSTDIR/$exename$HOST_EXE 462 if [ "$_BUILD_MK" ]; then 463 _BUILD_TARGETS=$_BUILD_TARGETS" $exe" 464 echo "$exe: $_BUILD_OBJECTS" >> $_BUILD_MK 465 fi 466 builder_log "${_BUILD_PREFIX}Executable: $exename$HOST_EXE" 467 468 if [ -z "$_BUILD_CXX" ]; then 469 _BUILD_CXX=${CXX:-g++} 470 fi 471 472 # Important: -lgcc must appear after objects and static libraries, 473 # but before shared libraries for Android. It doesn't hurt 474 # for other platforms. 475 builder_command ${_BUILD_CXX} \ 476 -s \ 477 $_BUILD_OBJECTS \ 478 $_BUILD_STATIC_LIBRARIES \ 479 $_BUILD_SHARED_LIBRARIES \ 480 $_BUILD_LDFLAGS \ 481 -o $exe 482 fail_panic "Could not create ${_BUILD_PREFIX}executable $libname" 483} 484 485 486builder_end () 487{ 488 if [ "$_BUILD_MK" ]; then 489 echo "all: $_BUILD_TARGETS" >> $_BUILD_MK 490 run make -j$NUM_JOBS -f $_BUILD_MK 491 fail_panic "Could not build project!" 492 fi 493 494 if [ "$_BUILD_DIR_NEW" ]; then 495 log2 "Cleaning up build directory: $_BUILD_DIR" 496 rm -rf "$_BUILD_DIR" 497 _BUILD_DIR_NEW= 498 fi 499} 500 501# Same as builder_begin, but to target Android with a specific ABI 502# $1: ABI name (e.g. armeabi) 503# $2: Build directory 504# $3: Gcc version 505# $4: Optional llvm version 506# $5: Optional Makefile name 507builder_begin_android () 508{ 509 local ABI BUILDDIR LLVM_VERSION MAKEFILE 510 local ARCH SYSROOT LDIR FLAGS 511 local CRTBEGIN_SO_O CRTEND_SO_O CRTBEGIN_EXE_SO CRTEND_SO_O 512 local BINPREFIX GCC_TOOLCHAIN LLVM_TRIPLE GCC_VERSION 513 local SCRATCH_FLAGS 514 if [ -z "$NDK_DIR" ]; then 515 panic "NDK_DIR is not defined!" 516 elif [ ! -d "$NDK_DIR/platforms" ]; then 517 panic "Missing directory: $NDK_DIR/platforms" 518 fi 519 ABI=$1 520 BUILDDIR=$2 521 GCC_VERSION=$3 522 LLVM_VERSION=$4 523 MAKEFILE=$5 524 ARCH=$(convert_abi_to_arch $ABI) 525 526 if [ "$(arch_in_unknown_archs $ARCH)" = "yes" ]; then 527 LLVM_VERSION=$DEFAULT_LLVM_VERSION 528 fi 529 if [ -n "$LLVM_VERSION" ]; then 530 # override GCC_VERSION to pick $DEFAULT_LLVM_GCC??_VERSION instead 531 if [ "$ABI" != "${ABI%%64*}" ]; then 532 GCC_VERSION=$DEFAULT_LLVM_GCC64_VERSION 533 else 534 GCC_VERSION=$DEFAULT_LLVM_GCC32_VERSION 535 fi 536 fi 537 for TAG in $HOST_TAG $HOST_TAG32; do 538 BINPREFIX=$NDK_DIR/$(get_toolchain_binprefix_for_arch $ARCH $GCC_VERSION $TAG) 539 if [ -f ${BINPREFIX}gcc ]; then 540 break; 541 fi 542 done 543 if [ -n "$LLVM_VERSION" ]; then 544 GCC_TOOLCHAIN=`dirname $BINPREFIX` 545 GCC_TOOLCHAIN=`dirname $GCC_TOOLCHAIN` 546 BINPREFIX=$NDK_DIR/$(get_llvm_toolchain_binprefix $LLVM_VERSION $TAG) 547 fi 548 549 SYSROOT=$NDK_DIR/$(get_default_platform_sysroot_for_arch $ARCH) 550 LDIR=$SYSROOT"/usr/"$(get_default_libdir_for_arch $ARCH) 551 552 CRTBEGIN_EXE_O=$LDIR/crtbegin_dynamic.o 553 CRTEND_EXE_O=$LDIR/crtend_android.o 554 555 CRTBEGIN_SO_O=$LDIR/crtbegin_so.o 556 CRTEND_SO_O=$LDIR/crtend_so.o 557 if [ ! -f "$CRTBEGIN_SO_O" ]; then 558 CRTBEGIN_SO_O=$CRTBEGIN_EXE_O 559 fi 560 if [ ! -f "$CRTEND_SO_O" ]; then 561 CRTEND_SO_O=$CRTEND_EXE_O 562 fi 563 564 builder_begin "$BUILDDIR" "$MAKEFILE" 565 builder_set_prefix "$ABI " 566 if [ -z "$LLVM_VERSION" ]; then 567 builder_set_binprefix "$BINPREFIX" 568 else 569 builder_set_binprefix_llvm "$BINPREFIX" 570 case $ABI in 571 armeabi) 572 LLVM_TRIPLE=armv5te-none-linux-androideabi 573 ;; 574 armeabi-v7a|armeabi-v7a-hard) 575 LLVM_TRIPLE=armv7-none-linux-androideabi 576 ;; 577 arm64-v8a) 578 LLVM_TRIPLE=aarch64-none-linux-android 579 ;; 580 x86) 581 LLVM_TRIPLE=i686-none-linux-android 582 ;; 583 x86_64) 584 LLVM_TRIPLE=x86_64-none-linux-android 585 ;; 586 mips) 587 LLVM_TRIPLE=mipsel-none-linux-android 588 ;; 589 mips64) 590 LLVM_TRIPLE=mips64el-none-linux-android 591 ;; 592 *) 593 LLVM_TRIPLE=le32-none-ndk 594 GCC_TOOLCHAIN= 595 CRTBEGIN_SO_O= 596 CRTEND_SO_O= 597 CRTBEGIN_EXE_O= 598 CRTEND_EXE_O= 599 FLAGS=-emit-llvm 600 ;; 601 esac 602 SCRATCH_FLAGS="-target $LLVM_TRIPLE $FLAGS" 603 builder_cflags "$SCRATCH_FLAGS" 604 builder_cxxflags "$SCRATCH_FLAGS" 605 builder_ldflags "$SCRATCH_FLAGS" 606 if [ ! -z $GCC_TOOLCHAIN ]; then 607 SCRATCH_FLAGS="-gcc-toolchain $GCC_TOOLCHAIN" 608 builder_cflags "$SCRATCH_FLAGS" 609 builder_cxxflags "$SCRATCH_FLAGS" 610 builder_ldflags "$SCRATCH_FLAGS" 611 fi 612 fi 613 614 SCRATCH_FLAGS="--sysroot=$SYSROOT" 615 builder_cflags "$SCRATCH_FLAGS" 616 builder_cxxflags "$SCRATCH_FLAGS" 617 618 SCRATCH_FLAGS="--sysroot=$SYSROOT -nostdlib" 619 _BUILD_LDFLAGS_BEGIN_SO="$SCRATCH_FLAGS $CRTBEGIN_SO_O" 620 _BUILD_LDFLAGS_BEGIN_EXE="$SCRATCH_FLAGS $CRTBEGIN_EXE_O" 621 622 _BUILD_LDFLAGS_END_SO="$CRTEND_SO_O" 623 _BUILD_LDFLAGS_END_EXE="$CRTEND_EXE_O" 624 625 case $ABI in 626 armeabi) 627 if [ -z "$LLVM_VERSION" ]; then 628 # add -minline-thumb1-jumptable such that gabi++/stlport/libc++ can be linked 629 # with compiler-rt where helpers __gnu_thumb1_case_* (in libgcc.a) don't exist 630 SCRATCH_FLAGS="-minline-thumb1-jumptable" 631 builder_cflags "$SCRATCH_FLAGS" 632 builder_cxxflags "$SCRATCH_FLAGS" 633 else 634 builder_cflags "" 635 builder_cxxflags "" 636 fi 637 ;; 638 armeabi-v7a|armeabi-v7a-hard) 639 SCRATCH_FLAGS="-march=armv7-a -mfpu=vfpv3-d16" 640 builder_cflags "$SCRATCH_FLAGS" 641 builder_cxxflags "$SCRATCH_FLAGS" 642 builder_ldflags "-march=armv7-a -Wl,--fix-cortex-a8" 643 if [ "$ABI" != "armeabi-v7a-hard" ]; then 644 SCRATCH_FLAGS="-mfloat-abi=softfp" 645 builder_cflags "$SCRATCH_FLAGS" 646 builder_cxxflags "$SCRATCH_FLAGS" 647 else 648 SCRATCH_FLAGS="-mhard-float -D_NDK_MATH_NO_SOFTFP=1" 649 builder_cflags "$SCRATCH_FLAGS" 650 builder_cxxflags "$SCRATCH_FLAGS" 651 builder_ldflags "-Wl,--no-warn-mismatch -lm_hard" 652 fi 653 ;; 654 esac 655} 656 657# $1: Build directory 658# $2: Optional Makefile name 659builder_begin_host () 660{ 661 prepare_host_build 662 builder_begin "$1" "$2" 663 builder_set_prefix "$HOST_TAG " 664} 665