iOS工程02-Pods产物,xcodeproj文件作用

1,616 阅读5分钟

上一章讲了Xcode IDE是终端,是各种Shell,ruby,python等脚本的集合,runscript运行shell,pods 是如何关联target的。

一、pods工程产物

1、 Target产物

可以 Product --> Show Build Folder in Finder 打开Build产物路径,生成在 DerivedData 文件夹下 image.png

  1. workspace名称 / 第一个project名称-复杂字符串
  2. Build文件夹
  3. Intermediates.noindex文件夹:存放中间产物
  4. Products文件夹:存放产物

如何创建相同Target呢? image.png 改名为(NYTag-US): image.png 可是NYTag-US Target并不是和NYTag同名啊,那我们在创建一个framework工程(NYTag-US)然后进行Target 修改成同名NYTag: image.png 这时候需要一个workspace来管理两个Target(NYWorkspace.xcworkspace): image.png

2、 修改Target产物

如何通过NYWorkspace.xcworkspace 修改配置产物路径呢? image.png 我们把LGCatRun.m和LGMeow.m 这两个文件,分别拖动到NYTag->Sources和NYTag-US->Sourcesimage.png 注意:Dependencies 的特点是在相同(project)作用域下才能添加引用。

核心问题
如果我要在NYTag 中使用到NYTag-US中的(xx.m xx.h)怎么办呢?

那么我们在温习一下Scheme的特点
scheme定义了要各个action使用的Target集合、以及要使用的配置以及环境变量等等。

所以一个Scheme可以定义使用多个Target了。就能解决我们在NYTag 中使用 NYTag-US 文件的问题。

创建一个Scheme - NYTag-Merge image.png 这样NYTag-Merge 就控制了两个NYTag :但是目前编译是会报错的。

产物路径规则,这两个target产出路径会重名,因此我们可以通过修改产物路径,对其多加一层文件夹来做出差异.

那么如何修改产物路径呢?

当前Shell所有环境变量
  1. 要修改路径,需要用到很多环境变量,可以使用% printenv拿到 image.png
  2. 写到脚本中就能获取Xcode的所有环境变量 :(printenv > /dev/ttys000)
  3. 可以 将环境变量的值 与已有project的路径进行比对从而确定需要使用哪几个环境变量名进行拼接

2个project 分别创建Config文件 修改CONFIGURATION_BUILD_DIR为不同路径(CocoaPods自动集成三方库也是增加了文件夹层级,只是因为是Pods所以 环境变量名前多个PODS_,可以作为参考) image.png 将2个Config文件分别应用到对应的project中,再运行时即使2个project的target同名也不会报错了 image.png (注意:PRODUCT 要换成 PROJEC) image.png 编译运行: image.png

小结:
1.产物路径是固定的
2.要使用同名target 需要配置shceme 对的target集合对应。
3.需要配置config 来生成文件夹别名区分产物路径。才能在一个workspace同时编译生成同名target产物。

3、 打印解析hmap,自定义命令

image.png 我们build 项目看到中间产物各种.hmap 文件,然后我们知道config文件可以编写编译命令:

VERBOSE_SCRIPT_LOGGING=-v

HMAP_PATH="${TEMP_FILES_DIR}/${PRODUCT_NAME}-all-non-framework-target-headers.hmap" "$(TARGET_TEMP_DIR)/${PRODUCT_NAME}-all-target-headers.hmap" "$(TARGET_TEMP_DIR)/${PRODUCT_NAME}-generated-files.hmap" "$(TARGET_TEMP_DIR)/${PRODUCT_NAME}-own-target-headers.hmap" "$(TARGET_TEMP_DIR)/${PRODUCT_NAME}-project-headers.hmap" "$(TARGET_TEMP_DIR)/${PRODUCT_NAME}.hmap"

// hmap路径?
// shell for
// DumpHeaderMap
// DumpHeaderMap ${HMAP_PATH}
CMD = source ~/.bashrc;for i in $HMAP_PATH;do DumpHeaderMap $i;done
//

TTY = /dev/ttys000

run script: printenv >/dev/ttys000 输出环境变量到终端。 image.png 在打开$SRCROOT/xcode_run_cmd.sh 运行【由于我的DumpHeaderMap(在github:作者cat1237可以下载)配置有点问题】 image.png 解决配置环境问题:

1.vim ~/.bashrc
2.export PATH=~/thirdpartyLib/custom:$PATH
3.source ~/.bashrc
4.cho $PATH

