GYP,Generate Your Projects,一个google开源的构建系统,最开始用于Chromium项目,现在一些其他的开源项目也开始使用GYP,如V8和node-gyp。本文是学习使用GYP的笔记,算是一个GYP的简明教程吧。

特别之处

在已经有很多的构建系统的情况下,gyp诞生的哲学或者说优点如下:

  1. 各平台使用各自主流的构建系统。

    • 程序员更熟悉自己的平台,减少学习成本。
    • 构建速度快。自己平台的主流构建系统的速度是各平台优化过的。
  2. 在一个平台上可以生成所有支持的平台的工程文件。
    • 如在mac上也可以生成Visual Studio工程,windows上也可以生成Xcode工程。
  3. 生成的工程文件和手工创建的工程文件没有区别
    • 这样,随时可以停止使用gyp。别人可以只使用相关工程文件而不使用gyp

安装

前提条件:本机需要安装python,svn或git。

下载:
svn方式,svn checkout http://gyp.googlecode.com/svn/trunk/ <gyp-dir>
git方式,git clone http://git.chromium.org/external/gyp.git <gyp-dir>git clone https://git.chromium.org/git/external/gyp.git <gyp-dir>

安装:
有两种安装方式。

  1. 执行安装命令

    1
    2
    
    cd <gyp-dir> # 刚才的下载目录
    [sudo] python setup.py install
    

    这个命令做的事情主要是安装python的第三方扩展到/Library/Python/2.7/site-packages/gyp-0.1-py2.7.egg,并把gyp的可执行文件copy到/usr/local/bin。

  2. 简易安装,直接将<gyp-dir>加入PATH。

使用

  1. 编写.gyp文件
  2. 运行gyp命令生成makefile、build.ninja文件或xcode、vs等工程
  3. 编译。根据第2步的结果,运行make、ninja或者在xcode、vs里编译

举一个最简单的例子,源文件如下:

main.cpp

1
2
3
4
5
6
#include <iostream>

int main(int argc, const char* argv[]) {    std::cout << "Hello World!" << std::endl;
    return 0;
}

编写.gyp文件如下: main.gyp

1
2
3
4
5
6
7
8
9
10
11
{  'targets': [
    {      'target_name': 'main',
      'type': 'executable',
      'sources': [
        'main.cpp',
      ],
    },
  ],
}

在源文件目录下运行命令gyp --depth=. main.gyp,生成工程文件。打开生成的工程文件编译、运行即可。

更多例子可以参考play_gyp

生成跨平台工程的实践经验

如上个例子中展示的,运行gyp命令的大概方式为gyp --depth=. --generator-output=build -f ninja main.gyp,其中 –depth指定工程的根目录,–generator-output指定工程文件的输出目录,默认为当前目录,-f指定生成工程文件的类型,常用的有'make', ‘ninja’, ‘xcode’, ‘msvs’, ‘scons'。更多的命令行选项可以通过gyp -h查看。

工程实践中还有一种更方便的生成不同平台工程的方法,即使用gyp的全局变量。定义全局变量的好处是可以使用别人封装好的gyp脚本,如Chromium工程中就可以使用gyp_chromium.py了。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# iOS 真机
export GYP_DEFINES="$GYP_DEFINES OS=ios target_arch=armv7"
export GYP_CROSSCOMPILE=1
export GYP_GENERATOR_OUTPUT=../build
export GYP_GENERATORS=xcode

# iOS 模拟器
export GYP_DEFINES="$GYP_DEFINES OS=ios target_arch=ia32"
export GYP_CROSSCOMPILE=1
export GYP_GENERATOR_OUTPUT=../build
export GYP_GENERATORS=xcode

# mac
export GYP_DEFINES="$GYP_DEFINES OS=mac target_arch=x64"
export GYP_GENERATOR_OUTPUT=../build
export GYP_GENERATORS=xcode

