zoukankan      html  css  js  c++  java
  • Xcode 构建规则

    本文翻译自:Xcode Build Rules

    当我把默认的CSS样式规则独立到一个文件中时,我面临着一个困境:我如何才能把这个文件嵌入进静态库中,同时又很容易地向里面添加内容。我之前讲解了如何把任意的文件转换为 C 字节码数组。但是仍然需要手动操作。

    我做了一些搜索,发现在常规的Linux系统上,人们似乎有一个名叫 objcopy 的工具,可以把文件复制到一个对象文件(.o)里面,从而最终通过链接器把这些对象文件链接起来。但遗憾的是这个工具并没有在Xcode中出现。所以这是不可能的,因为我希望所有人都可以构建DTCoreText。

    Xcode 的构建规则拯救了我们。它可以自动化任何类型的操作,似乎这是这个问题的一种解决方案。

    Xcode知道如何处理三种基本的源文件(非常简单):

    • c, c++ or Objective-C 源码,或者任何可以被编译的代码

    • 头文件

    • 其它类型文件

    如果你把 “其它类型文件” 添加到一个构建目标中(target),会被当作资源,仅仅是复制到你的应用包中。

    现在我将教你如何把任何类型文件变成可编译的。例如你想在构建你的游戏时将一些纹理图片压缩,或者想把某些资源文件嵌入你的二进制文件中。

    创建一个构建规则

    当Xcode被要求编译一个文件时,它会有一系列的规则来约定如何去做。现在我们将要做的就是添加我们自己的规则,来把一个CSS文件转换成一个 .c 文件。而对于.c 文件,Xcode有一个内建的构建规则。你可以使用两个或者多个链式规则来组合处理每个规则返回的结果。

    有一点不是很方便的就是,你不能定义全局的规则。你必须对每个构建目标重复定义你的构建规则。

    为了添加你的构建规则,你可以去到项目信息里面来查看你的构建目标,如下:

    这个规则对所有.css后缀格式的文件起作用,然后会执行一个自定义的脚本:

    cd "$INPUT_FILE_DIR"  # move into file dir, otherwise xxd takes the full path for the symbol
    /usr/bin/xxd -i "$INPUT_FILE_NAME" "$DERIVED_SOURCES_DIR/$INPUT_FILE_BASE.css.c" # builds a c file with a hex array
    

    首先进入到输入文件所在的目录,因为 xxd 命令总是会将完整的路径转换为c数组的名称。上面的形式就会被命名为 default_c ,长度将会是 default_c_len。

    上面的规则将会告诉Xcode如何把一个 .css文件 转换为一个 .c 文件。下一步就是确保我们的default.css文件会被编译,而不是被复制。

    编译、不复制

    你可以在Build Pases栏目下看到default.css 放到了 Compile Sources下面。

    如果你编译这个项目,你可以看到所有的编译过程日志信息。在构建日志的上面,你可以看到文件被预处理,再下面一点你可以看到编译出来的c文件。

    再下面,这个库工具把所有的对象文件放到了库归档里面。如果你不相信我,你可以试试 nm 工具来检查最终产品的对象符号。

    nm DemoApp | grep default_c
    00045474 D _default_css
    00045fe0 D _default_css_len
    

    在default.css.c 文件中有两个符号。下面我将告诉你如何访问到这些符号。

    访问对象化的文件

    上面我讲过, xxd 命令会用传过来的文件名字来创建两个变量,一个是c类型的数组,一个是长度。唯一改变的就是必须要把文件名转换成合法的字符,所以 点 符号转为下划线。

    DTCSSStylesheet.m 文件里,我向下面那样访问这个数组。我声明两个外部变量,提示链接器插入正确的地址给他们。

    + (DTCSSStylesheet *)defaultStyleSheet
    // external symbols generated via custom build rule and xxd
    extern unsigned char default_css[];
    extern unsigned int default_css_len;
    }
    

    那么从它们里面拿到字符就很容易了:

    + (DTCSSStylesheet *)defaultStyleSheet
    {
        // get the data from the external symbol
        NSData *data = [NSData dataWithBytes:default_css length:default_css_len];
        NSString *cssString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    
        return [[DTCSSStylesheet alloc] initWithStyleBlock:cssString];
    }
    

    这样可以正常执行,因为我知道所有我的资源都是UTF8 编码的。例如,一个字符占用一个字节。变量default_css_len 整数可以很方便地告诉我们数组的长度,因为在C语言中,一个数组只是指向了数组的第一个字节。

    总结

    现在,有了自定义构建规则,你不用每次在构建前执行而外的外部脚本,现在这些都集成到构建过程了。你能通过这个规则做什么取决于你的想象力和你的脚本能力。

    使用自定义构建规则比使用外部程序有一个优点,就是它们本身是项目的一部分。所以如果它们使用标准的命令,那么就可以无缝地移植到其他开发人员的机器上,这对于开源项目非常有用。

  • 相关阅读:
    真题-中国科学技术大学2017年夏令营数学分析试题
    真题-中国科学技术大学2019年夏令营实变函数复变函数试题
    真题-中国科学技术大学2019年夏令营数学分析高等代数试题
    真题-中国科学技术大学2021年夏令营微分几何近世代数试题
    真题-中国科学技术大学2021年夏令营实变函数复变函数试题
    真题-中国科学技术大学2021年夏令营数学分析高等代数试题
    竞赛厦门大学第15届景润杯数学竞赛数学类试题参考解答
    厦门大学第16届景润杯数学竞赛数学类试题参考解答
    厦门大学第17届景润杯数学竞赛数学类试题参考解答
    厦门大学第18届景润杯数学竞赛数学类试题参考解答
  • 原文地址:https://www.cnblogs.com/YungMing/p/4371691.html
Copyright © 2011-2022 走看看