【C/C++基础进阶系列】实战记录 -- C++ 应用程序项目结构搭建 (GYP)
【1】GYP 中的关键字概述
- conditions : 条件定义
- includes : 包含.gypi文件的列表
- target_defaults : 默认的项目配置,每个项目(targets)的配置都需要从这个配置继承
- targets : 项目列表
- variables : 定义了键值对,可以被其他地方以<(varname)的方式引用
- targets : 项目列表
- target_name : 指定定义的target的名称
- type : target的类型
- 支持executable、static_library、shared_library和 none
- 其中none类型也很有用,可以作为处理资源、文档等特别项目的类型
- product_extension : 指定target生成目标的扩展名,不包含'.'
- product_name : 指定tareget生成目标的文件名,与product_extension组成一个文件全名
- dependencies : 指定target依赖的其他target
- defines: 定义了预处理宏。类似于C/C++命令行编译中的-D或/D选项
- include_dirs: 指定了包含文件的查找目录。类似于C/C++命令行编译中的-I或/I选项
- sources: 列出了项目中的代码文件和一些项目相关的文件,sources!段中可以指定被排除的文件
- configurations: 为targets定义的一套构建配置
- 可以在targets和target_defaults段中,configurations不能够重写由target_defaults中指定的项
- link_settings: 指定target需要链接的库,executable和shared_library类型的target需要指定链接库
- direct_dependent_settings: 指定依赖本target的target设置
- libraries: 指定target依赖的库
- actions: 针对输入的文件,定义了一组自定义的构建动作
- action_name: action的名称,某些平台可能会忽略这个字段
- inputs: 输入信息,作为增量构建时使用
- outputs: 输出信息,作为增量构建时使用
- action: 构建命令
- message: 构建时显示的信息
- copies: 定义了一套拷贝动作
- destination: 拷贝的目的地文件夹
- files: 需要拷贝的文件列表
- conditions: 条件判断
- target_conditions: 条件判断
【2】GYP 配置文件示例
{
'variables': { # 定义了键值对
# 可以被其他地方以<(varname)的方式引用
'pi': 'import math; print math.pi',
'third_letters': "<(other_letters)HIJK",
'letters_list': 'ABCD',
'other_letters': '<(letters_list)EFG',
'check_lists': [
'<(third_letters)',
],
'check_int': 5,
'check_str_int': '6',
'check_list_int': [
7,
'8',
9,
],
'not_int_1': ' 10',
'not_int_2': '11 ',
'not_int_3': '012',
'not_int_4': '13.0',
'not_int_5': '+14',
'negative_int': '-15',
'zero_int': '0',
},
'target_defaults': { # 默认的项目配置
# 每个项目(targets)的配置都需要从这个配置继承
'defines': [
'U_STATIC_IMPLEMENTATION',
['LOGFILE', 'foo.log',],
],
'include_dirs': [ # 指定了包含文件的查找目录,类似于C/C++命令行编译中的-I或/I选项
'..',
],
'target_conditions': # 在处理完所有依赖项后在处理
# 可以出现在.gyp文件的任何位置
[
# Ensure target and host have different shared_library names
['_toolset=="host"', {'product_extension': 'host'}],
],
'conditions': # 条件定义
# 在加载.gyp文件后即进行处理
# 可以出现在.gyp文件的任何位置
[
[ 'target_arch == "ia32"', { # CPU 架构为 ia32
'cflags': [ '-m32' ], # gcc 编译选项
'ldflags': [ '-m32' ] # gcc 链接选项
}],
[ 'target_arch == "x64"', { # CPU 架构为 x64
'cflags': [ '-m64' ], # gcc 编译选项
'ldflags': [ '-m64' ] # gcc 链接选项
}]
]
'configurations': # 为 targets 定义的一套构建配置
# 此处指定了 Release / Debug 配置下的预处理宏、编译选项
# 可以在targets和target_defaults段中
# configurations不能够重写由target_defaults中指定的项
{
'Release':
{
# gcc 编译选项
'cflags': [ '-O3', '-Wno-unknown-warning-option', '-fPIC' ]
},
'Debug':
{
# 定义了预处理宏,类似于C/C++命令行编译中的-D或/D选项
'defines': [ 'DEBUG', 'MS_LOG_TRACE', 'MS_LOG_FILE_LINE' ],
# gcc 编译选项
'cflags': [ '-g', '-O0', '-Wno-parentheses-equality', '-Wno-unknown-warning-option', '-fPIC' ],
}
},
},
'targets': [ # 项目列表
{
'target_name': 'hello1', # 指定定义的target的名称
'product_extension': '_bin', # 指定target生成目标的扩展名,不包含'.'
'product_name': 'hellow_1_', # 指定tareget生成目标的文件名,与product_extension组成一个文件全名
'type': 'executable', # target的类型
# 支持 executable(可执行)、static_library(静态库)、
# shared_library(动态库) 和 none(一般文件)
'dependencies': [ # 指定target依赖的其他target
# 依赖项成员可以多个,其依赖的只能是当前 gyp 或其他 gyp 文件中的 target
'b/b.gyp:b',
'c/c.gyp:*'
],
'defines': [ # 定义了预处理宏,类似于C/C++命令行编译中的-D或/D选项
'FOO',
'VALUE=1',
'PAREN_VALUE=(1+2+3)',
'HASH_VALUE="a#1"',
],
'include_dirs': [ # 指定了包含文件的查找目录,类似于C/C++命令行编译中的-I或/I选项
'.',
'inc1',
'subdir/inc2',
],
'sources': [ # 列出了项目中的源文件
# sources!段中可以指定被排除的文件
'hello.h'
'hello.c',
],
'link_settings': { # 指定target需要链接的库
# executable和shared_library类型的target需要指定链接库
'libraries': [ # 指定target依赖的库
'libiconv.dylib',
'subdir/libminizip.a',
],
'ldflags': [ '-pthread' ], # gcc 链接选项
},
'direct_dependent_settings': { # 指定依赖本target的target设置
'defines': [ # 定义了预处理宏,类似于C/C++命令行编译中的-D或/D选项
'UNIT_TEST',
],
'include_dirs': [ # 指定了包含文件的查找目录,类似于C/C++命令行编译中的-I或/I选项
'foo',
'foo/include',
],
},
'actions': [ # 提供了自定义处理输入输出的功能
# 构建系统会比较inputs和outputs中的文件是否是修改过,
# 只有在修改过的情况下才会运行action
{
'variables': { # 定义了键值对
# 可以被其他地方以<(varname)的方式引用
'core_library_files': [
'src/runtime.js',
'src/v8natives.js',
'src/macros.py',
],
},
'action_name': 'js2c', # action的名称,某些平台可能会忽略这个字段
'inputs': [ # 输入信息,作为增量构建时使用
'tools/js2c.py',
'<@(core_library_files)',
],
'outputs': [ # 输出信息,作为增量构建时使用
'<(INTERMEDIATE_DIR)/libraries.cc',
'<(INTERMEDIATE_DIR)/libraries-empty.cc',
],
'action': ['python', 'tools/js2c.py', '<@(_outputs)', 'CORE', '<@(core_library_files)'], # 构建命令
},
],
},
{
'target_name': 'copies1', # 指定定义的target的名称
'type': 'none', # target的类型
# 支持 executable(可执行)、static_library(静态库)、
# shared_library(动态库) 和 none(一般文件)
'includes': [ # includes: 包含.gypi文件的列表
'../common.gypi',
'./thread.gypi',
],
'copies': [ # 定义了一套拷贝动作
# copies会在destination创建相同名称的文件
{
'destination': 'copies-out', # 拷贝的目的地文件夹
'files': [ # 需要拷贝的文件列表
'file1',
],
},
],
},
# 拷贝目录
{
'target_name': 'copies3', # 指定定义的target的名称
'type': 'none', # target的类型
# 支持 executable(可执行)、static_library(静态库)、
# shared_library(动态库) 和 none(一般文件)
'copies': [ # 定义了一套拷贝动作
# copies会在destination创建相同名称的文件
{
'destination': '<(PRODUCT_DIR)/copies-out', # 拷贝的目的地文件夹
'files': [ # 需要拷贝的文件列表
'directory/',
],
},
],
},
{
'target_name': 'program', # 指定定义的target的名称
'type': 'executable', # target的类型
'sources': [ # 列出了项目中的源文件
# sources!段中可以指定被排除的文件
'main.c',
'prog1.in',
'prog2.in',
],
'rules': [ # 提供了自定义构建的功能
# 如下变量可在outputs、action和message中访问
# RULE_INPUT_PATH: 当前输入的全路径
# RULE_INPUT_DIRNAME: 当前输入的目录
# RULE_INPUT_NAME: 当前输入的名称
# RULE_INPUT_ROOT: 当前输入的去掉扩展名
# RULE_INPUT_EXT: 当前输入的扩展名
{
'rule_name': 'make_sources', # rule的名称,某些平台可能会忽略这个字段
'extension': 'in', # 在本target中,所有以此为扩展名的源文件在构建时都使用这个规则
'inputs': [ # 依赖的构建规则
'make-sources.py',
],
'outputs': [ # 输出信息,作为增量构建时使用
'<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).c',
'<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).h',
],
'action': [ # 构建命令
'python', '<(_inputs)', '<(RULE_INPUT_NAME)', '<@(_outputs)',
],
},
],
},
],
}
参考与致谢
本博客为博主的学习实践总结,并参考了众多博主的博文,在此表示感谢,博主若有不足之处,请批评指正。
【2】GYP使用总结 ---- 从Makefile到GYP
【3】Gyp语法规则参考 & 工具的使用