# android arm target
export GYP_DEFINES="$GYP_DEFINES OS=android"
export GYP_CROSSCOMPILE=1
export GYP_GENERATOR_OUTPUT=../build
export GYP_GENERATORS=ninja

# android x86 target
export GYP_DEFINES="$GYP_DEFINES OS=android target_arch=ia32"
export GYP_CROSSCOMPILE=1
export GYP_GENERATOR_OUTPUT=../build
export GYP_GENERATORS=ninja

# android MIPS target
export GYP_DEFINES="$GYP_DEFINES OS=android target_arch=mipsel"
export GYP_CROSSCOMPILE=1
export GYP_GENERATOR_OUTPUT=../build
export GYP_GENERATORS=ninja

# windows
export GYP_DEFINES="$GYP_DEFINES OS=win"
export GYP_GENERATOR_OUTPUT=../build
export GYP_GENERATORS= msvs # or msvs-ninja
export GYP_MSVS_VERSION = 2008

# linux
export GYP_DEFINES="$GYP_DEFINES OS=linux" # or unix
export GYP_GENERATOR_OUTPUT=../build
export GYP_GENERATORS=make

# gyp 其他可用的 环境变量
GYP_GENERATOR_FLAGS

也可以通过修改GYP_GENERATORS,生成各种类型的工程文件

  • ninja for Ninja
  • make for Makefiles
  • msvs for Visual Studio
  • msvs-ninja for Visual Studio project building with ninja
  • xcode for Xcode

gyp文件语法

GYP的输入文件习惯上后缀为.gyp或.gypi。.gypi文件作为.gyp文件的include文件。 以Visual Studio为例,.gyp文件对应.sln工作空间,.gyp文件中的target对应.vcproj或.vxcproj工程。

.gyp文件的顶级元素为'variables’, ‘includes’, ‘target_defaults’, ‘targets’, ‘conditions'。语法是JSON,或者说是允许trailing comments的python。.gyp文件之间其实可以不用相互引用,gyp会递归的扫描当前目录的所有子目录,处理扫描到的所有*.gyp文件。

官方文档

  • 模版和例子:GypUserDocumentation
  • 主要元素或者配置项:GypLanguageSpecification
  • 基本语法:InputFormatReference

变量

变量分为三类,Predefined、User-defined、Automatic。
变量设置默认值的方法:name%:value。只有name未定义时,才将name的值设置为value.

  • Predefined,命名习惯为CAPITAL_LETTERS。

    1. OS:用于判断操作系统
    2. EXECUTABLE_PREFIX:可执行文件的前缀
    3. EXECUTABLE_SUFFIX:可执行文件的后缀
    4. INTERMEDIATE_DIR:中间文件目录,只对单一target有效
    5. SHARED_INTERMEDIATE_DIR:中间文件共享目录,所有target(包括跨.gyp文件的target)共用同一目录
    6. PRODUCT_DIR:输出文件(编译出的可执行文件、库等)的主目录
  • User-defined,命名习惯为lowercase_letters。变量使用的方式如下
    1. <(VAR) early phase, value is string
    2. >(VAR) post phase, value is string
    3. <@(VAR) early phase, value is list
    4. >@(VAR) post phase, value is list
  • Automatic,dictionary中,name:string的key/value对会自动生成一个_name的变量,值为string

命令

gyp可以执行shell命令,即将命令内容传递给shell执行,然后获得返回值。
用法为<!(cmd)<!@(cmd),前者返回值为string,后者返回值为list。

这样,虽然gyp没有提供通配符,但是可以通过命令实现这个功能,如实现添加当前目录下所有.cpp后缀的文件作为sources:

1
2
3
'sources': [
    '<!@(ls -1 ./*.cpp)',
],

target的配置项目

