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语言中,一个数组只是指向了数组的第一个字节。

    总结

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

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

  • 相关阅读:
    pandas Dataframe filter
    process xlsx with pandas
    data manipulate in excel with easyExcel class
    modify registry in user environment
    add number line in vim
    java import webservice
    ctypes MessageBoxA
    music 163 lyrics
    【python实例】自动贩卖机
    【python基础】sys模块(库)方法汇总
  • 原文地址:https://www.cnblogs.com/YungMing/p/4371691.html
Copyright © 2011-2022 走看看