Xcode构建阶段输入文件夹

时间:2016-04-05 11:51:10

标签: ios xcode

我有一个自定义"运行脚本"构建阶段,根据文件夹A中包含的文件生成一些源文件。构建阶段在"编译源"之前执行。建设阶段。在生成源文件时,我想避免每次运行时触发完整的项目重建,我想利用"输入文件"和"输出文件"部分,as described in this blog post

不幸的是,文件夹A是一个文件夹而不是文件。当我提供文件夹A的路径为"输入文件"时,如果文件夹中没有任何内容发生更改,则无法正确执行构建阶段。当我重命名一些文件时,构建阶段也正确执行。 但是当更改文件夹A内的文件中的内容时,不会执行构建阶段

我尝试提供的文件夹名称不包含*,最后也包含***

当给定输入文件夹中的任何文件发生更改(添加,删除,修改内容)时,如何执行构建阶段?。

1 个答案:

答案 0 :(得分:3)

有两个极端:喜欢使用Xcode的人和那些倾向于避免使用Xcode的人,除了只能通过它完成的工作。这是一个开发人员的答案,他不喜欢所有Xcode的非IDE功能:我不知道你的确切问题的答案,我甚至不想,因为我试图避免使用Xcode来超越它的任何东西默认功能。

就我的问题而言,你有一些你需要对它进行处理的东西,以便处理产生一些OUT的东西。我们称之为Subproject:包含IN,OUT和处理的内容:IN -> OUT。并且您希望此处理是增量的:如果已经完成,则不要重复相同的工作,即如果OUT在那里而IN未被修改则不执行处理IN -> OUT因为结果已经存在。

对于这种任务,我使用Make(任何其他构建系统很好,例如Ninja),这正是完成这项工作的工具:你描述你需要的东西,描述你拥有的东西和转换过程,它可以工作并为您提供增量处理。

您可以通过编写正确的cd Subproject; make来放置IN -> OUT并将与Makefile处理相关的所有内容委托给Make,而不是修改Xcode的“运行脚本”阶段的构建阶段。 Xcode中唯一剩下的就是Run Script阶段,它将你的构建规则的这个委托执行到Make。

我创建了一个示例来解决您的问题并演示了基于Make的子项目与Xcode项目的集成:Xcode and Make

├── README.md
├── Subproject
│   ├── Generated-Code
│   │   ├── file1.out
│   │   ├── file2.out
│   │   └── file3.out
│   ├── Makefile
│   └── Source
│       ├── file1.in
│       ├── file2.in
│       └── file3.in
└── Xcode-and-Make
    ├── Xcode-and-Make
    │   └── main.m
    └── Xcode-and-Make.xcodeproj
        └── project.pbxproj

自定义内容在Subproject文件夹中被隔离。此文件夹包含在Xcode项目中:Generated-Code .out文件包含在项目的主目标中,* .in文件不包含在内,Makefile也不包括在内。

在项目的“运行脚本”阶段,只能调用Make:

cd ../Subproject
make

所有Source/*.in -> Generated-Code/*.out处理都在Makefile中完成,其编写如下:

IN_PATH=./Source
IN_FILES=$(wildcard $(IN_PATH)/*.in)

OUT_PATH=./Generated-Code

OUT_FILES := $(patsubst %, $(OUT_PATH)/%, $(notdir $(IN_FILES)))
OUT_FILES := $(patsubst %.in, %.out, $(OUT_FILES))

default: generate

generate: $(OUT_FILES)

clean:
    rm -rf $(OUT_PATH)

$(OUT_PATH)/%.out: $(OUT_PATH) $(IN_PATH)/%.in
    cp -v $(IN_PATH)/$*.in $(OUT_PATH)/$*.out

$(OUT_PATH):
    mkdir -p $(OUT_PATH)

如果你是新手,那么所有这些符号一开始可能会让人感到困惑,但是在阅读了一天的教程之后,让你对Make如何运作有基本的了解。

编写此Makefile是为了进行增量处理:cp只是简单的演示操作,它将*.in复制到*.out - 在实际应用中它可以是编译器或其他一些工具。

Subproject文件夹内,您第一次看到make时会看到:

Subproject$ make
mkdir -p ./Generated-Code
cp -v ./Source/file1.in ./Generated-Code/file1.out
./Source/file1.in -> ./Generated-Code/file1.out
cp -v ./Source/file2.in ./Generated-Code/file2.out
./Source/file2.in -> ./Generated-Code/file2.out
cp -v ./Source/file3.in ./Generated-Code/file3.out
./Source/file3.in -> ./Generated-Code/file3.out

但是在第二轮你会得到:

Subproject$ make
make: Nothing to be done for `default'.

那是因为Make很明白你没有对任何*.in文件进行任何修改,所以要让Make再次执行它的处理,你需要在{{1}中实际执行一些更改文件,这正是你原来的问题所在。

我认为示例项目是最好的展示,所以请随意决定是否偏离Xcode的默认设置会让您感到舒服,并随时询问您是否还有其他问题。

免责声明:我已经使用Make 2年(几乎)所有涉及构建Xcode无法处理的东西所以我强烈建议你学习Make的基础知识:它可以是构建脚本的非常强大的工具,其中增量处理很高兴。