顶级元素下的target_defaults中可以设置所有targets共用的配置项目,targets中可以具体配置每个target。
常用的target可分为可运行程序、静态库、动态库等,但在跨平台时,不同平台的target各不相同,参数的设置也相差很远。 target的通用框架如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{    'targets': [{        'target_name': 'target_one',
        'type': 'executable',
        'dependencies': [
            'xyzzy',
            '../bar/bar.gyp:bar',
        ],
        'defines': [
            'DEFINE_FOO',
            'DEFINE_A_VALUE=value',
        ],
        'include_dirs': [
            '..',
        ],
        'sources': [
            'file1.cc',
            'file2.cc',
        ],
        'conditions': [
          ['OS=="linux"', {}],
          ['OS=="win"', {}]
        ],
    },],
}

target的一些常用配置,各个平台都差不多,gyp提供了统一的设置方法。
defines为宏定义,对应-D或/D;
include_dirs对应-I或/I;
cflags为编译选项,对应类似-Werror或/Werror;
ldflags为链接选项,对应类似-pthread;

target还有一些在类型不同、平台不同时,差别很大的配置,列举一些如下:

  • 静态库或动态库

direct_dependent_settings:定义一些编译参数、宏定义等,这些定义将导出到直接依赖该库(通常是第三方库)的target
all_dependent_settings:定义一些编译参数、宏定义等,这些定义将导出到所有依赖该库的target,包含直接依赖和间接依赖
link_settings:定义一些当将该库作为输入时需要配置的链接参数。通常是对静态库有效,动态库忽略
export_dependent_settings:列出一些dependencies中的target,direct_dependent_settings定义的配置将应用到export_dependent_settings列出的target。即将依赖该库的配置导出到该库依赖的target

  • 跨平台工程

针对各个平台不同的配置,gyp的策略是直接使用各平台工程的原生参数。如生成Xcode工程时,可以直接在gyp文件中使用SDKROOT,TARGETED_DEVICE_FAMILY等Xcode中使用的参数。

在xcode_settings对象中设置Xcode的特有参数
在msvs_settings对象中设置Visual Studio的特有参数。

这种策略有一个便利之处。以Xcode工程为例,如果有不知道怎么设置的选项,可以先在Xcode工程中设置好,再从工程文件.xcodeproj包内的project.pbxproj文件中拷贝出来,同步到.gyp文件中。

gyp的潜规则

  1. target的sources项会按照对应平台自动过滤后缀(*_linux.{ext}, *_mac.{ext}, *_posix.{ext} or *_win.{ext})不符合的源文件。

参考资料

  1. gypDemo
  2. gypGettingStarted

