GYP(Generate Your Projects)是一个google开源的构建系统,最开始用于Chromium项目,现在一些其他的开源项目也开始使用GYP,如V8,Node.js,WebRTC等。
- 跨平台的工程配置工具
- 通过gyp可以生成平台相关的编译配置,比如ninja,xcode,msvs等
- 类似json格式的文件配置,维护简单,但功能强大
环境准备
配置gyp
参考: https://chromium.googlesource.com/external/gyp
git clone https://chromium.googlesource.com/external/gyp
配置depot_tools (ninja)
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
使用gyp的例子
cpp文件
// gypTest.cpp
#include <iostream>
int main()
{
std::cout << "hello gyp!" << std::endl;
return 0;
}
gyp配置
# gypTest.gyp
{
'target_defaults': {
'default_configuration': 'Release',
'configurations': {
'Debug': {},
'Release': {},
},
},
'targets':[
{
'target_name': 'gypTest',
'type': 'executable',
'sources' : [
'gypTest.cpp'
],
},
],
}
gyp命令
gyp --depth=. -f ninja gypTest.gyp
会生成基于ninja的编译配置,ninja是一个跨平台的高效的编译工具,接下来就可以通过
ninja -C out/Debug gypTest
来编译了。
gyp --depth=. -f xcode gypTest.gyp
会生成xcode的工程,在Mac下就能通过xcode来打开和编译调试。
说明:
–depth
指定工程的根目录,–generator-output
指定工程文件的输出目录,默认为当前目录,-f
指定生成工程文件的类型,常用的有ninja, xcode, msvs, xcode-ninja。更多的命令行选项可以通过gyp -h
查看
分析下chromium的gyp配置
gyp_pylib(src/tools/gyp)
这是gyp的实现部分,用python来实现,因此可以通过python导入gyp库来开发;同时gyp还提供了各个平台的脚本,可以通过脚本gyp命令(Windows下是gyp.bat)来快速生成工程配置。
gyp_chromium
这是chromium包装gyp库的python文件,通过提供了很多自定义的机制,比如可以通过-D传递gyp的变量,同时也可以通过设置环境变量来改变gyp的配置和行为。
常用用法说明:
-D
自定义gyp变量指- os.environ设置环境变量
- 默认是 all.gyp 把整个chrome工程的顶层target及依赖定义好
- 通过设置CHROMIUM_GYP_FILE环境变量,比如
os.environ['CHROMIUM_GYP_FILE'] = 'base/base.gyp'
可以指定使用gyp文件,而不是默认的all.gyp - 默认会包含 common.gypi 通用的变量和配置
基于 gyp_chromium 的简单包装
比如:只想以shared_library模式编译base库,可以使用如下的包装;稍加丰富这个python脚本,可以实现更多的自定义能力。
# -*- coding: utf-8 -*-
__author__ = 'suninf'
import os
import json
import xml.dom.minidom
import sys
import subprocess
import getopt
def getstatusoutput(cmd):
print cmd
args = cmd.split(" ")
pipe = subprocess.Popen(args, stdout=subprocess.PIPE, shell=False, universal_newlines=True)
output = "".join(pipe.stdout.readlines())
sts = pipe.returncode
if sts is None:
sts = 0
return sts, output
if __name__ == '__main__':
common_flags = ["flag1=value1", "flag2=value2"]
os.environ['CHROMIUM_GYP_FILE'] = 'base/base.gyp';
opts, args = getopt.getopt(sys.argv[1:], "", ["static", "only-ninja"])
flags = common_flags
flags.append("component=shared_library")
cmd = "python build/gyp_chromium"
for flag in flags:
cmd = cmd + " -D " + flag
ret,err = getstatusoutput( cmd )
if ret==0:
print "success"
else:
print "error with code: %d" % (ret)
print err
关于gyp语法
gyp的详细语法也比较复杂,比如:
- 依赖
- 变量及其使用
- 条件判断
- 预定义宏
- 依赖的文件路径与库路径
详细的语法还是要在使用的不断的参考和测试来掌握,gyp官方文档可以参考:https://gyp.gsrc.io/