Esempio n. 1
0
def RunTestsOnNaCl(targets, build_args):
  """Run a test suite for the NaCl version."""
  # Currently we can only run the limited test set which is defined as
  # nacl_test_targets in nacl_extension.gyp.
  if targets:
    PrintErrorAndExit('Targets [%s] are not supported.' % ', '.join(targets))
  nacl_gyp = os.path.join(SRC_DIR, 'chrome', 'nacl', 'nacl_extension.gyp')
  (build_options, build_targets) = ParseBuildOptions(
      build_args + [nacl_gyp + ':run_nacl_test'])
  # Run the test suite in NaCl.
  BuildMain(build_options, build_targets)
Esempio n. 2
0
def BuildMain(options, targets):
  """The main function for the 'build' command."""
  if not targets:
    PrintErrorAndExit('No build target is specified.')

  # Add the mozc root directory to PYTHONPATH.
  original_python_path = os.environ.get('PYTHONPATH', '')
  depot_path = MOZC_ROOT
  python_path = os.pathsep.join([original_python_path, depot_path])
  os.environ['PYTHONPATH'] = python_path

  if IsWindows():
    BuildOnWindows(targets)
  else:
    BuildWithNinja(options, targets)

  # Revert python path.
  os.environ['PYTHONPATH'] = original_python_path