平台交叉打包 GYP相关推荐

  1. Android 系统(138 )---Mtk平台 Android 打包解包*.img ,修改system.img 参数

    Mtk平台 Android 打包解包*.img ,修改system.img 参数 MTK 升级包文件如下: 若存在软件版本号存在错误或需要修改,重新编译则需要几个小时,或者要几天的测试 若可以直接修改 ...

  2. Windows 平台下打包 bzip2 和 gzip 格式压缩包

    Windows 平台下打包 bzip2 和 gzip 格式压缩包 问题起因 bzip2 和 gzip 压缩格式是 Linux 下非常流行的压缩文件格式,且压缩率比传统的 rar 等格式高,因此笔者非常 ...

  3. cocos2d-x基于windows平台交叉编辑android工程

    cocos2d-x确实是一款优秀的引擎,尽管和正规军的unity3d比起来它显得有点土,但它在移动平台上的性能表现着实惊艳. 以下讲解如何将win32工程交叉编译到android平台. 一.环境搭建 ...

  4. zynq平台交叉编译器的安装

    一.创建工作目录 新建工作目录 zynq,并进入该目录.新建 packs 目录,目的是存储源码安装包,拷贝相关文件到该目录. mkdir zynq cd zynq mkdir packs 二.解压文件 ...

  5. Linux平台应用打包的几种方法(qt/dll --> exec|appimage)

    首先,linux平台常用的打包方式,就是通过ldd查看依赖库,然后将依赖库的依赖复制过来,然后写一个脚本,让用户在运行的时候,运行这个脚本,然后这个脚本设置好环境变量(主要是将依赖库添加到环境变量中) ...

  6. Wince平台软件打包

    wince平台使用最多的是PDA手持设备,使用c#可以开发基于该平台的软件.软件开发后需要打包,这里介绍一款打包软件WinCE.CAB.Manager,个人感觉还不错 ,可以设置桌面图标,开始菜单,快 ...

  7. Android云打包平台,Android平台云端打包使用的DCloud公用证书(安卓证书)

    HBuilder|HBuilderX应用云端打包Android平台默认使用的DCloud公用证书,其信息如下: MD5: 59:20:1C:F6:58:92:02:CB:2C:DA:B2:67:52: ...

  8. Qt4程序在windows平台下打包发布

    一.打包成绿色版 将源码编译成release版,运行*.exe文件,提示缺少*.dll,在Qt安装目录中找到相应的dll文件(一般在bin目录下),将dll文件复制到exe文件目录下即可. 二.打包成 ...

  9. 安卓8.X解包打包工具和教程,windows平台一键打包解包工具

    ROM制作工具在上周独家适配了安卓8.X的解包打包功能,很多朋友对这个功能翘首以盼,历经一个月的适配完善,得到了广泛认可. 软件是免费使用的哦! ROM制作工具目前已经是windows下最强大的一键解 ...

  10. android语音插件,Android平台离线打包 - 语音识别(Speech)插件配置

    百度语音设置 需要添加的文件 将以下文件放入工程的libs下 路径 文件名SDK\libs speech-release.aar.speech_baidu-release.aar AndroidMan ...

最新文章

  1. C语言----字符串左旋
  2. 数据库类型少_全栈之数据库系列 - 数据库的设计、架构和使用规范
  3. java注释日志打印_java 日志文件打印
  4. ITK:通过镜像填充图像
  5. 航海王_html_css3_旋转效果demo
  6. R中安装LightGBM(Windows 64位)
  7. prepareStatement的用法和解释
  8. 线性回归与分类, 解决与区别
  9. 用Eclipse创建第一个JSP项目
  10. imx8mq - bootloader编译过程
  11. idea的导包快捷键+自动导包设置
  12. 帝国php漏洞,帝国cms远程代码执行漏洞-1
  13. 翁恺老师 | 城堡游戏解读
  14. win10开机提示服务未登录,无法加载用户配置文件
  15. mysql 从大到小排序
  16. 激光三角测量物体高度
  17. MOOC中国接受《环球时报》英文版专访:MOOC证书对求职有用吗?
  18. 球形/PH响应性的树枝状聚合物:树枝状聚酰胺PAMAM/His-PAMAM/DNA 聚酰胺偶联组氨酸/的制备流程
  19. n3160装微软服务器,英特尔赛扬N3160处理器性能跑分评测
  20. BZOJ1415: [Noi2005]聪聪和可可

热门文章

  1. DTAS棣拓公差分析软件尺寸链计算:DTAS Talk尺寸联盟参与公益课
  2. 第一次学游泳技巧_包你第一次下水就能学会游泳的方法
  3. aardio匹配问题以及编码问题
  4. 【大数据技术详解】搭建redis集群服务的步骤和配置以及解决创建集群时会遇到的错误:NodeX replied with error:ERRInvalid node address specified
  5. Linux内核访问用户空间文件 filp_open/vfs_read/vfs_write/set_fs/get_fs
  6. macOS免费串口工具coolTerm/Minicom/Comtool/Volt+(伏特加)/友善串口调试助手/screen/picocom
  7. 瑞士轮赛制模拟器_【入门必读】VGC综合介绍(下篇)【翻译】
  8. Java 1072 开学寄语
  9. MATLAB2016笔记(七):数据分析
  10. clustMD r语言_R语言做聚类分析Kmeans时确定类的个数