Gyp語法規則參考 & 工具的使用


by Markdown, 8/14/2014 10:17:28 AM


翻譯自 https://code.google.com/p/gyp/wiki/GypLanguageSpecification

目的和背景

Google使用過很多處理平台無關的項目構建系統,比如SconsCMake。在實際使用中這些並不能滿足需求。開發復雜的應用程序時,在Mac上Xcode更加適合,而Windows上Visual Studio更是無二之選。
gyp是為Chromium項目創建的項目生成工具,可以從平台無關的配置生成平台相關的Visual Studio、Xcode、Makefile的項目文件。這樣一來我們就不需要花額外的時間處理每個平台不同的項目配置以及項目之間的依賴關系。

概述

Gyp大致有如下的特點:

  • 配置文件都是以.gyp結尾
  • 每個.gyp文件都描述了如何去構建項目
  • 每個.gyp文件都能生成若干個合適特定平台的項目文件:
    • 在Mac上,.gyp文件會生成Xcode項目文件,包含了如何構建項目。一個.gyp文件會生成的一個.xcodeproj
    • 在Windows上,.gyp文件會生成Visual Studio項目文件。一個.gyp文件會生成一個.sln,並為每個targets生成一個.vcproj
    • 在Linux上,.gyp文件會生成Makefile文件
  • .gyp文件的語法是Python數據格式(Json格式)
  • .gypi文件可以被.gyp文件包含,方便統一設置
  • 配置中數據是鍵-值對的形式

詳細設計

設計准則:

  • 關鍵字一致性:所有的關鍵字都和平台項目的項目配置字段相同
  • 通過前綴表明配置屬於的特定平台。比如:msvs_disabled_warnings,xcode_framework_dirs

樣例

{
  'target_defaults': {
    'defines': [
      'U_STATIC_IMPLEMENTATION',
      ['LOGFILE', 'foo.log',],
    ],
    'include_dirs': [
      '..',
    ],
  },
  'targets': [
    {
      'target_name': 'foo',
      'type': 'static_library',
      'sources': [
        'foo/src/foo.cc',
        'foo/src/foo_main.cc',
      ],
      'include_dirs': [
         'foo',
         'foo/include',
      ],
      'conditions': [
         [ 'OS==mac', { 'sources': [ 'platform_test_mac.mm' ] } ]
      ],
      'direct_dependent_settings': {
        'defines': [
          'UNIT_TEST',
        ],
        'include_dirs': [
          'foo',
          'foo/include',
        ],
      },
    },
  ],
} 

結構元素

.gyp文件中定義了一些targets和構建規則。