Esempio n. 3
0
def GypMain(options, unused_args):
  """The main function for the 'gyp' command."""
  # Generate a version definition file.
  logging.info('Generating version definition file...')
  template_path = '%s/%s' % (SRC_DIR, options.version_file)
  version_path = '%s/mozc_version.txt' % SRC_DIR
  if options.noqt:
    qt_version = ''
  else:
    qt_version = '5'
  GenerateVersionFile(template_path, version_path, options.target_platform,
                      qt_version)
  version = GetMozcVersion()
  target_platform = version.GetTargetPlatform()
  logging.info('Version string is %s', version.GetVersionString())

  # Back up the original 'PYTHONPATH' environment variable in case we change
  # it in this function.
  original_python_path = os.environ.get('PYTHONPATH', '')

  # 'gypdir' option allows distributors/packages to specify the location of
  # the system-installed version of gyp to conform their packaging policy.
  if options.gypdir:
    # When distributors/packages choose to use system-installed gyp, it is
    # their responsibility to make sure if 'gyp' command works well on
    # their environment.
    gyp_dir = os.path.abspath(options.gypdir)
    gyp_command = [os.path.join(gyp_dir, 'gyp')]
  else:
    # Use third_party/gyp/gyp unless 'gypdir' option is specified. This is
    # the default and official way to build Mozc. In this case, you need to
    # consider the case where a Python package named 'gyp' has already been
    # installed in the target machine. So we update PYTHONPATH so that
    # third_party/gyp/gyp_main.py can find its own library modules (they are
    # installed under 'third_party/gyp/pylib') rather than system-installed
    # GYP modules.
    gyp_dir = os.path.abspath(os.path.join(MOZC_ROOT, 'third_party', 'gyp'))
    gyp_main_file = os.path.join(gyp_dir, 'gyp_main.py')
    # Make sure |gyp_main_file| exists.
    if not os.path.exists(gyp_main_file):
      message = (
          'GYP does not exist at %s. Please run "git submodule update --init" '
          'to check out GYP. If you want to use system-installed GYP, use '
          '--gypdir option to specify its location. e.g. '
          '"python build_mozc.py gyp --gypdir=/usr/bin"' % gyp_main_file)
      PrintErrorAndExit(message)
    gyp_python_path = options.gyp_python_path or sys.executable
    gyp_command = [gyp_python_path, gyp_main_file]
    os.environ['PYTHONPATH'] = os.pathsep.join(
        [os.path.join(gyp_dir, 'pylib'), original_python_path])

    # Following script tests if 'import gyp' is now available and its
    # location is expected one. By using this script, make sure
    # 'import gyp' actually loads 'third_party/gyp/pylib/gyp'.
    gyp_check_script = os.path.join(
        ABS_SCRIPT_DIR, 'build_tools', 'ensure_gyp_module_path.py')
    expected_gyp_module_path = os.path.join(gyp_dir, 'pylib', 'gyp')
    RunOrDie([gyp_python_path, gyp_check_script,
              '--expected=%s' % expected_gyp_module_path])

  # Set the generator name.
  os.environ['GYP_GENERATORS'] = 'ninja'

  # Get and show the list of .gyp file names.
  gyp_file_names = GetGypFileNames(options)
  logging.debug('GYP files:')
  for file_name in gyp_file_names:
    logging.debug('- %s', file_name)

  # Build GYP command line.
  logging.info('Building GYP command line...')
  gyp_options = ['--depth=.']
  if target_platform == 'Windows':
    gyp_options.extend(['--include=%s/gyp/common_win.gypi' % SRC_DIR])
  else:
    gyp_options.extend(['--include=%s/gyp/common.gypi' % SRC_DIR])

  gyp_options.extend(['-D', 'abs_depth=%s' % MOZC_ROOT])
  gyp_options.extend(['-D', 'ext_third_party_dir=%s' % EXT_THIRD_PARTY_DIR])

  if IsWindows():
    gyp_options.extend(['-D', 'python="%s"' % sys.executable])
  else:
    gyp_options.extend(['-D', 'python=%s' % sys.executable])

  gyp_options.extend(gyp_file_names)

  gyp_options.extend(['-D', 'version=' + version.GetVersionString()])
  gyp_options.extend(['-D', 'short_version=' + version.GetShortVersionString()])

  if options.branding:
    gyp_options.extend(['-D', 'branding=%s' % options.branding])

  # Qt configurations
  if options.noqt:
    gyp_options.extend(['-D', 'use_qt=NO'])
    gyp_options.extend(['-D', 'qt_dir='])
  elif target_platform == 'Linux':
    gyp_options.extend(['-D', 'use_qt=YES'])
    gyp_options.extend(['-D', 'qt_dir='])

    # Check if Qt libraries are installed.
    if not PkgExists('Qt5Core', 'Qt5Gui', 'Qt5Widgets'):
      PrintErrorAndExit('Qt is required to build GUI Tool. '
                        'Specify --noqt to skip building GUI Tool.')

  else:
    gyp_options.extend(['-D', 'use_qt=YES'])
    if options.qtdir:
      gyp_options.extend(['-D', 'qt_dir=%s' % os.path.abspath(options.qtdir)])
    else:
      gyp_options.extend(['-D', 'qt_dir='])

  if target_platform == 'Windows' and options.wix_dir:
    gyp_options.extend(['-D', 'use_wix=YES'])
    gyp_options.extend(['-D', 'wix_dir=%s' % options.wix_dir])
  else:
    gyp_options.extend(['-D', 'use_wix=NO'])

  gyp_options.extend(['-D', 'build_base=%s' %
                      GetBuildBaseName(target_platform)])
  gyp_options.extend(['-D', 'build_short_base=%s' %
                      GetBuildShortBaseName(target_platform)])

  if options.warn_as_error:
    gyp_options.extend(['-D', 'warn_as_error=1'])
  else:
    gyp_options.extend(['-D', 'warn_as_error=0'])

  if version.IsDevChannel():
    gyp_options.extend(['-D', 'channel_dev=1'])

  target_platform_value = target_platform
  gyp_options.extend(['-D', 'target_platform=%s' % target_platform_value])

  if IsWindows():
    gyp_options.extend(['-G', 'msvs_version=2017'])

  if (target_platform == 'Linux' and
      '%s/unix/ibus/ibus.gyp' % SRC_DIR in gyp_file_names):
    gyp_options.extend(['-D', 'use_libibus=1'])

  if options.server_dir:
    gyp_options.extend([
        '-D', 'server_dir=%s' % os.path.abspath(options.server_dir)])

  gyp_options.extend(['--generator-output=.'])
  short_basename = GetBuildShortBaseName(target_platform)
  gyp_options.extend(['-G', 'output_dir=%s' % short_basename])

  # Enable cross-compile
  # TODO(yukawa): Enable GYP_CROSSCOMPILE for Windows.
  if not IsWindows():
    os.environ['GYP_CROSSCOMPILE'] = '1'

  # Run GYP.
  logging.info('Running GYP...')
  RunOrDie(gyp_command + gyp_options)

  # Restore PYTHONPATH just in case.
  if not original_python_path:
    os.environ['PYTHONPATH'] = original_python_path

  # Done!
  logging.info('Done')

  # For internal Ninja build on Windows, set up environment files
  if IsWindows():
    out_dir = os.path.join(MOZC_ROOT, 'out_win')
    AddPythonPathToEnvironmentFilesForWindows(out_dir)

    # When Windows build is configured to use DLL version of Qt, copy Qt's DLLs
    # and debug symbols into Mozc's build directory. This is important because:
    # - We can easily back up all the artifacts if relevant product binaries and
    #   debug symbols are placed at the same place.
    # - Some post-build tools such as bind.exe can easily look up the dependent
    #   DLLs (QtCore4.dll and QtQui4.dll in this case).
    # Perhaps the following code can also be implemented in gyp, but we atopt
    # this ad hock workaround as a first step.
    # TODO(yukawa): Implement the following logic in gyp, if magically possible.
    abs_qtdir = os.path.abspath(options.qtdir)
    abs_qt_bin_dir = os.path.join(abs_qtdir, 'bin')
    abs_qt_lib_dir = os.path.join(abs_qtdir, 'lib')
    abs_out_win_dir = GetBuildBaseName(target_platform)
    copy_script = os.path.join(
        ABS_SCRIPT_DIR, 'build_tools', 'copy_dll_and_symbol.py')
    copy_params = []
    if qt_version == '5':
      copy_params.append({
          'basenames': 'Qt5Cored;Qt5Guid;Qt5Widgetsd',
          'dll_paths': abs_qt_bin_dir,
          'pdb_paths': abs_qt_lib_dir,
          'target_dir': os.path.join(abs_out_win_dir, 'DebugDynamic')})
      copy_params.append({
          'basenames': 'Qt5Core;Qt5Gui;Qt5Widgets',
          'dll_paths': abs_qt_bin_dir,
          'pdb_paths': abs_qt_lib_dir,
          'target_dir': os.path.join(abs_out_win_dir, 'ReleaseDynamic')})
      copy_params.append({
          'basenames': 'qwindowsd',
          'dll_paths': os.path.join(abs_qtdir, 'plugins', 'platforms'),
          'pdb_paths': os.path.join(abs_qtdir, 'plugins', 'platforms'),
          'target_dir': os.path.join(abs_out_win_dir, 'DebugDynamic',
                                     'platforms')})
      copy_params.append({
          'basenames': 'qwindows',
          'dll_paths': os.path.join(abs_qtdir, 'plugins', 'platforms'),
          'pdb_paths': os.path.join(abs_qtdir, 'plugins', 'platforms'),
          'target_dir': os.path.join(abs_out_win_dir, 'ReleaseDynamic',
                                     'platforms')})
    for copy_param in copy_params:
      copy_commands = [
          copy_script,
          '--basenames', copy_param['basenames'],
          '--dll_paths', copy_param['dll_paths'],
          '--pdb_paths', copy_param['pdb_paths'],
          '--target_dir', copy_param['target_dir'],
      ]
      RunOrDie(copy_commands)
