Xcode与终端交互 - ShenYj/ShenYj.github.io GitHub Wiki

Xcode与终端交互

一、Xcode输出内容到终端

  1. 在终端输入tty, 获取终端标识

    ❯ tty
    /dev/ttys002
  2. xcode-TARGETS-Build Phases-Run Script下新增脚本

    echo "Xcode" > /dev/ttys002

    定位到名称为/dev/ttys002的终端之上


二、Xcode输出环境变量到终端

  1. 借助xcconfig文件, 在xcconfig中定义环境变量

    HOST_URL = 192.168.0.1

  2. xcode-TARGETS-Build Phases-Run Script下, 将之前输出的内容更换为xcconfig下的变量

    echo "${HOST_URL}" > /dev/ttys002

    这样就将环境变量的值输出到终端


三、xcode和终端实操演练

  • 利用xcode传参并执行.sh脚本文件, 完成nm指令的调用
  1. xcode-TARGETS-Build Phases-Run Script下, 修改脚本, 执行根目录下的xcode_run_cmd.sh脚本文件

    /bin/sh "$SRCROOT/xcode_run_cmd.sh"
    • 脚本内容:

      #!/bin/sh
      
      
      RunCommand() {
      #判断全局字符串VERBOSE_SCRIPT_LOGGING是否为空。-n string判断字符串是否非空
      #[[是 bash 程序语言的关键字。用于判断
      if [[ -n "$VERBOSE_SCRIPT_LOGGING" ]]; then
          #作为一个字符串输出所有参数。使用时加引号"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数
          if [[ -n "$TTY" ]]; then
              echo "$@" 1>$TTY
          else
              echo "$*"
          fi
          echo "------------------------------------------------------------------------------" 1>$TTY
      fi
      #与$*相同。但是使用时加引号,并在引号中返回每个参数。"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数
      if [[ -n "$TTY" ]]; then
          echo `$@ &>$TTY`
      else
          "$@"
      fi
      #显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
      return $?
      }
      
      EchoError() {
          #在shell脚本中,默认情况下,总是有三个文件处于打开状态,标准输入(键盘输入)、标准输出(输出到屏幕)、标准错误(也是输出到屏幕),它们分别对应的文件描述符是0,1,2
          # >  默认为标准输出重定向,与 1> 相同
          # 2>&1  意思是把 标准错误输出 重定向到 标准输出.
          # &>file  意思是把标准输出 和 标准错误输出 都重定向到文件file中
          # 1>&2 将标准输出重定向到标准错误输出。实际上就是打印所有参数已标准错误格式
          if [[ -n "$TTY" ]]; then
              echo "$@" 1>&2>$TTY
          else
              echo "$@" 1>&2
          fi
          
      }
      
      RunCMDToTTY() {
          if [[ ! -e "$TTY" ]]; then
              EchoError "=========================================="
              EchoError "ERROR: Not Config tty to output."
              exit -1
          fi
          
          if [[ -n "$CMD" ]]; then
              RunCommand "$CMD" ${CMD_FLAG}
          else
              EchoError "=========================================="
              EchoError "ERROR:Failed to run CMD. THE CMD must not null"
          fi
      }
      
      
      RunCMDToTTY
      
    • 脚本中定义了三个参数:

      CMD: 运行的命令
      CMD_FLAG: 运行的命令参数
      TTY: 终端

  2. 将这三个参数配置到xcconfig中, 确保Configurations下选中自定义的xcconfig配置文件

    CMD = nm
    CMD_FLAG = -pa /Users/shenyj/Desktop/macho/MultiEnvByXCConfigWOConflict.app/MultiEnvByXCConfigWOConflict
    TTY = /dev/ttys002
    • 参数注解:
      -p: 不排序
      -a: 显示所有符号, 包含调试符号
  3. 回到xcode项目编译指定了xcconfigscheme, 可以看到终端输入了内容

    iterm2

    • 结果等同于在终端中手动执行

      nm -pa /Users/shenyj/Desktop/macho/MultiEnvByXCConfigWOConflict.app/MultiEnvByXCConfigWOConflict

      操作的意义在于实现了自动化

    通过xcconfig来调整参数, 执行编译可以完成每一次的调试

  4. 刚刚在xcconfig中写死了一个路径下的macho文件来进行调试, xcode为我们提供的环境变量, 利用环境变量稍加优化, 实现为当前项目生成的macho文件进行调试

    MACHO_PATH = ${BUILD_DIR}/${CONFIGURATION}/${EFFECTIVE_PLATFORM_NAME}/*
    CMD = nm
    CMD_FLAG = -pa ${MACHO_PATH}
    TTY = /dev/ttys002
    • 环境变量说明

      ${BUILD_DIR} 当前编译的路径 .../Build
      ${CONFIGURATION} Build/Products
      ${EFFECTIVE_PLATFORM_NAME} 可执行文件的路径 (Build/Products/Debug)

    • 脚本的执行顺序, 在签名以前

    build

⚠️ **GitHub.com Fallback** ⚠️