下面的關鍵字可以定義在最頂層:

  • conditions: 條件定義。見條件(conditions)
  • includes: 包含.gypi文件的列表
    {
    'targets':[
    {
    'target_name': 'Thread',
    'type': 'executable',
    'includes': [
    '../common.gypi',
    './thread.gypi',
    ]
    ...
    }
    ],
    }
  • target_defaults: 默認的項目配置,每個項目(targets)的配置都需要從這個配置繼承
  • targets: 項目列表
    {
    'targets': [
    {
    'target_name': 'hello1',
    'product_extension': 'stuff',
    'type': 'executable',
    'sources': [
    'hello.c',
    ],
    },
    {
    'target_name': 'hello2',
    'target_extension': 'stuff',
    'type': 'executable',
    'sources': [
    'hello.c',
    ],
    }
    ]
    }
  • variables: 定義了鍵值對,可以被其他地方以<(varname)的方式引用
    {
    'variables': {
    'pi': 'import math; print math.pi',
    'third_letters': "<(other_letters)HIJK",
    'letters_list': 'ABCD',
    'other_letters': '<(letters_list)EFG',
    'check_included': '<(included_variable)',
    'check_lists': [
    '<(included_variable)',
    '<(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',
    },
    ...
    }

項目(targets)

.gyp文件定義的一套構建項目的規則。targets中也可以包含includesconditionsvariables。下面的是一些targets中的專有字段:

  • target_name: 指定定義的target的名稱
  • type: target的類型。支持executablestatic_libraryshared_librarynone。其中none類型也很有用,可以作為處理資源、文檔等特別項目的類型。例如,在Windows中,none將作為工具集類型的項目存在
  • product_extension: 指定target生成目標的擴展名,不包含'.'
  • product_name: 指定tareget生成目標的文件名,與product_extension組成一個文件全名
  • dependencies: 指定target依賴的其他target
    {
    'targets': [
    {
    'target_name': 'a',
    'type': 'static_library',
    'dependencies': [
    'b/b.gyp:b',
    'c/c.gyp:*'
    ],
    'sources': [
    'a.c',
    ],
    },
    ],
    }
  • defines: 定義了預處理宏。類似於C/C++命令行編譯中的-D或/D選項
    {
    'targets': [
    {
    'target_name': 'defines',
    'type': 'executable',
    'defines': [
    'FOO',
    'VALUE=1',
    'PAREN_VALUE=(1+2+3)',
    'HASH_VALUE="a#1"',
    ],
    'sources': [
    'defines.c',
    ],
    },
    ]
    }
  • include_dirs: 指定了包含文件的查找目錄。類似於C/C++命令行編譯中的-I或/I選項
    {
    'targets': [
    {
    'target_name': 'includes',
    'type': 'executable',
    'dependencies': [
    'subdir/subdir_includes.gyp:subdir_includes',
    ],
    'cflags': [
    '-Ishadow1',
    ],
    'include_dirs': [
    '.',
    'inc1',
    'shadow2',
    'subdir/inc2',
    ],
    'sources': [
    'includes.c',
    ],
    },
    ],
    }
  • sources: 列出了項目中的代碼文件和一些項目相關的文件。sources!段中可以指定被排除的文件
  • configurations: 為targets定義的一套構建配置。見配置(configurations)
  • link_settings: 指定target需要鏈接的庫。executableshared_library類型的target需要指定鏈接庫。這個段內可以指定target中可包含的除了configurationstarget_nametype的所有配置。可以與all_dependent_settingdirect_dependent_setting做對比
  • direct_dependent_settings: 指定依賴本target的target設置。這個段內可以指定target中可包含的除了configurationstarget_nametype的所有配置。可以與all_dependent_settinglink_settings做對比
  • all_dependent_settings:
  • libraries: 指定target依賴的庫,見link_settings>libraries
    ...
    'link_settings': {
    'libraries': [
    'libiconv.dylib',
    '<(ZLIB_DIR)contrib/minizip/libminizip.a',
    'libcurl.dylib',
    ],
    },
    ...
  • actions: 針對輸入的文件,定義了一組自定義的構建動作。見動作(actions)
  • copies: 定義了一套拷貝動作。見拷貝(copies)
  • rules: 見規則(rules)
  • target_conditions: 類似於conditions,但是起左右的時間比conditions晚
  • msvs_precompiled_header: 指定預編譯頭文件。只能用於Visual Studio
  • msvs_precompiled_source: 指定預編譯源文件。只能用於Visual Studio
  • msvs_prebuild: 生成之前事件。只能用於Visual Studio
  • msvs_postbuild: 生成之后事件。只能用於Visual Studio
    'msvs_postbuild':  r'copy "$(OutDir)$(TargetName)" "C:\$(TargetName)"
  • msvs_props: 指定target的屬性頁文件(.vsprops) 。只能用於Visual Studio
  • msvs_cygwin_shell: 指定action運行在cygwin下。只能用於Visual Studio
  • msvs_cygwin_dirs: 指定cygwin的目錄。只能用於Visual Studio
  • xcode_config_file: 在xcode中,指定target的配置文件(.xcconfig)。只能用於xcode
  • xcode_framework_dirs: 在xcode中,指定框架的目錄。只能用於xcode

配置(configurations)

configurations段可以在targetstarget_defaults段中。configurations不能夠重寫由target_defaults中指定的項。

在有些時候我們需要為項目指定多個配置,比如DebugRelease。 下面的一段為Windows中的常規配置


...
'configurations': {
    'Debug': {
      'msvs_settings': {
        'VCCLCompilerTool': {
          # 多線程調試 DLL (/MDd)
          'RuntimeLibrary': '3',
          # 不優化 /Od
          'Optimization': '0',
          # 用於“編輯並繼續”的程序數據庫 (/ZI)
          'DebugInformationFormat': '4',
        },
        'VCLinkerTool': {
          'GenerateDebugInformation': 'true',
          'GenerateMapFile': 'false',
          # 'SubSystem': '1',
        },
      },
    }, # Debug
    'Release': {
      'msvs_settings': {
        'VCCLCompilerTool': {
          # 多線程 DLL (/MD)
          'RuntimeLibrary': '2',
          # 完全優化 /Os
          'Optimization': '2',
          # 使用內部函數 /Oi
          'EnableIntrinsicFunctions': 'true',
          # 程序數據庫 (/Zi)
          'DebugInformationFormat': '3',
        },
        'VCLinkerTool': {
          'GenerateDebugInformation': 'true',
          'GenerateMapFile': 'false',
        },
      },
    }, # Release
},
...

條件(conditions)

conditionstarget_conditons可以出現在.gyp文件的任何位置。conditions語句在加載.gyp文件后即進行處理,target_conditions語句在處理完所有依賴項后在處理。
在加載完全局和局部的數據后,使用python的eval()函數對條件字符串做處理。

動作(actions)

actions提供了自定義處理輸入輸出的功能,其中的每一項都有下面的字段:

  • action_name: action的名稱,某些平台可能會忽略這個字段
  • inputs: 輸入信息,作為增量構建時使用
  • outputs: 輸出信息,作為增量構建時使用
  • action: 構建命令
  • message: 構建時顯示的信息

構建系統會比較inputsoutputs中的文件是否是修改過,只有在修改過的情況下才會運行action
在Xcode中,是通過shell腳本實現的;在Visual Studio中通過FileConfiguration包含一個自定義的VCCustomBuildTool實現。

'sources': [
  # libraries.cc is generated by the js2c action below.
  '<(INTERMEDIATE_DIR)/libraries.cc',
],
'actions': [
  {
    'variables': {
      'core_library_files': [
        'src/runtime.js',
        'src/v8natives.js',
        'src/macros.py',
      ],
    },
    'action_name': 'js2c',
    '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)'],
  },
],

