~ubuntu-branches/ubuntu/oneiric/mozc/oneiric

« back to all changes in this revision

Viewing changes to .pc/gyp.patch/build_mozc.py

  • Committer: Bazaar Package Importer
  • Author(s): Nobuhiro Iwamatsu
  • Date: 2010-07-14 03:26:47 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20100714032647-13qjisj6m8cm8jdx
Tags: 0.12.410.102-1
* New upstream release (Closes: #588971).
  - Add mozc-server, mozc-utils-gui and scim-mozc packages.
* Update debian/rules.
  Add --gypdir option to build_mozc.py.
* Update debian/control.
  - Bumped standards-version to 3.9.0.
  - Update description.
* Add mozc icon (Closes: #588972).
* Add patch which revises issue 18.
  ibus_mozc_issue18.patch
* kFreeBSD build support.
  support_kfreebsd.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright 2010, Google Inc.
2
 
# All rights reserved.
3
 
#
4
 
# Redistribution and use in source and binary forms, with or without
5
 
# modification, are permitted provided that the following conditions are
6
 
# met:
7
 
#
8
 
#     * Redistributions of source code must retain the above copyright
9
 
# notice, this list of conditions and the following disclaimer.
10
 
#     * Redistributions in binary form must reproduce the above
11
 
# copyright notice, this list of conditions and the following disclaimer
12
 
# in the documentation and/or other materials provided with the
13
 
# distribution.
14
 
#     * Neither the name of Google Inc. nor the names of its
15
 
# contributors may be used to endorse or promote products derived from
16
 
# this software without specific prior written permission.
17
 
#
18
 
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
 
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
 
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21
 
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
 
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23
 
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24
 
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25
 
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26
 
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27
 
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28
 
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
 
 
30
 
"""Script building Mozc.
31
 
 
32
 
Typical usage:
33
 
 
34
 
  % python build_mozc.py gyp
35
 
  % python build_mozc.py build_tools -c Release
36
 
  % python build_mozc.py build base/base.gyp:base
37
 
"""
38
 
 
39
 
__author__ = "komatsu"
40
 
 
41
 
import glob
42
 
import optparse
43
 
import os
44
 
import re
45
 
import shutil
46
 
import subprocess
47
 
import sys
48
 
 
49
 
SRC_DIR = '.'
50
 
EXTRA_SRC_DIR = '..'
51
 
 
52
 
sys.path.append(SRC_DIR)
53
 
 
54
 
from build_tools import mozc_version
55
 
 
56
 
 
57
 
def IsWindows():
58
 
  """Returns true if the platform is Windows."""
59
 
  return os.name == 'nt'
60
 
 
61
 
 
62
 
def IsMac():
63
 
  """Returns true if the platform is Mac."""
64
 
  return os.name == 'posix' and os.uname()[0] == 'Darwin'
65
 
 
66
 
 
67
 
def IsLinux():
68
 
  """Returns true if the platform is Linux."""
69
 
  return os.name == 'posix' and os.uname()[0] == 'Linux'
70
 
 
71
 
 
72
 
def GetGeneratorName():
73
 
  """Gets the generator name based on the platform."""
74
 
  generator = 'make'
75
 
  if IsWindows():
76
 
    generator = 'msvs'
77
 
  elif IsMac():
78
 
    generator = 'xcode'
79
 
  return generator
80
 
 
81
 
 
82
 
def GenerateVersionFile(version_template_path, version_path):
83
 
  """Reads the version template file and stores it into version_path.
84
 
 
85
 
  This doesn't update the "version_path" if nothing will be changed to
86
 
  reduce unnecessary build caused by file timestamp.
87
 
 
88
 
  Args:
89
 
    version_template_path: a file name which contains the template of version.
90
 
    version_path: a file name to be stored the official version.
91
 
  """
92
 
  version = mozc_version.MozcVersion(version_template_path, expand_daily=True)
93
 
  version_definition = version.GetVersionInFormat(
94
 
      'MAJOR=@MAJOR@\nMINOR=@MINOR@\nBUILD=@BUILD@\nREVISION=@REVISION@\n')
95
 
  old_content = ''
96
 
  if os.path.exists(version_path):
97
 
    # if the target file already exists, need to check the necessity of update.
98
 
    old_content = open(version_path).read()
99
 
 
100
 
  if version_definition != old_content:
101
 
    open(version_path, 'w').write(version_definition)
102
 
 
103
 
 
104
 
def GetVersionFileNames():
105
 
  """Gets the (template of version file, version file) pair."""
106
 
  template_path = '%s/mozc_version_template.txt' % SRC_DIR
107
 
  version_path = '%s/mozc_version.txt' % SRC_DIR
108
 
  return (template_path, version_path)
109
 
 
110
 
 
111
 
def GetGypFileNames():
112
 
  """Gets the list of gyp file names."""
113
 
  gyp_file_names = []
114
 
  mozc_top_level_names = glob.glob('%s/*' % SRC_DIR)
115
 
  # Exclude the gyp directory where we have special gyp files like
116
 
  # breakpad.gyp that we should exclude.
117
 
  mozc_top_level_names = [x for x in mozc_top_level_names if
118
 
                          os.path.basename(x) != 'gyp']
119
 
  for name in mozc_top_level_names:
120
 
    gyp_file_names.extend(glob.glob(name + '/*.gyp'))
121
 
  gyp_file_names.extend(glob.glob('%s/build_tools/*/*.gyp' % SRC_DIR))
122
 
  # Include subdirectory of dictionary
123
 
  gyp_file_names.append(
124
 
      '%s/dictionary/file/dictionary_file.gyp' % SRC_DIR)
125
 
  gyp_file_names.append(
126
 
      '%s/dictionary/system/system_dictionary.gyp' % SRC_DIR)
127
 
  # Include subdirectory of win32 and breakpad for Windows
128
 
  if IsWindows():
129
 
    gyp_file_names.extend(glob.glob('%s/win32/*/*.gyp' % SRC_DIR))
130
 
    gyp_file_names.extend(glob.glob('third_party/breakpad/*.gyp'))
131
 
    gyp_file_names.append('third_party/mozc/sandbox/sandbox.gyp')
132
 
  elif IsLinux():
133
 
    gyp_file_names.extend(glob.glob('%s/unix/*/*.gyp' % SRC_DIR))
134
 
  gyp_file_names.extend(glob.glob('third_party/rx/*.gyp'))
135
 
  gyp_file_names.sort()
136
 
  return gyp_file_names
137
 
 
138
 
 
139
 
def RemoveFile(file_name):
140
 
  """Removes the specified file."""
141
 
  if not os.path.isfile(file_name):
142
 
    return  # Do nothing if not exist.
143
 
  if IsWindows():
144
 
    # Read-only files cannot be deleted on Windows.
145
 
    os.chmod(file_name, 0700)
146
 
  print 'Removing file: %s' % file_name
147
 
  os.unlink(file_name)
148
 
 
149
 
 
150
 
def CopyFile(source, destination):
151
 
  """Copies a file to the destination. Remove an old version if needed."""
152
 
  if os.path.isfile(destination):  # Remove the old one if exists.
153
 
    RemoveFile(destination)
154
 
  print 'Copying file to: %s' % destination
155
 
  shutil.copy(source, destination)
156
 
 
157
 
 
158
 
def RecursiveRemoveDirectory(directory):
159
 
  """Removes the specified directory recursively."""
160
 
  if os.path.isdir(directory):
161
 
    print 'Removing directory: %s' % directory
162
 
    if IsWindows():
163
 
      # Use RD because shutil.rmtree fails when the directory is readonly.
164
 
      RunOrDie(['CMD.exe', '/C', 'RD', '/S', '/Q',
165
 
                os.path.normpath(directory)])
166
 
    else:
167
 
      shutil.rmtree(directory, ignore_errors=True)
168
 
 
169
 
 
170
 
def CleanBuildFilesAndDirectories():
171
 
  """Cleans build files and directories."""
172
 
  # File and directory names to be removed.
173
 
  file_names = []
174
 
  directory_names = []
175
 
 
176
 
  # Collect stuff in the gyp directories.
177
 
  gyp_directory_names = [os.path.dirname(f) for f in GetGypFileNames()]
178
 
  for gyp_directory_name in gyp_directory_names:
179
 
    if IsWindows():
180
 
      for pattern in ['*.rules', '*.sln', '*.vcproj']:
181
 
        file_names.extend(glob.glob(os.path.join(gyp_directory_name,
182
 
                                                 pattern)))
183
 
      for build_type in ['Debug', 'Optimize', 'Release']:
184
 
        directory_names.append(os.path.join(gyp_directory_name,
185
 
                                            build_type))
186
 
    elif IsMac():
187
 
      directory_names.extend(glob.glob(os.path.join(gyp_directory_name,
188
 
                                                    '*.xcodeproj')))
189
 
    elif IsLinux():
190
 
      file_names.extend(glob.glob(os.path.join(gyp_directory_name,
191
 
                                               '*.target.mk')))
192
 
  file_names.append('%s/mozc_version.txt' % SRC_DIR)
193
 
  file_names.append('third_party/rx/rx.gyp')
194
 
  # Collect stuff in the top-level directory.
195
 
  directory_names.append('mozc_build_tools')
196
 
  if IsMac():
197
 
    directory_names.append('xcodebuild')
198
 
  elif IsLinux():
199
 
    file_names.append('Makefile')
200
 
    directory_names.append('out')
201
 
  elif IsWindows():
202
 
    file_names.append('third_party/breakpad/breakpad.gyp')
203
 
    directory_names.append('out_win')
204
 
  # Remove files.
205
 
  for file_name in file_names:
206
 
    RemoveFile(file_name)
207
 
  # Remove directories.
208
 
  for directory_name in directory_names:
209
 
    RecursiveRemoveDirectory(directory_name)
210
 
 
211
 
 
212
 
def GetTopLevelSourceDirectoryName():
213
 
  """Gets the top level source directory name."""
214
 
  if SRC_DIR == '.':
215
 
    return SRC_DIR
216
 
  script_file_directory_name = os.path.dirname(sys.argv[0])
217
 
  num_components = len(SRC_DIR.split('/'))
218
 
  dots = ['..'] * num_components
219
 
  return os.path.join(script_file_directory_name, '/'.join(dots))
220
 
 
221
 
 
222
 
def MoveToTopLevelSourceDirectory():
223
 
  """Moves to the build top level directory."""
224
 
  os.chdir(GetTopLevelSourceDirectoryName())
225
 
 
226
 
 
227
 
def GetGypSvnUrl(deps_file_name):
228
 
  """Get the GYP SVN URL from DEPS file."""
229
 
  contents = file(deps_file_name).read()
230
 
  match = re.search(r'"(http://gyp\.googlecode\.com.*?)"', contents)
231
 
  if match:
232
 
    return match.group(1)
233
 
  else:
234
 
    PrintErrorAndExit('GYP URL not found in %s:' % deps_file_name)
235
 
 
236
 
 
237
 
def GypMain(deps_file_name):
238
 
  options = ParseGypOptions()
239
 
  """The main function for the 'gyp' command."""
240
 
  # Copy rx.gyp to the third party directory.
241
 
  CopyFile('%s/gyp/rx.gyp' % SRC_DIR,
242
 
           'third_party/rx/rx.gyp')
243
 
  # Copy breakpad.gyp to the third party directory, if necessary.
244
 
  if IsWindows():
245
 
    CopyFile('%s/gyp/breakpad.gyp' % SRC_DIR,
246
 
             'third_party/breakpad/breakpad.gyp')
247
 
 
248
 
  # Determine the generator name.
249
 
  generator = GetGeneratorName()
250
 
  os.environ['GYP_GENERATORS'] = generator
251
 
  print 'Build tool: %s' % generator
252
 
 
253
 
  # Get and show the list of .gyp file names.
254
 
  gyp_file_names = GetGypFileNames()
255
 
  print 'GYP files:'
256
 
  for file_name in gyp_file_names:
257
 
    print '- %s' % file_name
258
 
  # We use the one in mozc_build_tools/gyp
259
 
  gyp_script = 'mozc_build_tools/gyp/gyp'
260
 
  # If we don't have a copy of gyp, download it.
261
 
  if not os.path.isfile(gyp_script):
262
 
    # SVN creates mozc_build_tools directory if it's not present.
263
 
    gyp_svn_url = GetGypSvnUrl(deps_file_name)
264
 
    RunOrDie(['svn', 'checkout', gyp_svn_url, 'mozc_build_tools/gyp'])
265
 
  # Run GYP.
266
 
  print 'Running GYP...'
267
 
  command_line = [sys.executable, gyp_script,
268
 
                  '--no-circular-check',
269
 
                  '--depth=.',
270
 
                  '--include=%s/gyp/common.gypi' % SRC_DIR]
271
 
  command_line.extend(['-D', 'two_pass_build=1'])
272
 
  command_line.extend(gyp_file_names)
273
 
 
274
 
  if options.branding:
275
 
    command_line.extend(['-D', 'branding=%s' % options.branding])
276
 
  RunOrDie(command_line)
277
 
 
278
 
 
279
 
  # Done!
280
 
  print 'Done'
281
 
 
282
 
 
283
 
def CleanMain():
284
 
  """The main function for the 'clean' command."""
285
 
  CleanBuildFilesAndDirectories()
286
 
 
287
 
 
288
 
class RunOrDieError(StandardError):
289
 
  """The exception class for RunOrDie."""
290
 
 
291
 
  def __init__(self, message):
292
 
    StandardError.__init__(self, message)
293
 
 
294
 
 
295
 
def RunOrDie(argv):
296
 
  """Run the command, or die if it failed."""
297
 
 
298
 
  # Rest are the target program name and the parameters, but we special
299
 
  # case if the target program name ends with '.py'
300
 
  if argv[0].endswith('.py'):
301
 
    argv.insert(0, sys.executable)  # Inject the python interpreter path.
302
 
  # We don't capture stdout and stderr from Popen. The output will just
303
 
  # be emitted to a terminal or console.
304
 
  print 'Running: ' + ' '.join(argv)
305
 
  process = subprocess.Popen(argv)
306
 
 
307
 
  if process.wait() != 0:
308
 
    raise RunOrDieError('\n'.join(['',
309
 
                                   '==========',
310
 
                                   ' ERROR: %s' % ' '.join(argv),
311
 
                                   '==========']))
312
 
 
313
 
 
314
 
def PrintErrorAndExit(error_message):
315
 
  """Prints the error message and exists."""
316
 
  print error_message
317
 
  sys.exit(1)
318
 
 
319
 
 
320
 
def ParseGypOptions():
321
 
  """Parse command line options for the gyp command."""
322
 
  parser = optparse.OptionParser(usage='Usage: %prog gyp [options]')
323
 
  parser.add_option('--onepass', '-1', dest='onepass', action='store_true',
324
 
                    default=False, help='build mozc in one pass. ' +
325
 
                    'Not recommended for Debug build.')
326
 
  parser.add_option('--branding', dest='branding', default='Mozc')
327
 
  (options, unused_args) = parser.parse_args()
328
 
  return options
329
 
 
330
 
 
331
 
def ParseBuildOptions():
332
 
  """Parse command line options for the build command."""
333
 
  parser = optparse.OptionParser(usage='Usage: %prog build [options]')
334
 
  parser.add_option('--jobs', '-j', dest='jobs', default='4', metavar='N',
335
 
                    help='run jobs in parallel')
336
 
  parser.add_option('--configuration', '-c', dest='configuration',
337
 
                    default='Debug', help='specify the build configuration.')
338
 
  if IsWindows():
339
 
    parser.add_option('--platform', '-p', dest='platform',
340
 
                      default='Win32',
341
 
                      help='specify the target plaform: [Win32|x64]')
342
 
  # default Qt dir to support the current build procedure for Debian.
343
 
  default_qtdir = '/usr/local/Trolltech/Qt-4.5.2'
344
 
  if IsWindows():
345
 
    default_qtdir = None
346
 
  parser.add_option('--qtdir', dest='qtdir',
347
 
                    default=os.getenv('QTDIR', default_qtdir),
348
 
                    help='Qt base directory to be used.')
349
 
 
350
 
  (options, args) = parser.parse_args()
351
 
 
352
 
  targets = args
353
 
  if not targets:
354
 
    PrintErrorAndExit('No build target is specified.')
355
 
 
356
 
  return (options, args)
357
 
 
358
 
 
359
 
def ParseTarget(target):
360
 
  """Parses the target string."""
361
 
  if not ':' in target:
362
 
    PrintErrorAndExit('Invalid target: ' + target)
363
 
  (gyp_file_name, target_name) = target.split(':')
364
 
  return (gyp_file_name, target_name)
365
 
 
366
 
 
367
 
def BuildOnLinux(options, targets):
368
 
  """Build the targets on Linux."""
369
 
  target_names = []
370
 
  for target in targets:
371
 
    (unused_gyp_file_name, target_name) = ParseTarget(target)
372
 
    target_names.append(target_name)
373
 
 
374
 
  make_command = os.getenv('BUILD_COMMAND', 'make')
375
 
  # flags for building in Chrome OS chroot environment
376
 
  envvars = [
377
 
      'CFLAGS',
378
 
      'CXXFLAGS',
379
 
      'CXX',
380
 
      'CC',
381
 
      'AR',
382
 
      'AS',
383
 
      'RANLIB',
384
 
      'LD',
385
 
  ]
386
 
  for envvar in envvars:
387
 
    if envvar in os.environ:
388
 
      os.environ[envvar] = os.getenv(envvar)
389
 
 
390
 
  RunOrDie([make_command, '-j%s' % options.jobs,
391
 
            'BUILDTYPE=%s' % options.configuration] +
392
 
           target_names)
393
 
 
394
 
 
395
 
def CheckFileOrDie(file_name):
396
 
  """Check the file exists or dies if not."""
397
 
  if not os.path.isfile(file_name):
398
 
    PrintErrorAndExit('No such file: ' + file_name)
399
 
 
400
 
 
401
 
def GetRelpath(path, start):
402
 
  """Return a relative path to |path| from |start|."""
403
 
  # NOTE: Python 2.6 provides os.path.relpath, which has almost the same
404
 
  # functionality as this function. Since Python 2.6 is not the internal
405
 
  # official version, we reimplement it.
406
 
  path_list = os.path.abspath(os.path.normpath(path)).split(os.sep)
407
 
  start_list = os.path.abspath(os.path.normpath(start)).split(os.sep)
408
 
 
409
 
  common_prefix_count = 0
410
 
  for i in range(0, min(len(path_list), len(start_list))):
411
 
    if path_list[i] != start_list[i]:
412
 
      break
413
 
    common_prefix_count += 1
414
 
 
415
 
  return os.sep.join(['..'] * (len(start_list) - common_prefix_count) +
416
 
                     path_list[common_prefix_count:])
417
 
 
418
 
 
419
 
def BuildOnMac(options, targets, original_directory_name):
420
 
  """Build the targets on Mac."""
421
 
  # For some reason, xcodebuild does not accept absolute path names for
422
 
  # the -project parameter. Convert the original_directory_name to a
423
 
  # relative path from the build top level directory.
424
 
  original_directory_relpath = GetRelpath(original_directory_name, os.getcwd())
425
 
  sym_root = os.path.join(os.getcwd(), 'xcodebuild')
426
 
  for target in targets:
427
 
    (gyp_file_name, target_name) = ParseTarget(target)
428
 
    gyp_file_name = os.path.join(original_directory_relpath, gyp_file_name)
429
 
    CheckFileOrDie(gyp_file_name)
430
 
    (xcode_base_name, _) = os.path.splitext(gyp_file_name)
431
 
    RunOrDie(['xcodebuild',
432
 
              '-project', '%s.xcodeproj' % xcode_base_name,
433
 
              '-configuration', options.configuration,
434
 
              '-target', target_name,
435
 
              '-parallelizeTargets',
436
 
              'SYMROOT=%s' % sym_root])
437
 
 
438
 
 
439
 
def BuildOnWindows(options, targets, original_directory_name):
440
 
  """Build the target on Windowsw."""
441
 
  # TODO(yukawa): make a python module to set up environment for vcbuild.
442
 
 
443
 
  # TODO(yukawa): Locate the directory of the vcbuild.exe as follows.
444
 
  #   1. Get the clsid corresponding to 'VisualStudio.VCProjectEngine.8.0'
445
 
  #   2. Get the directory of the DLL corresponding to retrieved clsid
446
 
  program_files_path = os.getenv('ProgramFiles(x86)',
447
 
                                 os.getenv('ProgramFiles'))
448
 
  rel_paths = ['Microsoft Visual Studio 8/VC/vcpackages',
449
 
               'Microsoft SDKs/Windows/v6.0/VC/Bin']
450
 
  abs_vcbuild_dir = ''
451
 
  for rel_path in rel_paths:
452
 
    search_dir = os.path.join(program_files_path, rel_path)
453
 
    if os.path.exists(os.path.join(search_dir, 'vcbuild.exe')):
454
 
      abs_vcbuild_dir = os.path.abspath(search_dir)
455
 
      break
456
 
  CheckFileOrDie(os.path.join(abs_vcbuild_dir, 'vcbuild.exe'))
457
 
 
458
 
  if os.getenv('PATH'):
459
 
    os.environ['PATH'] = os.pathsep.join([abs_vcbuild_dir, os.getenv('PATH')])
460
 
  else:
461
 
    os.environ['PATH'] = abs_vcbuild_dir
462
 
 
463
 
  rel_paths = ['%s/third_party/platformsdk/v6_1/files/Bin' % EXTRA_SRC_DIR,
464
 
               '%s/third_party/code_signing' % EXTRA_SRC_DIR,
465
 
               '%s/third_party/vc_80/files/common7/IDE' % EXTRA_SRC_DIR,
466
 
               '%s/third_party/vc_80/files/common7/Tools' % EXTRA_SRC_DIR,
467
 
               '%s/third_party/vc_80/files/common7/Tools/bin' % EXTRA_SRC_DIR,
468
 
               '%s/third_party/wix/v3_0_4220/files' % EXTRA_SRC_DIR]
469
 
  rel_paths_x64 = ['%s/third_party/vc_80/files/vc/bin/x86_amd64'
470
 
                   % EXTRA_SRC_DIR]
471
 
  rel_paths_x86 = ['%s/third_party/vc_80/files/vc/bin' % EXTRA_SRC_DIR]
472
 
  if options.platform == 'x64':
473
 
    rel_paths += rel_paths_x64
474
 
  rel_paths += rel_paths_x86
475
 
  abs_paths = [os.path.abspath(path) for path in rel_paths]
476
 
  os.environ['PATH'] = os.pathsep.join(abs_paths + [os.getenv('PATH')])
477
 
 
478
 
  os.environ['INCLUDE'] = ''
479
 
  os.environ['LIB'] = ''
480
 
  os.environ['LIBPATH'] = ''
481
 
 
482
 
  for target in targets:
483
 
    # TODO(yukawa): target name is currently ignored.
484
 
    (gyp_file_name, _) = ParseTarget(target)
485
 
    gyp_file_name = os.path.join(original_directory_name, gyp_file_name)
486
 
    CheckFileOrDie(gyp_file_name)
487
 
    (sln_base_name, _) = os.path.splitext(gyp_file_name)
488
 
    sln_file_path = os.path.abspath('%s.sln' % sln_base_name)
489
 
    # To use different toolsets for vcbuild, we set %PATH%, %INCLUDE%, %LIB%,
490
 
    # %LIBPATH% and specify /useenv option here.  See the following article
491
 
    # for details.
492
 
    # http://blogs.msdn.com/vcblog/archive/2007/12/30/using-different-toolsets-for-vc-build.aspx
493
 
    RunOrDie(['vcbuild',
494
 
              '/useenv',  # Use %PATH%, %INCLUDE%, %LIB%, %LIBPATH%
495
 
              '/M',       # Use concurrent build
496
 
              '/time',    # Show build time
497
 
              '/platform:%s' % options.platform,
498
 
              sln_file_path,
499
 
              '%s|%s' % (options.configuration, options.platform)])
500
 
 
501
 
 
502
 
def BuildMain(original_directory_name):
503
 
  """The main function for the 'build' command."""
504
 
  (options, targets) = ParseBuildOptions()
505
 
 
506
 
  # Generate a version definition file.
507
 
  print 'Generating version definition file...'
508
 
  (template_path, version_path) = GetVersionFileNames()
509
 
  GenerateVersionFile(template_path, version_path)
510
 
 
511
 
  # Set $QTDIR for mozc_tool
512
 
  if options.qtdir:
513
 
    print 'export $QTDIR = %s' % options.qtdir
514
 
    os.environ['QTDIR'] = options.qtdir
515
 
 
516
 
  if IsMac():
517
 
    BuildOnMac(options, targets, original_directory_name)
518
 
  elif IsLinux():
519
 
    BuildOnLinux(options, targets)
520
 
  elif IsWindows():
521
 
    BuildOnWindows(options, targets, original_directory_name)
522
 
  else:
523
 
    print 'Unsupported platform: ', system
524
 
 
525
 
 
526
 
def BuildToolsMain(original_directory_name):
527
 
  """The main function for 'build_tools' command."""
528
 
  build_tools_dir = os.path.join(GetRelpath(os.getcwd(),
529
 
                                            original_directory_name),
530
 
                                 '%s/build_tools' % SRC_DIR)
531
 
  # build targets in this order
532
 
  gyp_files = [
533
 
      os.path.join(build_tools_dir, 'primitive_tools', 'primitive_tools.gyp'),
534
 
      os.path.join(build_tools_dir, 'build_tools.gyp')
535
 
      ]
536
 
 
537
 
  for gyp_file in gyp_files:
538
 
    (target, _) = os.path.splitext(os.path.basename(gyp_file))
539
 
    sys.argv.append('%s:%s' % (gyp_file, target))
540
 
    BuildMain(original_directory_name)
541
 
    sys.argv.pop()
542
 
 
543
 
 
544
 
def ShowHelpAndExit():
545
 
  """Shows the help message."""
546
 
  print 'Usage: build_mozc.py COMMAND [ARGS]'
547
 
  print 'Commands: '
548
 
  print '  gyp          Generate project files.'
549
 
  print '  build        Build the specified target.'
550
 
  print '  build_tools  Build tools used by the build command.'
551
 
  print '  clean        Clean all the build files and directories.'
552
 
  print ''
553
 
  print 'See also the comment in the script for typical usage.'
554
 
  sys.exit(1)
555
 
 
556
 
 
557
 
def main():
558
 
  if len(sys.argv) < 2:
559
 
    ShowHelpAndExit()
560
 
 
561
 
  # DEPS files should exist in the same directory of the script.
562
 
  deps_file_name = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]),
563
 
                                                'DEPS'))
564
 
  # Remember the original current directory name.
565
 
  original_directory_name = os.getcwd()
566
 
  # Move to the top level source directory only once since os.chdir
567
 
  # affects functions in os.path and that causes troublesome errors.
568
 
  MoveToTopLevelSourceDirectory()
569
 
 
570
 
  command = sys.argv[1]
571
 
  del(sys.argv[1])  # Delete the command.
572
 
  if command == 'build':
573
 
    BuildMain(original_directory_name)
574
 
  elif command == 'build_tools':
575
 
    BuildToolsMain(original_directory_name)
576
 
  elif command == 'clean':
577
 
    CleanMain()
578
 
  elif command == 'gyp':
579
 
    GypMain(deps_file_name)
580
 
  else:
581
 
    print 'Unknown command: ' + command
582
 
    ShowHelpAndExit()
583
 
 
584
 
if __name__ == '__main__':
585
 
  main()