目录
快速开始
一、工程文件的介绍
workspace:工作空间,包含了多个project
project:项目包含了所有的资源文件和代码文件和配置项
target:具体的构建产物,从project中选择资源文件和代码文件构建出具体的产物,配置默认项继承自project
scheme:一套规则,指定如何来操作target,比如build、run、archive。又比如是debug环境还是release环境
二、xcode是一个终端
xcode提供了运行脚本的环境变量
# 项目的根目录
SRCROOT
# 工程名称
PROJECT_NAME=XYApp
# BUILD_DIR:指定 Xcode 构建输出的目录
BUILD_DIR=/Users/lixiaoyi/Library/Developer/Xcode/DerivedData/XYApp-eitzecwceuevhddbkszxvqncrznc/Build/Products
三、cocoapods工程的结构
XYApp 这个target 隐式依赖 Pods_XYApp.framework (Frameworks,Libraries,and Embedded Content)
Pods_XYApp.framework 显式依赖 AFN、SDWebimage、FMDB…等 (Target Dependencies)
四、编译一个target需要哪些物料
target + target的编译配置
所以指定workspacetarget 和 target 是没办法编译的
指定project 和 target 可以编译
指定project 和 scheme 可以编译
工程介绍
一、Workspace
工作空间,用于管理project
二、Project
包含了你的应用程序的源代码、资源文件、配置文件等所有信息。
Project中的配置信息 Build Settings 是全局配置,所有的targe都可以继承
三、Target
1、目标是指项目中的一个构建目标,可以是一个应用程序、一个框架、一个库等。
比如:XYApp.xcodeproj下的target XYApp是一个应用程序
2、一个项目可以有多个目标
比如:Pods.xcodeproj下的target AFN和FMDB是一个库
3、不同的目标可以共享相同的源代码也可以有自己的源代码
不同的target使用不同的代码有两种方式:
一种是在代码中添加编译宏来决定是否执行某段代码<br>
#if FREE_VERSION
// FreeVersion 免费版特有的代码
#else
// PaidVersion 付费版特有的代码
#endif
还有一种是选中xx.m文件,在xcode的右侧的Target Membership 来决定这个文件被哪个target使用
这两种方式可以组合使用
4、每个目标都有自己的设置,包括编译选项、链接库、预处理器宏等。使得你可以为同一份代码构建不同的产品或版本
target自己的Build Settings默认继承Project,也可以自己独立设置
四、Scheme
1、介绍
对指定Target的环境配置。
Scheme是一套规则,指定如何运行,构建target。比如我们经常用的切换环境:Debug 和 Release。
2、Scheme文件在什么位置
xx.xcsheme文件位于xx.xcodeproj目录下
scheme文件分为共享和私有,私有的可以不提交到git,只供自己使用
-
比如 XYApp.xcodeproj目录下的scheme文件的位置:
共享scheme的位置
/XYApp/XYApp.xcodeproj/xcshareddata/xcschemes
私有scheme的位置
XYApp/XYApp.xcodeproj/xcuserdata/lxy.xcuserdatad/xcschemes -
比如 Pods.xcodeproj目录下的scheme文件的位置:
私有scheme的位置
Pods/Pods.xcodeproj/xcuserdata/lxy.xcuserdatad/xcschemes
Workspace