規則(rules)

rules提供了自定義構建的功能,每一項都有下面的字段:

  • rule_name: rule的名稱,某些平台可能會忽略這個字段
  • extension: 在本target中,所有以此為擴展名的源文件在構建時都使用這個規則
  • inputs: 依賴的構建規則
  • outputs: 輸出信息,作為增量構建時使用。可以訪問下面的RULE_INPUT_*變量
  • action: 構建命令。可以訪問下面的RULE_INPUT_*變量
  • message: 構建時顯示的信息。可以訪問下面的RULE_INPUT_*變量

下面的這個變量可以在outputsactionmessage中訪問:

  • RULE_INPUT_PATH: 當前輸入的全路徑
  • RULE_INPUT_DIRNAME: 當前輸入的目錄
  • RULE_INPUT_NAME: 當前輸入的名稱
  • RULE_INPUT_ROOT: 當前輸入的去掉擴展名
  • RULE_INPUT_EXT: 當前輸入的擴展名
{
  'targets': [
    {
      'target_name': 'program',
      'type': 'executable',
      'msvs_cygwin_shell': 0,
      'sources': [
        'main.c',
        'prog1.in',
        'prog2.in',
      ],
      'rules': [
        {
          'rule_name': 'make_sources',
          'extension': 'in',
          'inputs': [
            'make-sources.py',
          ],
          'outputs': [
            '<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).c',
            '<(INTERMEDIATE_DIR)/<(RULE_INPUT_ROOT).h',
          ],
          'action': [
            'python', '<(_inputs)', '<(RULE_INPUT_NAME)', '<@(_outputs)',
          ],
          'process_outputs_as_sources': 1,
        },
      ],
    },
  ],
}

rulesactions有些相似之處。

拷貝(copies)