Esempio n. 4
0
def GetNinjaTargetName(target):
  """Extracts the build target name for Ninja."""
  if ':' not in target:
    PrintErrorAndExit('Invalid target: %s' % target)
  (_, target_name) = target.split(':')
  return target_name
Esempio n. 5
0
def GypMain(options, unused_args):
  """The main function for the 'gyp' command."""
  # Generate a version definition file.
  logging.info('Generating version definition file...')
  template_path = '%s/%s' % (SRC_DIR, options.version_file)
  version_path = '%s/mozc_version.txt' % SRC_DIR
  if options.noqt or options.target_platform in ['Android', 'NaCl']:
    qt_version = ''
  else:
    qt_version = '5'
  GenerateVersionFile(template_path, version_path, options.target_platform,
                      options.android_application_id,
                      options.android_arch, qt_version)
  version = GetMozcVersion()
  target_platform = version.GetTargetPlatform()
  logging.info('Version string is %s', version.GetVersionString())

  # Back up the original 'PYTHONPATH' environment variable in case we change
  # it in this function.
  original_python_path = os.environ.get('PYTHONPATH', '')

  # 'gypdir' option allows distributors/packages to specify the location of
  # the system-installed version of gyp to conform their packaging policy.
  if options.gypdir:
    # When distributors/packages choose to use system-installed gyp, it is
    # their responsibility to make sure if 'gyp' command works well on
    # their environment.
    gyp_dir = os.path.abspath(options.gypdir)
    gyp_command = [os.path.join(gyp_dir, 'gyp')]
  else:
    # Use third_party/gyp/gyp unless 'gypdir' option is specified. This is
    # the default and official way to build Mozc. In this case, you need to
    # consider the case where a Python package named 'gyp' has already been
    # installed in the target machine. So we update PYTHONPATH so that
    # third_party/gyp/gyp_main.py can find its own library modules (they are
    # installed under 'third_party/gyp/pylib') rather than system-installed
    # GYP modules.
    gyp_dir = os.path.abspath(os.path.join(MOZC_ROOT, 'third_party', 'gyp'))
    gyp_main_file = os.path.join(gyp_dir, 'gyp_main.py')
    # Make sure |gyp_main_file| exists.
    if not os.path.exists(gyp_main_file):
      message = (
          'GYP does not exist at %s. Please run "git submodule update --init" '
          'to check out GYP. If you want to use system-installed GYP, use '
          '--gypdir option to specify its location. e.g. '
          '"python build_mozc.py gyp --gypdir=/usr/bin"' % gyp_main_file)
      PrintErrorAndExit(message)
    gyp_command = [sys.executable, gyp_main_file]
    os.environ['PYTHONPATH'] = os.pathsep.join(
        [os.path.join(gyp_dir, 'pylib'), original_python_path])
    # Following script tests if 'import gyp' is now available and its
    # location is expected one. By using this script, make sure
    # 'import gyp' actually loads 'third_party/gyp/pylib/gyp'.
    gyp_check_script = os.path.join(
        ABS_SCRIPT_DIR, 'build_tools', 'ensure_gyp_module_path.py')
    expected_gyp_module_path = os.path.join(gyp_dir, 'pylib', 'gyp')
    RunOrDie([sys.executable, gyp_check_script,
              '--expected=%s' % expected_gyp_module_path])

  # Set the generator name.
  os.environ['GYP_GENERATORS'] = 'ninja'

  # Get and show the list of .gyp file names.
  gyp_file_names = GetGypFileNames(options)
  logging.debug('GYP files:')
  for file_name in gyp_file_names:
    logging.debug('- %s', file_name)

  # Build GYP command line.
  logging.info('Building GYP command line...')
  gyp_options = ['--depth=.']
  if target_platform == 'Windows':
    gyp_options.extend(['--include=%s/gyp/common_win.gypi' % SRC_DIR])
  else:
    gyp_options.extend(['--include=%s/gyp/common.gypi' % SRC_DIR])

  gyp_options.extend(['-D', 'abs_depth=%s' % MOZC_ROOT])
  gyp_options.extend(['-D', 'ext_third_party_dir=%s' % EXT_THIRD_PARTY_DIR])

  gyp_options.extend(['-D', 'python_executable=%s' % sys.executable])

  gyp_options.extend(gyp_file_names)

  if options.branding:
    gyp_options.extend(['-D', 'branding=%s' % options.branding])

  # Qt configurations
  if options.noqt or target_platform in ['Android', 'NaCl']:
    gyp_options.extend(['-D', 'use_qt=NO'])
    gyp_options.extend(['-D', 'qt_dir='])
  elif target_platform == 'Linux':
    gyp_options.extend(['-D', 'use_qt=YES'])
    gyp_options.extend(['-D', 'qt_dir='])

    # Check if Qt libraries are installed.
    if not PkgExists('Qt5Core', 'Qt5Gui', 'Qt5Widgets'):
      PrintErrorAndExit('Qt is required to build GUI Tool. '
                        'Specify --noqt to skip building GUI Tool.')

  else:
    gyp_options.extend(['-D', 'use_qt=YES'])
    if options.qtdir:
      gyp_options.extend(['-D', 'qt_dir=%s' % os.path.abspath(options.qtdir)])
    else:
      gyp_options.extend(['-D', 'qt_dir='])

  if target_platform == 'Windows' and options.wix_dir:
    gyp_options.extend(['-D', 'use_wix=YES'])
    gyp_options.extend(['-D', 'wix_dir=%s' % options.wix_dir])
  else:
    gyp_options.extend(['-D', 'use_wix=NO'])

  if target_platform == 'Linux':
    gyp_options.extend(['-D', 'enable_gtk_renderer=1'])

  # Android
  if target_platform == 'Android':
    android_home = GetAndroidHome(options)
    android_ndk_home = GetAndroidNdkHome(options)
    if not android_home or not os.path.isdir(android_home):
      raise ValueError(
          'Android Home was not found. '
          'Use --android_home option or make the home direcotry '
          'be included in PATH environment variable.')
    if not android_ndk_home or not os.path.isdir(android_ndk_home):
      raise ValueError(
          'Android NDK Home was not found. '
          'Use --android_ndk_home option or make the home direcotry '
          'be included in PATH environment variable.')

    gyp_options.extend(['-D', 'android_home=%s' % android_home])
    gyp_options.extend(['-D', 'android_arch=%s' % options.android_arch])
    gyp_options.extend(['-D', 'android_ndk_home=%s' % android_ndk_home])
    gyp_options.extend(['-D', 'android_application_id=%s' %
                        options.android_application_id])
    if options.android_hide_icon:
      gyp_options.extend(['-D', 'android_hide_icon=1'])
    else:
      gyp_options.extend(['-D', 'android_hide_icon=0'])
    if options.android_release_icon:
      gyp_options.extend(['-D', 'android_release_icon=1'])
    else:
      gyp_options.extend(['-D', 'android_release_icon=0'])

  gyp_options.extend(['-D', 'build_base=%s' %
                      GetBuildBaseName(target_platform)])
  gyp_options.extend(['-D', 'build_short_base=%s' %
                      GetBuildShortBaseName(target_platform)])

  if options.warn_as_error:
    gyp_options.extend(['-D', 'warn_as_error=1'])
  else:
    gyp_options.extend(['-D', 'warn_as_error=0'])

  if version.IsDevChannel():
    gyp_options.extend(['-D', 'channel_dev=1'])

  def SetCommandLineForFeature(option_name, windows=False, mac=False,
                               linux=False, android=False, nacl=False):
    """Updates an option like '--enable_foober' and add a -D argument for gyp.

    This function ensures an option like '--enable_foober' exists and it has a
    default boolean for each platform based on givem parameters. This
    function also sets a '-D' command line option for gyp as
    '-D enable_foober=0' or '-D enable_foober=1' depending on the actual value
    of the target option.

    Args:
      option_name: A base name of the option. If 'foobar' is given,
          '--enable_foober' option will be checked.
      windows: A boolean which replesents the default value of the target
          option on Windows platform.
      mac: A boolean which replesents the default value of the target option
          on MacOS X platform.
      linux: A boolean which replesents the default value of the target option
          on Linux platform.
      android: A boolean which replesents the default value of the target
          option on Android platform.
      nacl: A boolean which replesents the default value of the target
          option on NaCl.

    Raises:
      ValueError: An error occurred when 'option_name' is empty.
    """
    if not option_name:
      raise ValueError('"option_name" should be specified')

    default_enabled = {'Windows': windows,
                       'Mac': mac,
                       'Linux': linux,
                       'Android': android,
                       'NaCl': nacl}.get(target_platform, False)
    enable_option_name = 'enable_%s' % option_name
    enabled = options.ensure_value(enable_option_name, default_enabled)
    gyp_options.extend(['-D',
                        '%s=%s' % (enable_option_name, 1 if enabled else 0)])

  is_official = (options.branding == 'GoogleJapaneseInput')
  is_official_dev = (is_official and version.IsDevChannel())

  SetCommandLineForFeature(option_name='cloud_handwriting',
                           linux=is_official_dev,
                           windows=is_official_dev,
                           mac=is_official_dev)

  target_platform_value = target_platform
  gyp_options.extend(['-D', 'target_platform=%s' % target_platform_value])

  if IsWindows():
    gyp_options.extend(['-G', 'msvs_version=2015'])

  if (target_platform == 'Linux' and
      '%s/unix/ibus/ibus.gyp' % SRC_DIR in gyp_file_names):
    gyp_options.extend(['-D', 'use_libibus=1'])

  if target_platform == 'NaCl':
    if options.nacl_sdk_root:
      nacl_sdk_root = os.path.abspath(options.nacl_sdk_root)
    else:
      nacl_sdk_root = os.path.abspath(os.path.join(EXT_THIRD_PARTY_DIR,
                                                   'nacl_sdk', 'pepper_40'))
    if not os.path.isdir(nacl_sdk_root):
      PrintErrorAndExit('The nacl_sdk_root directory (%s) does not exist.'
                        % options.nacl_sdk_root)
    gyp_options.extend(['-D', 'nacl_sdk_root=%s' % nacl_sdk_root])

  if options.server_dir:
    gyp_options.extend([
        '-D', 'server_dir=%s' % os.path.abspath(options.server_dir)])

  gyp_options.extend(['--generator-output=.'])
  short_basename = GetBuildShortBaseName(target_platform)
  gyp_options.extend(['-G', 'output_dir=%s' % short_basename])

  # Enable cross-compile
  # TODO(yukawa): Enable GYP_CROSSCOMPILE for Windows.
  if not IsWindows():
    os.environ['GYP_CROSSCOMPILE'] = '1'

  # Run GYP.
  logging.info('Running GYP...')
  RunOrDie(gyp_command + gyp_options)

  # Restore PYTHONPATH just in case.
  if not original_python_path:
    os.environ['PYTHONPATH'] = original_python_path

  # Done!
  logging.info('Done')

  # For internal Ninja build on Windows, set up environment files
  if IsWindows():
    out_dir = os.path.join(MOZC_ROOT, 'out_win')
    AddPythonPathToEnvironmentFilesForWindows(out_dir)

    # When Windows build is configured to use DLL version of Qt, copy Qt's DLLs
    # and debug symbols into Mozc's build directory. This is important because:
    # - We can easily back up all the artifacts if relevant product binaries and
    #   debug symbols are placed at the same place.
    # - Some post-build tools such as bind.exe can easily look up the dependent
    #   DLLs (QtCore4.dll and QtQui4.dll in this case).
    # Perhaps the following code can also be implemented in gyp, but we atopt
    # this ad hock workaround as a first step.
    # TODO(yukawa): Implement the following logic in gyp, if magically possible.
    abs_qtdir = os.path.abspath(options.qtdir)
    abs_qt_bin_dir = os.path.join(abs_qtdir, 'bin')
    abs_qt_lib_dir = os.path.join(abs_qtdir, 'lib')
    abs_out_win_dir = GetBuildBaseName(target_platform)
    copy_script = os.path.join(
        ABS_SCRIPT_DIR, 'build_tools', 'copy_dll_and_symbol.py')
    copy_params = []
    if qt_version == '5':
      copy_params.append({
          'basenames': 'Qt5Cored;Qt5Guid;Qt5Widgetsd',
          'dll_paths': abs_qt_bin_dir,
          'pdb_paths': abs_qt_lib_dir,
          'target_dir': os.path.join(abs_out_win_dir, 'DebugDynamic')})
      copy_params.append({
          'basenames': 'Qt5Core;Qt5Gui;Qt5Widgets',
          'dll_paths': abs_qt_bin_dir,
          'pdb_paths': abs_qt_lib_dir,
          'target_dir': os.path.join(abs_out_win_dir, 'ReleaseDynamic')})
      copy_params.append({
          'basenames': 'qwindowsd',
          'dll_paths': os.path.join(abs_qtdir, 'plugins', 'platforms'),
          'pdb_paths': os.path.join(abs_qtdir, 'plugins', 'platforms'),
          'target_dir': os.path.join(abs_out_win_dir, 'DebugDynamic',
                                     'platforms')})
      copy_params.append({
          'basenames': 'qwindows',
          'dll_paths': os.path.join(abs_qtdir, 'plugins', 'platforms'),
          'pdb_paths': os.path.join(abs_qtdir, 'plugins', 'platforms'),
          'target_dir': os.path.join(abs_out_win_dir, 'ReleaseDynamic',
                                     'platforms')})
    for copy_param in copy_params:
      copy_commands = [
          copy_script,
          '--basenames', copy_param['basenames'],
          '--dll_paths', copy_param['dll_paths'],
          '--pdb_paths', copy_param['pdb_paths'],
          '--target_dir', copy_param['target_dir'],
      ]
      RunOrDie(copy_commands)