一、contents.xcworkspacedata文件
XYApp.xcwrokspace 和 project.xcworkspace 是文件夹,代表一个工作空间
文件夹内部有一个contents.xcworkspacedata文件是xml格式,用于描述这个工作空间
cocoapods就是通过操作这个文件来管理各个project的
project.xcworkspace/contents.xcworkspacedata
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
XYApp.xcwrokspace/contents.xcworkspacedata
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:XYApp.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
1、self:
表示引用xx.xcworkspace同目录下有相同文件名的pbxproj结尾的文件
比如:project.xcworkspace 和 project.pbxproj 文件
2、group:
表示引用指定目录下的xcodeproj结尾的文件,group代表XYApp.xcwrokspace所在目录
比如:XYApp.xcwrokspace 和 XYApp.xcodeproj
3、container: 在.xcworkspace当前目录下有不同名,但以.xcodeproj结尾文件
4、absolute:绝对路径
workspace中的所有project都构建在同一个目录中
xcodebuild
在 Linux 和 macOS 终端中: command [options] [arguments]
command: 要执行的命令或程序的名称。
options: 命令的选项,通常以单个短划线(-)或双短划线(–)开头,可以有多个选项。
arguments: 命令的参数,是命令操作的对象或要处理的数据。
一、指令演示
# 只指定xx.xcworkspace 和 target 是没法发编译的
# lxy:因为只有xcworkspace没办法指定源文件,也没有办法指定编译配置
# 想要编译需要指定一个xx.scheme文件
xcbuild -workspace XYApp.xcworkspace -target XYApp
二、指令演示
# lxy:这个可以编译(是可以编译不一定成功)。没有指定scheme文件就是没有指定target的环境配置。但它有默认配置所以能成功。
xcodebuild -project XYApp.xcodeproj -target XYApp
# showBuildSettings:显示有关构建设置的信息。构建设置包括编译器选项、目标架构、输出目录等等。指定这个选项就不会编译了只会输出内容
# -json: 这个选项指示 xcodebuild 以 JSON 格式输出构建设置的信息
xcodebuild -project XYApp.xcodeproj -target XYApp -showBuildSettings -json
三、指令演示
xcodebuild -workspace LGApp.xcworkspace -scheme LGApp -showBuildSettings -json
xcodebuild -project LGApp.xcodeproj -scheme LGApp -showBuildSettings -json
xcodebuild -project LGApp.xcodeproj -target LGApp -showBuildSettings -json
xcodebuild -project LGApp.xcodeproj -scheme LGApp -showBuildSettings -json -configuration Debug -destination generic/ platform="iOS Simulator"
要明白一个产物构建出来需要什么物料:(源码文件、编译配置)+ target + target环境配置
xcode就是个终端
xcode就是一个终端怎么理解这句话呢?
xcode可以在Build Phases - Run scrip处执行脚本,脚本使用的解释器也是mac上安装的解释器zsh
Xcode把生成产物需要的参数(Build Settings)例如clang需要的参数,定义成环境变量,脚本在执行时就可以访问这些环境变量。
xcode就是一个终端,就是xcode提供了脚本执行时所需的环境变量、解释器、上下文。
一、给project配置config文件
1、创建xx.xcconfig文件
2、配置xx.xcconfig文件
3、在xx.xcconfig文件中声明的变量,可以在xcode这个大终端中使用
如果在 Target - Build Phases - Run Script 处直接配置的是脚本文件,在脚本文件内同样可以使用xx.xcconfig文件中的变量
二、xcode的环境变量
1、查看所有的环境变量
printenv
2、主要环境变量
# SRCROOT 项目的跟目录
SRCROOT=/Users/lixiaoyi/LXYFile/ResourceInCoding/XYApp
# 工程名称
PROJECT_NAME=XYApp
# BUILD_DIR:指定 Xcode 构建输出的目录
BUILD_DIR=/Users/lixiaoyi/Library/Developer/Xcode/DerivedData/XYApp-eitzecwceuevhddbkszxvqncrznc/Build/Products
# CONFIGURATION:表示当前的构建配置,Xcode项目中会有多个构建配置,比如 "Debug"、"Release" 等。
CONFIGURATION=Debug
# EFFECTIVE_PLATFORM_NAME:表示当前构建的目标平台的名称。这个环境变量的值通常是一个字符串,表示正在构建的目标平台,例如 "iphoneos" 或 "iphonesimulator"。
EFFECTIVE_PLATFORM_NAME=-iphonesimulator
# 构建过程中生成的二进制文件、资源文件等的存放位置
CONFIGURATION_BUILD_DIR=/Users/lixiaoyi/Library/Developer/Xcode/DerivedData/XYApp-eitzecwceuevhddbkszxvqncrznc/Build/Products/Debug-iphonesimulator
三、其它
xx.xcconfig文件规则
https://jianghuhike.github.io/2112.html
一个可以配置在Run Script处的脚本
https://jianghuhike.github.io/2117.html
cocoapods的Podfile.lock和Manifest.lock文件
一、Run Scrip 的Input Files 和 Output Files
# 递归检测输入文件是否有变更
USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES
在配置的xx.xcconfig文件中,如果打开了上述开关,只有在Run Script 的Input Files处配置的文件发生了更改才会执行脚本
这样可以提高编译速度
二、Podfile.lock 和 Manifest.lock文件
diff "${PODS_PODFILE_DIR_PATH}/Podfile.lock" "${PODS_ROOT}/Manifest.lock" > /dev/null
if [ $? != 0 ] ; then
# print error to STDERR
echo "error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation." >&2
exit 1
fi
# This output is used by Xcode 'outputs' to avoid re-running this script phase.
echo "SUCCESS" > "${SCRIPT_OUTPUT_FILE_0}"
上边是配置在Build Phases - Check Pods Manifest.lock 处的脚本代码
从代码可以看出只要Podfile.lock和Manifest.lock文件内容不同就会触发错误
假如我们将Manifest.lock文件放在本地,当我们拉取到新的Podfile.lock文件时,Podfile.lock是配置的输入文件发生了变化会触发执行脚本
这是会触发脚本错误提醒开发者Podfile.lock文件有更改了
SCRIPT_OUTPUT_FILE_0 代表 配置的第一个 输出文件
cocoapods工程的结构
一、工程结构介绍
在XYApp.xcworkspace下有两个project:
一个是XYApp.xcodeproj,这个project下有一个target是XYApp
另一个是Pods/Pods.xcodeproj,这个project下有一个target是Pods-XYApp,还有其它的target比如AFN等
而XYApp这个target只依赖Pods-XYApp这一个target就可以而不用关心像AFN这样的target
二、依赖关系介绍
如果target A要使用到target B的内容,则target A依赖target B,有两种依赖方式:
1、隐式依赖
如果target A和B在同一个project或者 workspace下,则Xcode可以自动检测依赖关系。
XYApp 和 Pods_XYApp 两个target 就是这种依赖关系
在target XYApp - General - Frameworks,libraries,and Embedded Content 下添加 Pods_XYApp.framework
当构建 XYApp 之前,会自动构建 Pods_XYApp;
2、显示依赖
需要手动添加依赖关系,Pods-XYApp和其它向AFN这样的target的关系就是这样的
依赖关系操作的是scheme
行者常至,为者常成!