copies提供了簡單的文件拷貝功能,每一項都有下面的字段:

  • destination: 拷貝的目的地文件夾
  • files: 需要拷貝的文件列表

copies會在destination創建相同名稱的文件。

{
  'targets': [
    {
      'target_name': 'copies1',
      'type': 'none',
      'copies': [
        {
          'destination': 'copies-out',
          'files': [
            'file1',
          ],
        },
      ],
    },
    {
      'target_name': 'copies2',
      'type': 'none',
      'copies': [
        {
          'destination': '<(PRODUCT_DIR)/copies-out',
          'files': [
            'file2',
          ],
        },
      ],
    },
    # 拷貝目錄
    {
      'target_name': 'copies3',
      'type': 'none',
      'copies': [
        {
          'destination': '<(PRODUCT_DIR)/copies-out',
          'files': [
            'directory/',
          ],
        },
      ],
    },
  ],
}

代碼文件的命名

平台相關的文件命名規則為*_win.{ext}*_mac.{ext}*_linux.{ext}*_posix.{ext}。例如:

  • _win: foo_win.cpp
  • _mac: foo_mac.cpp,foo_mac.mm
  • _linux: foo_linux.cpp
  • _posix: foo_posix.cpp

gyp的源代碼

對於文檔中一些未列出和有爭議地方最可靠的是去看gyp的源代碼和例子。gyp的測試代碼很詳細,可以作為學習的例子做參考。

使用IDE調試生成的Makefile項目

在Linux上調試一般都是使用gdb,但是對於不態熟悉的就不好直接上手。這里推薦QtCreator,當然Netbeans和Eclispe CDT也可以,但是不如QtCreator方便和高效。

