1#!/bin/bash 2 3make_boolean() { 4 OPTION="${1}" 5 6 case "${OPTION}" in 7 ("0"|"no"|""|"No"|"nO"|"NO"|"false"|"FALSE") OPTION="0";; 8 (*) OPTION="1";; 9 esac 10 11 printf "${OPTION}" 12} 13 14phase() { 15 echo 16 echo "***" 17 echo "*** ${1}..." 18 echo "***" 19 echo 20} 21 22usage() { 23 exec >&2 24 25 NO_VAL="0, no, NO, No, nO, false or FALSE" 26 printf "$(basename ${0}): usage\n\n" 27 printf "Accepted environment variables:\n" 28 printf "\tSDK:\t\t\t\tsets the target SDK [string]\n\t\t\t\t\tdefault: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk\n" 29 printf "\tMACOSX_DEPLOYMENT_TARGET:\tsets the deployment target (specific OS X version to optimize/build for) [string]\n\t\t\t\t\tdefault: 10.7\n" 30 printf "\tSTDLIB:\t\t\t\tsets a specific stdlib variant. Must be used with FORCE_STDLIB to have any effect. [string]\n\t\t\t\t\tdefault: autodetect\n" 31 printf "\tFORCE_STDLIB:\t\t\tforces a specific C++ stdlib version. If you use this, also specify STDLIB. YOU SHOULD NEVER USE THIS, UNLESS YOU KNOW WHAT YOU ARE DOING! [boolean]\n\t\t\t\t\tdefault: disabled\n" 32 printf "\tDEBUG\t\t\t\tenables or disables debug builds [boolean]\n\t\t\t\t\tdefault: disabled\n" 33 printf "\tBUNDLE\t\t\t\tenables or disables library bundling and the creation of a .dmg installer [boolean]\n\t\t\t\t\tdefault: enabled\n" 34 printf "\tUNIVERSAL\t\t\tenables or disables x86 support. x86_64 support is always enabled [boolean]\n\t\t\t\t\tdefault: enabled\n" 35 printf "\tMACPORTS_PREFIX\t\t\tsets the (MacPorts) prefix used to detect PulseAudio, nxproxy and xauth binaries [string]\n\t\t\t\t\tdefault: /opt/local/\n" 36 printf "\n" 37 printf "Boolean values help:\n" 38 printf "\ta value of ${NO_VAL} will be treated as false\n" 39 printf "\tany other value will be treated as true\n" 40 41 exit 2 42} 43 44dependency_error() { 45 exec >&2 46 47 typeset element="${1}"; shift 48 typeset component="${1}"; shift 49 typeset type="${1}"; shift 50 51 echo "${element} ${type} not found." 52 echo "Install ${component} -- e.g., via "port -vt install ${component}" if using MacPorts." 53 echo "If ${component} is already installed, try passing MACPORTS_PREFIX if the autodetected or default value (${MACPORTS_PREFIX}) does not match your setup." 54 55 exit 3 56} 57 58lazy_canonical_path() { 59 typeset path="${1}" 60 61 typeset old_path="" 62 while [ "${old_path}" != "${path}" ]; do 63 old_path="${path}" 64 path="${path//\/\///}" 65 done 66 67 printf "${old_path}" 68} 69 70get_nesting_level() { 71set -x 72 typeset -i level=0 73 typeset path="${1}" 74 75 while [ -n "${path}" ] && [ "${path}" != "." ] && [ "${path}" != "/" ]; do 76 i="$((${i} + 1))" 77 path="$(dirname "${path}")" 78 done 79 80 printf "${level}" 81set +x 82} 83 84repeat_str() { # INPUT COUNT 85 typeset INPUT="${1:?"Error: no input string passed to ${FUNCNAME}()."}" 86 typeset COUNT="${2:?"Error: no count passed to ${FUNCNAME}()."}" 87 88 typeset ret="" 89 typeset -i i=0 90 while [ "${i}" -lt "${COUNT}" ]; do 91 ret="${ret}$(printf "${INPUT}")" 92 i=$((${i} + 1)) 93 done 94 95 printf "${ret}" 96 97 return 0 98} 99 100typeset -a otool_fail_str 101otool_fail_str=( "is not an object file" 102 "can't open file" 103 "Archive : " ) 104 105parse_otool_output() { 106#set -x 107 typeset raw_output="${@}" 108 109 typeset fail_str="" 110 for fail_str in "${otool_fail_str[@]}"; do 111 if echo "${raw_output}" | grep -q "${fail_str}"; then 112 return 1 113 fi 114 done 115 116 typeset tmp_regex='^[[:space:]]+(.*)[[:space:]]\(compatibility version .*, current version .*\)' 117 118 # In this special case, we do not want read to perform any word splitting. 119 typeset oldifs="${IFS}" 120 IFS='' 121 122 # Used for skipping the ID entry. 123 # Initialized to the empty string, but the first matching line will set it once. 124 # The ID filename is required for subsequent dependency discovery. 125 typeset id="" 126 127 typeset line="" 128 while read -r line; do 129 if [[ "${line}" =~ ${tmp_regex} ]]; then 130 typeset file="${BASH_REMATCH[1]}" 131 132 if [ -z "${id}" ]; then 133 echo "ID unset, something is wrong" >&2 134 return 1 135 elif [ "$(basename "${file}")" != "${id}" ]; then 136 echo "${BASH_REMATCH[1]}" 137 else 138 first="0" 139 fi 140 elif [ -z "${id}" ]; then 141 id="$(basename "${line%":"}")" 142 fi 143 done <<< "${raw_output}" 144 145 IFS="${oldifs}" 146#set +x 147 return 0 148} 149 150MATCH_HELP='(^((-h)|(--help))([ ]|$))|([ ]+((-h)|(--help))([ ]|$))' 151[ -n "${*}" ] && [[ "${*}" =~ ${MATCH_HELP} ]] && usage 152 153NAME="x2goclient" 154 155TOP_DIR="$(dirname "$0")" 156[[ "${TOP_DIR}" == /* ]] || TOP_DIR="${PWD}/${TOP_DIR#./}" 157BUILD_DIR="${TOP_DIR}/client_build" 158APPBUNDLE="${BUILD_DIR}/${NAME}.app" 159EXE_DIR="${APPBUNDLE}/Contents/exe/" 160FRAMEWORKS_DIR="${APPBUNDLE}/Contents/Frameworks/" 161RESOURCES_DIR="${APPBUNDLE}/Contents/Resources/" 162DMGFILE="${BUILD_DIR}/${NAME}.dmg" 163PROJECT="${TOP_DIR}/${NAME}.pro" 164PKG_DMG="${TOP_DIR}/pkg-dmg" 165 166# Try to find the MacPorts prefix. 167typeset MACPORTS_PREFIX_SEARCH="" 168if type -P port >/dev/null 2>&1; then 169 MACPORTS_PREFIX_SEARCH="$(type -P port)" 170 MACPORTS_PREFIX_SEARCH="${MACPORTS_PREFIX_SEARCH%%bin/port}" 171else 172 # Port not being found in ${PATH} doesn't necessarily mean it isn't available. 173 # Try to guess. 174 MACPORTS_PREFIX_SEARCH="/opt/local/" 175fi 176 177NXPROXY="nxproxy" 178NXAUTH="xauth" 179PULSEAUDIO_BINARIES=( "pulseaudio" "esdcompat" "pacat" "pacmd" "pactl" 180 "pamon" "paplay" "parec" "parecord" "pasuspender" ) 181PULSEAUDIO_LIBRARIES=( "libpulse-simple.0.dylib" 182 "pulse-13.0" 183 "pulseaudio" ) 184RESOURCE_FILES=( "audio/startup.wav" ) 185 186typeset -a special_files_regex 187special_files_regex+=( "pulseaudio/libpulsecommon-[0-9]+\.[0-9]+\.dylib" 188 "pulseaudio/libpulsecore-[0-9]+\.[0-9]+\.dylib" ) 189 190typeset -r dependency_base_format='@executable_path/../Frameworks/' 191 192: ${SDK:="/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.7.sdk"} 193: ${MACOSX_DEPLOYMENT_TARGET:="10.7"} 194: ${FORCE_STDLIB:="0"} 195: ${DEBUG:="0"} 196: ${BUNDLE:="1"} 197: ${UNIVERSAL:="1"} 198: ${MACPORTS_PREFIX:="${MACPORTS_PREFIX_SEARCH}"} 199 200unset MACPORTS_PREFIX_SEARCH 201 202FORCE_STDLIB="$(make_boolean "${FORCE_STDLIB}")" 203DEBUG="$(make_boolean "${DEBUG}")" 204BUNDLE="$(make_boolean "${BUNDLE}")" 205UNIVERSAL="$(make_boolean "${UNIVERSAL}")" 206 207[ "${DEBUG}" -eq "0" ] && BUILD_MODE="release" || BUILD_MODE="debug" 208 209BUILD_ARCH="x86_64" 210[ "${UNIVERSAL}" -eq "1" ] && BUILD_ARCH="${BUILD_ARCH} x86" 211 212if [ "${FORCE_STDLIB}" -eq "1" ]; then 213 if [[ -z "${STDLIB}" ]]; then 214 echo "stdlib forcing enabled, but STDLIB not passed." >&2 215 exit 1 216 fi 217 218 if [[ "${STDLIB}" != "libc++" && "${STDLIB}" != "libstdc++" ]]; then 219 echo "stdlib forcing enabled, but STDLIB contains illegal value. Legal values: libc++, libstdc++" >&2 220 exit 1 221 fi 222else 223 SDK_MINOR_VERSION="$(/usr/bin/perl -pe 's#.*?10\.(\d+).*?\.sdk$#\1#' <<< "${SDK}")" 224 MATCH_NUMBERS='^[0-9]+$' 225 if [[ "${SDK_MINOR_VERSION}" =~ ${MATCH_NUMBERS} ]]; then 226 [ "${SDK_MINOR_VERSION}" -gt "6" ] && STDLIB="libstdc++" 227 [ "${SDK_MINOR_VERSION}" -gt "8" ] && STDLIB="libc++" 228 else 229 echo "Unable to determine OS X version. Unknown value '${SDK_MINOR_VERSION}'." >&2 230 exit 1 231 fi 232fi 233 234# Gather files. 235NXPROXY="$(lazy_canonical_path "${MACPORTS_PREFIX}/bin/${NXPROXY}")" 236NXAUTH="$(lazy_canonical_path "${MACPORTS_PREFIX}/bin/${NXAUTH}")" 237 238[ -x "${NXPROXY}" ] || dependency_error "nxproxy" "nxproxy" "binary" 239[ -x "${NXAUTH}" ] || dependency_error "xauth" "xauth" "binary" 240 241typeset -i i 242typeset -i fail 243typeset -a PULSEAUDIO_BINARIES_FULL 244typeset cur_binary 245fail="0" 246for cur_binary in ${PULSEAUDIO_BINARIES[@]}; do 247 cur_binary="$(lazy_canonical_path "${MACPORTS_PREFIX}/bin/${cur_binary}")" 248 249 if [ -x "${cur_binary}" ]; then 250 PULSEAUDIO_BINARIES_FULL+=( "${cur_binary}" ) 251 else 252 fail="1" 253 break 254 fi 255done 256 257[ "${fail}" -eq "1" ] && dependency_error "${cur_binary##"$(lazy_canonical_path "${MACPORTS_PREFIX}/bin/")"}" "pulseaudio" "binary" 258 259typeset cur_lib_or_libdir 260typeset -a PULSEAUDIO_LIBRARIES_FULL 261fail="0" 262for cur_lib_or_libdir in ${PULSEAUDIO_LIBRARIES[@]}; do 263 cur_lib_or_libdir="$(lazy_canonical_path "${MACPORTS_PREFIX}/lib/${cur_lib_or_libdir}")" 264 265 if [ ! -d "${cur_lib_or_libdir}" ] && [ -x "${cur_lib_or_libdir}" ]; then 266 echo "Adding ${cur_lib_or_libdir} to \${PULSEAUDIO_LIBRARIES_FULL}" 267 PULSEAUDIO_LIBRARIES_FULL+=( "${cur_lib_or_libdir}" ) 268 elif [ -d "${cur_lib_or_libdir}" ]; then 269 # That's a directory... more work needed here. 270 echo "Scrubbing directory ${cur_lib_or_libdir}" 271 typeset entry="" 272 273 # -r parameter to read: Backslashes may NOT escape any characters! 274 # -d '': specifies the delimiter to be used - as '' resolves to an empty string followed 275 # by a NUL character, the delimiter is set to this very NUL (\000) character. 276 while read -r -d '' entry; do 277 typeset cur_file="$(basename "${entry}")" 278 typeset TMP_REGEX='^.*\.(\.[0-9]+){0,2}(so|dylib|bundle)$' 279 280 # This is only here should the PA build system ever break and create 281 # "linux-style" library file names. Let's hope it never actually comes to that. 282 typeset TMP_REGEX_LINUX_COMPAT='^.*\.(so|dylib|bundle)(\.[0-9]+){0,2}$' 283 284 if [[ "${cur_file}" =~ ${TMP_REGEX} ]] || [[ "${cur_file}" =~ ${TMP_REGEX_LINUX_COMPAT} ]]; then 285 # Filename matched the expected template. 286 echo "Adding $(lazy_canonical_path "${entry}") to \${PULSEAUDIO_LIBRARIES_FULL}" 287 PULSEAUDIO_LIBRARIES_FULL+=( "$(lazy_canonical_path "${entry}")" ) 288 fi 289 done < <(gfind "${cur_lib_or_libdir}" -type 'f' -print0) 290 else 291 fail="1" 292 break 293 fi 294done 295 296[ "${fail}" -eq "1" ] && dependency_error "${cur_lib_or_libdir}" "pulseaudio" "library or library directory" 297 298set -e 299 300phase "Cleaning" 301make clean 302 303# Create gitlog. 304git --no-pager log --since "2 years ago" --format="%ai %aN (%h) %n%n%x09*%w(68,0,10) %s%d%n" > "ChangeLog.gitlog" 305mv "ChangeLog.gitlog" "res/txt/git-info" 306 307# Copy debian changelog as the general changelog. 308cp -a "debian/changelog" "res/txt/" 309 310[ -e "${BUILD_DIR}" ] && rm -rf "${BUILD_DIR}" 311 312mkdir "${BUILD_DIR}" 313pushd "${BUILD_DIR}" 314 315phase "Running lrelease" 316lrelease "${PROJECT}" 317 318phase "Running qmake" 319qmake -config "${BUILD_MODE}" -spec macx-g++ "${PROJECT}" \ 320 CONFIG+="${BUILD_ARCH}" \ 321 QMAKE_MAC_SDK="${SDK}" \ 322 QMAKE_MACOSX_DEPLOYMENT_TARGET="${MACOSX_DEPLOYMENT_TARGET}" \ 323 OSX_STDLIB="${STDLIB}" \ 324 MACPORTS_INCLUDE_PATH="${MACPORTS_PREFIX}/include" \ 325 MACPORTS_LIBRARY_PATH="${MACPORTS_PREFIX}/lib" \ 326 MACPORTS_PREFIX="${MACPORTS_PREFIX}" 327 328phase "Running make" 329make -j2 330 331mkdir -p "${EXE_DIR}/" 332mkdir -p "${FRAMEWORKS_DIR}/" 333 334phase "Copying nxproxy" 335cp -av "${NXPROXY}" "${EXE_DIR}/" 336 337phase "Copying (n)xauth" 338cp -av "${NXAUTH}" "${EXE_DIR}/nxauth" 339 340phase "Copying misc resources" 341typeset cur_res_file 342for cur_res_file in ${RESOURCE_FILES[@]}; do 343 cp -av "${TOP_DIR}/res/${cur_res_file}" "${RESOURCES_DIR}/" 344done 345 346phase "Copying PulseAudio" 347for cur_binary in ${PULSEAUDIO_BINARIES_FULL[@]}; do 348 cp -av "${cur_binary}" "${EXE_DIR}/" 349done 350 351typeset intermediate_lib_dir="" 352for cur_binary in ${PULSEAUDIO_LIBRARIES_FULL[@]}; do 353set -x 354 intermediate_lib_dir="$(lazy_canonical_path "$(dirname "${cur_binary}")/")" 355 intermediate_lib_dir="${intermediate_lib_dir##"$(lazy_canonical_path "${MACPORTS_PREFIX}/lib/")"}" 356 357 mkdir -p "${FRAMEWORKS_DIR}/${intermediate_lib_dir}/" 358 359 cp -av "${cur_binary}" "${FRAMEWORKS_DIR}/${intermediate_lib_dir}/" 360set +x 361done 362 363if [ "${BUNDLE}" = "1" ]; then 364 phase "Bundling nxproxy" 365 dylibbundler \ 366 --fix-file "${EXE_DIR}/nxproxy" \ 367 --bundle-deps \ 368 --dest-dir "${FRAMEWORKS_DIR}/" \ 369 --install-path "@executable_path/../Frameworks/" \ 370 --create-dir 371 372 phase "Bundling (n)xauth" 373 dylibbundler \ 374 --fix-file "${EXE_DIR}/nxauth" \ 375 --bundle-deps \ 376 --dest-dir "${FRAMEWORKS_DIR}/" \ 377 --install-path "@executable_path/../Frameworks/" \ 378 --create-dir 379 380 phase "Bundling PulseAudio" 381 typeset cur_binary_name="" 382 for cur_binary in ${PULSEAUDIO_BINARIES_FULL[@]}; do 383 if [ ! -L "${cur_binary}" ]; then 384 cur_binary_name="$(basename "${cur_binary}")" 385 dylibbundler \ 386 --fix-file "${EXE_DIR}/${cur_binary_name}" \ 387 --bundle-deps \ 388 --dest-dir "${FRAMEWORKS_DIR}/" \ 389 --install-path "@executable_path/../Frameworks/" \ 390 --create-dir \ 391 --overwrite-files 392 fi 393 done 394 395 typeset intermediate_lib_dir="" 396 for cur_binary in ${PULSEAUDIO_LIBRARIES_FULL[@]}; do 397 intermediate_lib_dir="$(lazy_canonical_path "$(dirname "${cur_binary}")/")" 398 intermediate_lib_dir="${intermediate_lib_dir##"$(lazy_canonical_path "${MACPORTS_PREFIX}/lib/")"}" 399 400 if [ ! -L "${cur_binary}" ]; then 401 cur_binary_name="$(basename "${cur_binary}")" 402 echo "Handling ${cur_binary} => ${intermediate_lib_dir}/${cur_binary_name}." 403 404 typeset nesting_level="$(get_nesting_level "${intermediate_lib_dir}")" 405 406 dylibbundler \ 407 --fix-file "${FRAMEWORKS_DIR}/${intermediate_lib_dir}/${cur_binary_name}" \ 408 --bundle-deps \ 409 --dest-dir "${FRAMEWORKS_DIR}/${intermediate_lib_dir}" \ 410 --install-path "@executable_path/$(repeat_str "../" "${nesting_level}")../Frameworks/${intermediate_lib_dir}" \ 411 --create-dir \ 412 --overwrite-files 413 fi 414 done 415 416 phase "Deduplicating PulseAudio libraries and dependencies" 417 typeset -r base_dir="$(lazy_canonical_path "${FRAMEWORKS_DIR}")" 418 419 typeset -a all_files 420 typeset entry="" 421 while read -r -d '' entry; do 422 typeset sanitized_entry="$(lazy_canonical_path "${entry}")" 423 echo "Adding ${sanitized_entry} to all files" 424 all_files+=( "${sanitized_entry}" ) 425 done < <(gfind "${base_dir}" -type 'f' -print0) 426 427 typeset -a top_files 428 for entry in "${all_files[@]}"; do 429 typeset relative_path="${entry##"$(lazy_canonical_path "${base_dir}/")"}" 430 typeset tmp_regex='^[^/]+$' 431 echo "Checking ${relative_path} against regex '${tmp_regex}'" 432 if [[ "${relative_path}" =~ ${tmp_regex} ]]; then 433 echo "${relative_path} is top file, adding to array." 434 top_files+=( "${relative_path}" ) 435 fi 436 done 437 438 typeset -a duplicates 439 for entry in "${all_files[@]}"; do 440 typeset relative_path="${entry##"$(lazy_canonical_path "${base_dir}/")"}" 441 typeset file_name="$(basename "${entry}")" 442 typeset top_entry="" 443 for top_entry in "${top_files[@]}"; do 444 if [ "${top_entry}" != "${relative_path}" ]; then 445 if [ "${file_name}" = "${top_entry}" ]; then 446 echo "Adding duplicate: ${relative_path}" 447 duplicates+=( "${relative_path}" ) 448 fi 449 fi 450 done 451 done 452 453 echo "duplicates array before:" 454 for entry in "${duplicates[@]}"; do 455 echo "${entry}" 456 done 457 458 typeset -i i="0" 459 for i in "${!duplicates[@]}"; do 460 entry="${duplicates[${i}]}" 461 typeset special_file_regex="" 462 for special_file_regex in "${special_files_regex[@]}"; do 463 typeset tmp_regex='^'"${special_file_regex}"'$' 464 if [[ "${entry}" =~ ${tmp_regex} ]]; then 465 cp -v "${base_dir}/$(basename "${entry}")" "${base_dir}/$(dirname "${special_file_regex}")/" 466 duplicates[${i}]="$(basename "${entry}")" 467 echo "Renamed ${entry} in duplicates array to ${duplicates[${i}]}" 468 fi 469 done 470 done 471 472 echo "duplicates array after:" 473 for entry in "${duplicates[@]}"; do 474 echo "${entry}" 475 done 476 477 for entry in "${duplicates[@]}"; do 478 rm -v "${base_dir}/${entry}" 479 typeset -i i="0" 480 for i in "${!all_files[@]}"; do 481 typeset all_entry="${all_files[${i}]}" 482 typeset relative_path="${all_entry##"$(lazy_canonical_path "${base_dir}/")"}" 483 if [ "${relative_path}" = "${entry}" ]; then 484 unset all_files[${i}] 485 fi 486 done 487 done 488 489 echo "New value for all_files:" 490 for entry in "${all_files[@]}"; do 491 echo "${entry}" 492 done 493 494 echo "Duplicates-to-real map:" 495 # Build complementary array to duplicates. 496 typeset -a to_files 497 for entry in "${duplicates[@]}"; do 498 typeset filename="$(basename "${entry}")" 499 500 typeset all_entry="" 501 for all_entry in "${all_files[@]}"; do 502 typeset all_entry_filename="$(basename "${all_entry}")" 503 504 if [ -n "${filename}" ] && [ -n "${all_entry_filename}" ]; then 505 if [ "${filename}" = "${all_entry_filename}" ]; then 506 typeset dependency_format="$(lazy_canonical_path "${dependency_base_format}/${all_entry##${base_dir}}")" 507 to_files+=( "${dependency_format}" ) 508 509 echo "${entry} => ${dependency_format}" 510 511 # There should be only one entry matching, so we can save a bit of time and break out of the loop. 512 # Even more importantly, we only want one entry for each duplicates entry anyway... 513 break 514 fi 515 else 516 echo "ERROR: empty file name while matching duplicates with non-duplicates." >&2 517 echo "ERROR: duplicate entry: \"${entry}\"" >&2 518 echo "ERROR: real entry: \"${all_entry}\"" >&2 519 exit 1 520 fi 521 done 522 done 523 524 # Add binaries to all_files as well. 525 typeset entry="" 526 while read -r -d '' entry; do 527 echo "Adding ${entry} to all files" 528 all_files+=( "${entry}" ) 529 done < <(gfind "${EXE_DIR}" -type 'f' -executable -print0) 530 531 # Try to fixup files broken by duplicates removal. 532 for all_entry in "${all_files[@]}"; do 533 typeset otool_out="" 534 typeset -i tmp_ret="0" 535 536 # Newer otool versions terminate with a non-zero return code on errors, 537 # while the classic/legacy versions do not. We need to make sure our 538 # script doesn't terminate just because otool returns a non-zero exit 539 # status. 540 set +e 541 otool_out="$(otool -L "${all_entry}")" 542 tmp_ret="${?}" 543 set -e 544 545 # If the return code was non-zero, skip this file. 546 # A return code of zero does not automatically mean that otool finished 547 # successfully, so in that case throw otool's stdout into parse_otool_output(). 548 if [ "${tmp_ret}" -eq "0" ]; then 549 # Don't merge the declaration and initialization with the real value assignment. 550 # We need the return value of parse_otool_output(), but running 551 # typeset foo="$(bar)" will give us the return value of typeset, not bar(). 552 typeset dependencies="" 553 set +e 554 dependencies="$(parse_otool_output "${otool_out}")" 555 tmp_ret="${?}" 556 set -e 557 fi 558 559 if [ "${tmp_ret}" -ne "0" ]; then 560 echo "WARNING: otool returned error for file: ${all_entry}" >&2 561 echo "WARNING: skipping." >&2 562 continue 563 fi 564 565 typeset line="" 566 while read -r line; do 567 #echo "dependency of ${all_entry}: ${line}" 568 569 typeset duplicate_entry="" 570 typeset -i i="0" 571 for i in "${!duplicates[@]}"; do 572 typeset duplicate_entry="${duplicates[${i}]}" 573 #echo "checking for duplicate ${duplicate_entry}" 574 typeset duplicate_format="$(lazy_canonical_path "${dependency_base_format}/${duplicate_entry}")" 575 576 if [ -n "${line}" ] && [ -n "${duplicate_format}" ]; then 577 if [ "${line}" = "${duplicate_format}" ]; then 578 install_name_tool -change "${line}" "${to_files[${i}]}" "${all_entry}" 579 fi 580 else 581 echo "ERROR: empty file name while replacing duplicate dependencies." >&2 582 echo "ERROR: for file ${all_entry}" >&2 583 echo "ERROR: at dependency ${line}" >&2 584 echo "ERROR: duplicate entry: \"${duplicate_entry}\"" >&2 585 echo "ERROR: dependency: \"${line}\"" >&2 586 exit 1 587 fi 588 done 589 done <<< "${dependencies}" 590 done 591 592 phase "Bundling up using macdeployqt" 593 macdeployqt "${APPBUNDLE}" -verbose=2 594 595 phase "Creating DMG" 596 ${PKG_DMG} \ 597 --source "${APPBUNDLE}" \ 598 --sourcefile \ 599 --target "${DMGFILE}" \ 600 --volname "x2goclient" \ 601 --verbosity 2 \ 602 --mkdir "/.background" \ 603 --copy "${TOP_DIR}/res/img/png/macinstaller_background.png:/.background" \ 604 --copy "${TOP_DIR}/res/osxbundle/macdmg.DS_Store:/.DS_Store" \ 605 --copy "${TOP_DIR}/LICENSE" \ 606 --copy "${TOP_DIR}/COPYING" \ 607 --symlink "/Applications" \ 608 --icon "${TOP_DIR}/res/img/icons/dmg/x2go-mac-dmg.icns" \ 609 --format "UDBZ" 610fi 611 612popd 613