image.png 打印结果(在运行上面NYAPP01): image.png 我们创建一个工程 NYDumpHeaderMap (模仿DumpHeaderMap-自定义命令工具)image.png lldb命令:parray 2 argv image.png image.png 运行结果:

**__XPC_DYLD_FRAMEWORK_PATH=/Users/ningye/Library/Developer/Xcode/DerivedData/NYDumpHeaderMap-ajcxszcdjzgzfcfoenqyammsktzd/Build/Products/Debug**
**TMPDIR=/var/folders/v9/ry9xdp0n3mb9mfz00s2ckzt80000gn/T/**
**FZ_YN_ENV=NY**
**XPC_FLAGS=0x0**
**SHELL=/bin/zsh**
**GPUProfilerEnabled=YES**
**XPC_SERVICE_NAME=application.com.apple.dt.Xcode.8734984961.8735719237**
**NSUnbufferedIO=YES**

拷贝-Swift.h文件到指定目录

image.png 1.创建staticlibrary工程=NYLibrary
2.添加NYL.swift 文件中定义一个继承于NSObject的类
3.创建Config文件CONFIGURATION_BUILD_DIR = ${SRCROOT}/build
4.Xcode会自动生成Target名-Swift.h文件,用于OC调用Swift文件内容(OC调用Swift文件内容需要导入该头文件)因为是编译过程中产生,因此 -Swift.h 文件会放到 中间产物目录 5.在OC文件中使用Swift内容,需要导入 -Swift.h头文件

#import "NYLibrary.h"
#import "NYLibrary-Swift.h

@implementation NYLibrary
- (instancetype)init {
    self = [super init];
    if (self) {
       NYL *file = [NYL new];
    }
    return self;
}
@end

编写脚本将 -Swift.h文件 copy 到project同级文件夹下

SWIFT_H_PATH="${SRCROOT}/Swift Compatibility Header/${PRODUCT_NAME}-Swift.h"

ditto "$DERIVED_FILES_DIR/${PRODUCT_NAME}-Swift.h" "${SWIFT_H_PATH}"

二、pbxproj文件

1、pbxproj文件解析

1.我们先创建一个空project,再新建一个target,选择 macOS 类型的Command Line Tool(命令行工具)
2.然后在这个target下的 Build Phases 中我们能看到,Compile Sources中自动将main.m文件添加了进来 image.png 3.NYdpx.xcodeproj显示包内容打开project.pbxproj 查看: image.png 由此可见:pbxproj文件是用来管理,项目文件的。

核心问题:
为什么Xcode能准确的将main.m添加到Compile Sources 中,而不是 Dependencies 或者 Link Binary 呢?

4.为了有对比添加文件后的参数变化,我们先删掉project的target留个空project,然后用VS打开 project.pbxproj文件(有个pbx插件辅助看文件) image.png 能看到 pbxproj文件包含的几种Key:

key描述
archiveVersion当前文件的生成版本
classes无意义,占位
objectVersion当前文件内objects的描述版本
objects字典,以每个object的UUID作为keyobject的属性(Private、Public等)作为value
rootObject当前文件的根object的UUID(isa = PBXProject)

rootObject表示 当前文件的根object的UUID,那么我们就搜一下它UUID image.png

  • 每个object都有一个key名为isa,用来表明 当前是什么object
  • 每个object也有key名为attributes,用来表明 当前object特性,以及包含的其他object的UUID描述object的依赖与包含关系

object类型

pbxproj⽂件,已知的object:
• PBXBuildFile
• AbstractBuildPhase
• PBXBuildRule
• XCBuildConfiguration
• XCConfigurationList
• PBXContainerItemProxy:⽤来代指当前project包含的其他project
• PBXFileReference
• PBXGroup
• PBXProject
• PBXTargetDependency
• PBXReferenceProxy:当前project引⽤的,相同空间的其他project的⽂件
• AbstractTarget

还可以通过 xcodeproj --help 终端查看相应的命令。

5.创建一个NYObject,然后在看pbxproj⽂件变化了什么,发现: image.png

注:sourceTree
sourceTree的值描述
< absolute >绝对路径
< group >相对于所在group路径
SOURCE_ROOT相对于⼯程所在⽬录路径
DEVELOPER_DIR相对于DEVELOPER_DIR⽬录路径
BUILT_PRODUCTS_DIR相对于产物所在⽬录路径
SDKROOT相对于SDK⽬录所在路径

已知的AbstractTarget:

  • PBXNativeTarget:正常

  • PBXAggregateTarget:代表一组文件,占位target

  • PBXLegacyTarget:使用外部构建工具的生成的target