通用配置 common.gypi

 {
  'includes': [
    'env.gypi'  
  ],
  'include_dirs': [
    '.',
  ],
  'configurations': {
    'Debug': {
      'defines': [
        'DEBUG',
      ],
    },
    'Release': {
      'defines': [
        'NDEBUG',
      ],
    },
  }, # configurations
  'conditions': [
    ['OS=="win"', {
      'defines': [
        'WIN32',
        'UNICODE',
        '_UNICODE',
        'OS_WIN',
      ],
      'msbuild_configuration_attributes': {
        'IntermediateDirectory': '$(OutDir)__BuildTemp\\$(ProjectName)\\',
      },
      'msbuild_toolset': {
        #'PlatformToolset': 'v100'
      }, # msbuild_toolset
      'msvs_settings': {
        'VCCLCompilerTool': {
          'WarningLevel': '3',
          'DisableSpecificWarnings': ['4251','4996'],
          'WarnAsError': 'true',
        },
        'VCLinkerTool': {
          'AdditionalDependencies': [
            'kernel32.lib',
            'user32.lib',
          ],
          'AdditionalLibraryDirectories': [],
        },
      }, # msvs_settings
      'configurations': {
        'Debug': {
          'msvs_settings': {
            'VCCLCompilerTool': {
              # 多線程調試 DLL (/MDd)
              'RuntimeLibrary': '3',
              # 不優化 /Od
              'Optimization': '0',
              # 用於“編輯並繼續”的程序數據庫 (/ZI)
              'DebugInformationFormat': '4',
            },
            'VCLinkerTool': {
              'GenerateDebugInformation': 'true',
              'GenerateMapFile': 'false',
              # 'SubSystem': '1',
            },
          }, # msvs_settings
        }, # Debug
        'Release': {
          'msvs_settings': {
            'VCCLCompilerTool': {
              # 多線程 DLL (/MD)
              'RuntimeLibrary': '2',
              # 完全優化 /Os
              'Optimization': '2',
              # 使用內部函數 /Oi
              'EnableIntrinsicFunctions': 'true',
              # 程序數據庫 (/Zi)
              'DebugInformationFormat': '3',
            },
            'VCLinkerTool': {
              'GenerateDebugInformation': 'true',
              'GenerateMapFile': 'false',
            },
          }, # msvs_settings
        }, # Release
      }, # configurations
    }], # Windows
    ['OS=="mac"', {
      'make_global_settings': [
        ['CC', '/usr/bin/clang'],
        ['CXX', '/usr/bin/clang++'],
       ],
      
      'defines': [
        'OS_POSIX',
        'OS_MACOSX',
      ],
      'xcode_settings': {
        'ALWAYS_SEARCH_USER_PATHS': 'NO',
        #'i386', 'x86_64'
        'ARCHS': [ 'x86_64' ],
        'MACOSX_DEPLOYMENT_TARGET': '10.6',
        'CC': 'clang',
        'GCC_VERSION': 'com.apple.compilers.llvm.clang.1_0',
        'CLANG_CXX_LANGUAGE_STANDARD': 'c++0x',
        # libstdc++, c++11, libc++
        'CLANG_CXX_LIBRARY': 'libstdc++',
        'GCC_ENABLE_OBJC_GC': 'unsupported',
        #'LIBRARY_SEARCH_PATHS': [],
        'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
        'GCC_SYMBOLS_PRIVATE_EXTERN': 'NO',
        'DEBUG_INFORMATION_FORMAT': 'dwarf-with-dsym',
        #'DEPLOYMENT_POSTPROCESSING': 'YES',
        'OTHER_CFLAGS': [
          '-fno-eliminate-unused-debug-symbols',
          '-mmacosx-version-min=10.6',
          # compile use oc++
          '-x objective-c++',
        ],
        'WARNING_CFLAGS': ['-Wno-deprecated-declarations'],
        'WARNING_CFLAGS!': ['-Wall', '-Wextra',],
        'WARNING_CXXFLAGS': ['-Wstrict-aliasing', '-Wno-deprecated',],
      }, # xcode_settings
      'link_settings': {
        'libraries': [
          '$(SDKROOT)/System/Library/Frameworks/Foundation.framework',
        ],
      },
      'libraries': [],
      'mac_framework_dirs': [],
      'configurations': {
        'Debug': {
          'xcode_settings': {
            'GCC_DEBUGGING_SYMBOLS': 'full',
            'STRIP_INSTALLED_PRODUCT': 'YES',
            'GCC_OPTIMIZATION_LEVEL': '0',
            'OTHER_CFLAGS': ['-g',],
            'OTHER_CXXFLAGS': ['-g',],
          }, # xcode_settings
        }, # Debug
        'Release': {
          'xcode_settings': {
            'GCC_OPTIMIZATION_LEVEL': 's',
          }, # xcode_settings
        }, # Release
      }, # configurations
    }], # Mac
    ['OS=="linux"', {
      'defines': [
        'OS_POSIX',
        'OS_LINUX',
      ],
      'cflags': [
        # Support 64-bit shared libs (also works fine for 32-bit).
        '-fPIC',
        '-std=c++11',
        '-fstrict-aliasing',
        '-Wall',
        '-Wextra',
        '-Wshadow',
        '-Wconversion',
        #'-Wpadded',
        '-Wstrict-aliasing=2',
        '-Wstrict-overflow=4',
      ],
      'ldflags': [],
      'configurations': {
        'Debug': {
          'cflags': [
            '-g',
            '-C',
          ],
        },
        'Release': {
          'cflags': [
            '-O2',
          ],
        },
      }, # configurations
    }], # Linux
  ], # conditions
}

gyp命令行

  • --depth: Chromium歷史遺留問題,需要設置為.
  • --generator-out: 設置生成項目的輸出文件夾
  • --f: 設置生成項目的類型,不設置則根據平台決定生成的項目類型。可用的值有:msvsxcodemake
  • --G: 設置生成的其他標記參數,這個值和具體的平台有關。
    • msvs_version: 指定生成的Visual Studio項目的版本,不設置則會根據系統中安裝的最新的Visual Stuio生成項目。可用的值有20052005e20082008e20102010e20122012e20132013e。例如: --Gmsvs_version=2010
  • --toplevel-dir: 設置源代碼的跟目錄,默認將取--depth指定的值
  • -D: 傳入變量到.gyp,可以使用<(varname)這種方式讀取。例如:-Dbuildtype=share_library
  • --no-circular-check:

寫API文檔是一件很蛋疼的事情,以后繼續添加。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM