GYP
是一个元构建系统,一个生成其他构建系统的构建系统
GYP
旨在支持需要构建在多个平台上的大型项目(例如,Mac
、Windows
、Linux
),重要的是项目可以使用在每个平台上流行的IDE
来构建,就像项目是一个“本地”项目一样。
它可以用来生成XCode
项目、Visual Studio
项目、Ninja
构建文件和makefile
文件。在每种情况下,GYP
的目标都是尽可能地复制使用IDE
设置本机构建项目的方式。
GYP
还可以用于生成“混合”项目,这些项目为良好的用户体验提供IDE
脚手架,但需要Ninja
来进行实际的构建(这通常比IDE
的本地构建系统快得多)。
本文档旨在提供用户级的GYP
指南,这里的重点是如何使用GYP
来完成特定的任务,而不是完整的技术语言规范。(对此,请参阅语言描述。)
下面的文档从提供上下文的览开始:.gyp
文件本身的结构概览、.gyp
文件中典型的可执行程序目标概览、.gyp
文件中典型的库目标概览。
在概览之后,有一些针对不同常见用例的gyp
模式示例。
这是Chromium
项目中一个典型的.gyp
文件的骨架:
{
'variables': {
.
.
.
},
'includes': [
'../build/common.gypi',
],
'target_defaults': {
.
.
.
},
'targets': [
{
'target_name': 'target_1',
.
.
.
},
{
'target_name': 'target_2',
.
.
.
},
],
'conditions': [
['OS=="linux"', {
'targets': [
{
'target_name': 'linux_target_3',
.
.
.
},
],
}],
['OS=="win"', {
'targets': [
{
'target_name': 'windows_target_4',
.
.
.
},
],
}, { # OS != "win"
'targets': [
{
'target_name': 'non_windows_target_5',
.
.
.
},
}],
],
}
整个文件只包含一个Python
字典。(它实际上是JSON
,具有两个Python
的小差异:注释用#
, 逗号,
位于list
或是dictionary
最后一个元素之后是合法的。 )
.gyp
文件的顶级部分如下:
variables
: 可以在文件的其他部分插入和使用的变量的定义。includes
: 将包含在此文件中的其他文件的列表。按照惯例,包含的文件后缀为.gypi
(gyp include
)。target_defaults
: 适用于这个.gyp
文件中定义的所有目标的设置。targets
: 这个.gyp
文件可以生成构建的目标列表。每个目标都是一个字典,其中包含描述构建目标所需的所有信息的设置。conditions
: 一个条件规范列表,它可以根据不同变量的值修改.gyp
文件定义的全局字典中的项的内容。如上例所示,顶级字典中的条件部分最常见的用法是添加特定平台的目标到目标列表中。最直接的目标可能是一个简单的可执行程序。下面是一个可执行目标示例,它演示了gyp
最简单的用法
{
'targets': [
{
'target_name': 'foo',
'type': 'executable',
'msvs_guid': '5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65',
'dependencies': [
'xyzzy',
'../bar/bar.gyp:bar',
],
'defines': [
'DEFINE_FOO',
'DEFINE_A_VALUE=value',
],
'include_dirs': [
'..',
],
'sources': [
'file1.cc',
'file2.cc',
],
'conditions': [
['OS=="linux"', {
'defines': [
'LINUX_DEFINE',
],
'include_dirs': [
'include/linux',
],
}],
['OS=="win"', {
'defines': [
'WINDOWS_SPECIFIC_DEFINE',
],
}, { # OS != "win",
'defines': [
'NON_WINDOWS_DEFINE',
],
}]
],
},
],
}
目标的顶级设置包括:
target_name
: 目标的名称,它应该在所有.gyp
文件中是唯一的。这个名称将在生成的Visual Studio
解决方案中用作项目名,在生成的XCode
配置中用作目标名,并在生成的SCons
配置的命令行中用作构建这个目标的别名。type
: 设置为executable
,表明可执行。msvs_guid
: 这个变量只过渡使用。这是一个硬编码的GUID值,将在生成的Visual Studio
解决方案文件中使用。这让我们将gyp
生成的项目文件互操作记录到一个chrome.sln
文件。一旦Chromium
中的所有内容都由gyp
生成,那么跨调用保持guid
不变就不再重要了,我们可能会去掉这些设置dependencies
: 目标所依赖的其他目标列表。gyp
生成的文件将确保在此目标之前构建其他目标。依赖项列表中的任何库目标都将与此目标链接。在目标的direct_dependent_settings
部分中列出的各种设置(definition
, include_dirs
等)将应用于如何构建和链接该目标。请参阅下面关于direct_dependent_settings
的更完整的讨论。definitions
: 将通过编译命令行传递的C
预处理器定义(使用-D
或/D
选项)。include_dirs
: 包含头文件的目录。它们将通过编译命令行传递(使用-I
或/I
选项)。sources
: 此目标的源文件。conditions
: 一个条件块,用于更新目标字典中的不同设置。绝大多数目标是库。下面是一个库目标的例子,其中包括了应该涵盖库的大多数需求的附加特性
{
'targets': [
{
'target_name': 'foo',
'type': '<(library)'
'msvs_guid': '5ECEC9E5-8F23-47B6-93E0-C3B328B3BE65',
'dependencies': [
'xyzzy',
'../bar/bar.gyp:bar',
],
'defines': [
'DEFINE_FOO',
'DEFINE_A_VALUE=value',
],
'include_dirs': [
'..',
],
'direct_dependent_settings': {
'defines': [
'DEFINE_FOO',
'DEFINE_ADDITIONAL',
],
'linkflags': [
],
},
'export_dependent_settings': [
'../bar/bar.gyp:bar',
],
'sources': [
'file1.cc',
'file2.cc',
],
'conditions': [
['OS=="linux"', {
'defines': [
'LINUX_DEFINE',
],
'include_dirs': [
'include/linux',
],
],
['OS=="win"', {
'defines': [
'WINDOWS_SPECIFIC_DEFINE',
],
}, { # OS != "win",
'defines': [
'NON_WINDOWS_DEFINE',
],
}]
],
],
}
库目标中可能的条目与可执行目标中指定的条目基本相同(definition
, include_dirs
等)。区别包括:
type
: 总是应该设置为<(library)
,这允许用户在生成构建项目时定义库是静态构建还是共享构建。(至少在Linux上
,链接共享库可以节省大量链接时间)如果有必要确定要构建的库的类型,则可以显式地将type
设置为static_library
或shared_library
。direct_dependent_settings
: 这定义了将应用于直接依赖于此目标的其他目标的设置——也就是说,在它们的dependencies
设置中列出此目标。这是你列出defines
,include_dirs
, cflags
和linkflags
的地方,其他目标编译或链接需要一致地建立这个目标。export_dependent_settings
: 这列出了应该将direct_dependent_settings
“传递”给使用(依赖于)此目标的其他目标的目标。TODO
:对这个描述进行扩展。这些用例旨在涵盖开发者使用GYP
执行的最长见操作。
请注意,这些示例都不是功能完整的、自包含的示例(否则它们就太长了)。每个示例大多只包含与示例相关的关键字和设置,可能还有一些用于上下文的额外关键字。这样做的目的是为了展示你在做某件事时需要注意的具体细节。[ 注:如果在实际使用中,这些例子在没有上下文的情况下让人感到困惑,请添加必要的内容来澄清。]
添加独立于平台的源文件与添加只在某些受支持平台上构建的源文件有相似之处,但也有些许不同的模式。
最简单的情况: 添加一个在所有平台上构建的文件。 只需将文件添加到目标列表中相应字典的源列表中:
{
'targets': [
{
'target_name': 'my_target',
'type': 'executable',
'sources': [
'../other/file_1.cc',
'new_file.cc',
'subdir/file3.cc',
],
},
],
},
文件路径名相对于.gyp
文件所在的目录。
保持列表按字母顺序排列(除非有非常、非常、非常好的理由不这样做)。
特定平台的文件名为*_linux.{ext}
、 * _mac.{ext}
、* _posix.{ext}
或* _win.{ext}
要添加一个特定平台的源文件,最简单的方法(假设你要添加一个全新的文件并命名它)是使用以下标准后缀之一:
_linux
(例如foo_linux.cc
)_mac
(例如foo_mac.cc
)_posix
(例如foo_posix.cc
)_win
(例如foo_win.cc
)只需将该文件添加到适当的dict的targets
列表下的sources
属性中,就像添加任何其他源文件一样。
{
'targets': [
{
'target_name': 'foo',
'type': 'executable',
'sources': [
'independent.cc',
'specific_win.cc',
],
},
],
},