init.configure 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801
  1. # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
  2. # This Source Code Form is subject to the terms of the Mozilla Public
  3. # License, v. 2.0. If a copy of the MPL was not distributed with this
  4. # file, You can obtain one at http://mozilla.org/MPL/2.0/.
  5. include('util.configure')
  6. include('checks.configure')
  7. option(env='DIST', nargs=1, help='DIST directory')
  8. # Do not allow objdir == srcdir builds.
  9. # ==============================================================
  10. @depends('--help', 'DIST')
  11. @imports(_from='os.path', _import='exists')
  12. def check_build_environment(help, dist):
  13. topobjdir = os.path.realpath(os.path.abspath('.'))
  14. topsrcdir = os.path.realpath(os.path.abspath(
  15. os.path.join(os.path.dirname(__file__), '..', '..')))
  16. if dist:
  17. dist = normsep(dist[0])
  18. else:
  19. dist = os.path.join(topobjdir, 'dist')
  20. result = namespace(
  21. topsrcdir=topsrcdir,
  22. topobjdir=topobjdir,
  23. dist=dist,
  24. )
  25. if help:
  26. return result
  27. if topsrcdir == topobjdir:
  28. die(' ***\n'
  29. ' * Building directly in the main source directory is not allowed.\n'
  30. ' *\n'
  31. ' * To build, you must run configure from a separate directory\n'
  32. ' * (referred to as an object directory).\n'
  33. ' *\n'
  34. ' * If you are building with a mozconfig, you will need to change your\n'
  35. ' * mozconfig to point to a different object directory.\n'
  36. ' ***'
  37. )
  38. # Check for a couple representative files in the source tree
  39. conflict_files = [
  40. '* %s' % f for f in ('Makefile', 'config/autoconf.mk')
  41. if exists(os.path.join(topsrcdir, f))
  42. ]
  43. if conflict_files:
  44. die(' ***\n'
  45. ' * Your source tree contains these files:\n'
  46. ' %s\n'
  47. ' * This indicates that you previously built in the source tree.\n'
  48. ' * A source tree build can confuse the separate objdir build.\n'
  49. ' *\n'
  50. ' * To clean up the source tree:\n'
  51. ' * 1. cd %s\n'
  52. ' * 2. gmake distclean\n'
  53. ' ***'
  54. % ('\n '.join(conflict_files), topsrcdir)
  55. )
  56. return result
  57. set_config('TOPSRCDIR', delayed_getattr(check_build_environment, 'topsrcdir'))
  58. set_config('TOPOBJDIR', delayed_getattr(check_build_environment, 'topobjdir'))
  59. set_config('MOZ_BUILD_ROOT', delayed_getattr(check_build_environment,
  60. 'topobjdir'))
  61. set_config('DIST', delayed_getattr(check_build_environment, 'dist'))
  62. option(env='MOZ_AUTOMATION', help='Enable options for automated builds')
  63. set_config('MOZ_AUTOMATION', depends_if('MOZ_AUTOMATION')(lambda x: True))
  64. option(env='OLD_CONFIGURE', nargs=1, help='Path to the old configure script')
  65. option(env='MOZ_CURRENT_PROJECT', nargs=1, help='Current build project')
  66. option(env='MOZCONFIG', nargs=1, help='Mozconfig location')
  67. # Read user mozconfig
  68. # ==============================================================
  69. # Note: the dependency on --help is only there to always read the mozconfig,
  70. # even when --help is passed. Without this dependency, the function wouldn't
  71. # be called when --help is passed, and the mozconfig wouldn't be read.
  72. @depends('MOZ_CURRENT_PROJECT', 'MOZCONFIG', 'OLD_CONFIGURE',
  73. check_build_environment, '--help')
  74. @imports(_from='mozbuild.mozconfig', _import='MozconfigLoader')
  75. def mozconfig(current_project, mozconfig, old_configure, build_env, help):
  76. if not old_configure:
  77. die('The OLD_CONFIGURE environment variable must be set')
  78. # Don't read the mozconfig for the js configure (yay backwards
  79. # compatibility)
  80. # While the long term goal is that js and top-level use the same configure
  81. # and the same overall setup, including the possibility to use mozconfigs,
  82. # figuring out what we want to do wrt mozconfig vs. command line and
  83. # environment variable is not a clear-cut case, and it's more important to
  84. # fix the immediate problem mozconfig causes to js developers by
  85. # "temporarily" returning to the previous behavior of not loading the
  86. # mozconfig for the js configure.
  87. # Separately to the immediate problem for js developers, there is also the
  88. # need to not load a mozconfig when running js configure as a subconfigure.
  89. # Unfortunately, there is no direct way to tell whether the running
  90. # configure is the js configure. The indirect way is to look at the
  91. # OLD_CONFIGURE path, which points to js/src/old-configure.
  92. # I expect we'll have figured things out for mozconfigs well before
  93. # old-configure dies.
  94. if os.path.dirname(os.path.abspath(old_configure[0])).endswith('/js/src'):
  95. return {'path': None}
  96. loader = MozconfigLoader(build_env.topsrcdir)
  97. current_project = current_project[0] if current_project else None
  98. mozconfig = mozconfig[0] if mozconfig else None
  99. mozconfig = loader.find_mozconfig(env={'MOZCONFIG': mozconfig})
  100. mozconfig = loader.read_mozconfig(mozconfig, moz_build_app=current_project)
  101. return mozconfig
  102. set_config('MOZCONFIG', depends(mozconfig)(lambda m: m['path']))
  103. option(env='PYTHON', nargs=1, help='Python interpreter')
  104. # Setup python virtualenv
  105. # ==============================================================
  106. @depends('PYTHON', check_build_environment, mozconfig, '--help')
  107. @imports('os')
  108. @imports('sys')
  109. @imports('subprocess')
  110. @imports(_from='mozbuild.configure.util', _import='LineIO')
  111. @imports(_from='mozbuild.virtualenv', _import='VirtualenvManager')
  112. @imports(_from='mozbuild.virtualenv', _import='verify_python_version')
  113. @imports('distutils.sysconfig')
  114. def virtualenv_python(env_python, build_env, mozconfig, help):
  115. if help:
  116. return
  117. python = env_python[0] if env_python else None
  118. # Ideally we'd rely on the mozconfig injection from mozconfig_options,
  119. # but we'd rather avoid the verbosity when we need to reexecute with
  120. # a different python.
  121. if mozconfig['path']:
  122. if 'PYTHON' in mozconfig['env']['added']:
  123. python = mozconfig['env']['added']['PYTHON']
  124. elif 'PYTHON' in mozconfig['env']['modified']:
  125. python = mozconfig['env']['modified']['PYTHON'][1]
  126. elif 'PYTHON' in mozconfig['vars']['added']:
  127. python = mozconfig['vars']['added']['PYTHON']
  128. elif 'PYTHON' in mozconfig['vars']['modified']:
  129. python = mozconfig['vars']['modified']['PYTHON'][1]
  130. with LineIO(lambda l: log.error(l)) as out:
  131. verify_python_version(out)
  132. topsrcdir, topobjdir = build_env.topsrcdir, build_env.topobjdir
  133. if topobjdir.endswith('/js/src'):
  134. topobjdir = topobjdir[:-7]
  135. with LineIO(lambda l: log.info(l)) as out:
  136. manager = VirtualenvManager(
  137. topsrcdir, topobjdir,
  138. os.path.join(topobjdir, '_virtualenv'), out,
  139. os.path.join(topsrcdir, 'build', 'virtualenv_packages.txt'))
  140. if python:
  141. # If we're not in the virtualenv, we need the which module for
  142. # find_program.
  143. if normsep(sys.executable) != normsep(manager.python_path):
  144. sys.path.append(os.path.join(topsrcdir, 'python', 'which'))
  145. found_python = find_program(python)
  146. if not found_python:
  147. die('The PYTHON environment variable does not contain '
  148. 'a valid path. Cannot find %s', python)
  149. python = found_python
  150. else:
  151. python = sys.executable
  152. if not manager.up_to_date(python):
  153. log.info('Creating Python environment')
  154. manager.build(python)
  155. python = normsep(manager.python_path)
  156. if python != normsep(sys.executable):
  157. log.info('Reexecuting in the virtualenv')
  158. if env_python:
  159. del os.environ['PYTHON']
  160. # One would prefer to use os.execl, but that's completely borked on
  161. # Windows.
  162. sys.exit(subprocess.call([python] + sys.argv))
  163. # We are now in the virtualenv
  164. if not distutils.sysconfig.get_python_lib():
  165. die('Could not determine python site packages directory')
  166. return python
  167. set_config('PYTHON', virtualenv_python)
  168. add_old_configure_assignment('PYTHON', virtualenv_python)
  169. # Inject mozconfig options
  170. # ==============================================================
  171. # All options defined above this point can't be injected in mozconfig_options
  172. # below, so collect them.
  173. @template
  174. def early_options():
  175. @dependable
  176. @imports('__sandbox__')
  177. def early_options():
  178. return set(
  179. option.env
  180. for option in __sandbox__._options.itervalues()
  181. if option.env
  182. )
  183. return early_options
  184. early_options = early_options()
  185. @depends(mozconfig, '--help')
  186. # This gives access to the sandbox. Don't copy this blindly.
  187. @imports('__sandbox__')
  188. @imports('os')
  189. def mozconfig_options(mozconfig, help):
  190. if mozconfig['path']:
  191. helper = __sandbox__._helper
  192. log.info('Adding configure options from %s' % mozconfig['path'])
  193. for arg in mozconfig['configure_args']:
  194. log.info(' %s' % arg)
  195. # We could be using imply_option() here, but it has other
  196. # contraints that don't really apply to the command-line
  197. # emulation that mozconfig provides.
  198. helper.add(arg, origin='mozconfig', args=helper._args)
  199. def add(key, value):
  200. if key.isupper():
  201. arg = '%s=%s' % (key, value)
  202. log.info(' %s' % arg)
  203. helper.add(arg, origin='mozconfig', args=helper._args)
  204. for key, value in mozconfig['env']['added'].iteritems():
  205. add(key, value)
  206. os.environ[key] = value
  207. for key, (_, value) in mozconfig['env']['modified'].iteritems():
  208. add(key, value)
  209. os.environ[key] = value
  210. for key, value in mozconfig['vars']['added'].iteritems():
  211. # mozconfig_loader adds _IS_SET variables that are irrelevant
  212. if not key.endswith('_IS_SET'):
  213. add(key, value)
  214. for key, (_, value) in mozconfig['vars']['modified'].iteritems():
  215. add(key, value)
  216. # Mozilla-Build
  217. # ==============================================================
  218. option(env='MOZILLABUILD', nargs=1,
  219. help='Path to Mozilla Build (Windows-only)')
  220. option(env='CONFIG_SHELL', nargs=1, help='Path to a POSIX shell')
  221. # It feels dirty replicating this from python/mozbuild/mozbuild/mozconfig.py,
  222. # but the end goal being that the configure script would go away...
  223. @depends('CONFIG_SHELL', 'MOZILLABUILD')
  224. @checking('for a shell')
  225. @imports('sys')
  226. def shell(value, mozillabuild):
  227. if value:
  228. return find_program(value[0])
  229. shell = 'sh'
  230. if mozillabuild:
  231. shell = mozillabuild[0] + '/msys/bin/sh'
  232. if sys.platform == 'win32':
  233. shell = shell + '.exe'
  234. return find_program(shell)
  235. # Host and target systems
  236. # ==============================================================
  237. option('--host', nargs=1, help='Define the system type performing the build')
  238. option('--target', nargs=1,
  239. help='Define the system type where the resulting executables will be '
  240. 'used')
  241. @imports(_from='mozbuild.configure.constants', _import='CPU')
  242. @imports(_from='mozbuild.configure.constants', _import='CPU_bitness')
  243. @imports(_from='mozbuild.configure.constants', _import='Endianness')
  244. @imports(_from='mozbuild.configure.constants', _import='Kernel')
  245. @imports(_from='mozbuild.configure.constants', _import='OS')
  246. def split_triplet(triplet):
  247. # The standard triplet is defined as
  248. # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
  249. # There is also a quartet form:
  250. # CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
  251. # But we can consider the "KERNEL-OPERATING_SYSTEM" as one.
  252. cpu, manufacturer, os = triplet.split('-', 2)
  253. # Autoconf uses config.sub to validate and canonicalize those triplets,
  254. # but the granularity of its results has never been satisfying to our
  255. # use, so we've had our own, different, canonicalization. We've also
  256. # historically not been very consistent with how we use the canonicalized
  257. # values. Hopefully, this will help us make things better.
  258. # The tests are inherited from our decades-old autoconf-based configure,
  259. # which can probably be improved/cleaned up because they are based on a
  260. # mix of uname and config.guess output, while we now only use the latter,
  261. # which presumably has a cleaner and leaner output. Let's refine later.
  262. os = os.replace('/', '_')
  263. if 'android' in os:
  264. canonical_os = 'Android'
  265. canonical_kernel = 'Linux'
  266. elif os.startswith('linux'):
  267. canonical_os = 'GNU'
  268. canonical_kernel = 'Linux'
  269. elif os.startswith('kfreebsd') and os.endswith('-gnu'):
  270. canonical_os = 'GNU'
  271. canonical_kernel = 'kFreeBSD'
  272. elif os.startswith('gnu'):
  273. canonical_os = canonical_kernel = 'GNU'
  274. elif os.startswith('mingw'):
  275. canonical_os = canonical_kernel = 'WINNT'
  276. elif os.startswith('darwin'):
  277. canonical_kernel = 'Darwin'
  278. canonical_os = 'OSX'
  279. elif os.startswith('ios'):
  280. canonical_kernel = 'Darwin'
  281. canonical_os = 'iOS'
  282. elif os.startswith('dragonfly'):
  283. canonical_os = canonical_kernel = 'DragonFly'
  284. elif os.startswith('freebsd'):
  285. canonical_os = canonical_kernel = 'FreeBSD'
  286. elif os.startswith('netbsd'):
  287. canonical_os = canonical_kernel = 'NetBSD'
  288. elif os.startswith('openbsd'):
  289. canonical_os = canonical_kernel = 'OpenBSD'
  290. elif os.startswith('solaris'):
  291. canonical_os = canonical_kernel = 'SunOS'
  292. else:
  293. die('Unknown OS: %s' % os)
  294. # The CPU granularity is probably not enough. Moving more things from
  295. # old-configure will tell us if we need more
  296. if cpu.endswith('86') or (cpu.startswith('i') and '86' in cpu):
  297. canonical_cpu = 'x86'
  298. endianness = 'little'
  299. elif cpu in ('x86_64', 'ia64'):
  300. canonical_cpu = cpu
  301. endianness = 'little'
  302. elif cpu in ('s390', 's390x'):
  303. canonical_cpu = cpu
  304. endianness = 'big'
  305. elif cpu in ('powerpc64', 'ppc64', 'powerpc64le', 'ppc64le'):
  306. canonical_cpu = 'ppc64'
  307. endianness = 'little' if 'le' in cpu else 'big'
  308. elif cpu in ('powerpc', 'ppc', 'rs6000') or cpu.startswith('powerpc'):
  309. canonical_cpu = 'ppc'
  310. endianness = 'big'
  311. elif cpu in ('Alpha', 'alpha', 'ALPHA'):
  312. canonical_cpu = 'Alpha'
  313. endianness = 'little'
  314. elif cpu.startswith('hppa') or cpu == 'parisc':
  315. canonical_cpu = 'hppa'
  316. endianness = 'big'
  317. elif cpu.startswith('sparc64'):
  318. canonical_cpu = 'sparc64'
  319. endianness = 'big'
  320. elif cpu.startswith('sparc') or cpu == 'sun4u':
  321. canonical_cpu = 'sparc'
  322. endianness = 'big'
  323. elif cpu.startswith('arm'):
  324. canonical_cpu = 'arm'
  325. endianness = 'big' if cpu.startswith(('armeb', 'armbe')) else 'little'
  326. elif cpu in ('mips', 'mipsel'):
  327. canonical_cpu = 'mips32'
  328. endianness = 'little' if 'el' in cpu else 'big'
  329. elif cpu in ('mips64', 'mips64el'):
  330. canonical_cpu = 'mips64'
  331. endianness = 'little' if 'el' in cpu else 'big'
  332. elif cpu.startswith('aarch64'):
  333. canonical_cpu = 'aarch64'
  334. endianness = 'little'
  335. else:
  336. die('Unknown CPU type: %s' % cpu)
  337. return namespace(
  338. alias=triplet,
  339. cpu=CPU(canonical_cpu),
  340. bitness=CPU_bitness[canonical_cpu],
  341. kernel=Kernel(canonical_kernel),
  342. os=OS(canonical_os),
  343. endianness=Endianness(endianness),
  344. raw_cpu=cpu,
  345. raw_os=os,
  346. # Toolchains, most notably for cross compilation may use cpu-os
  347. # prefixes.
  348. toolchain='%s-%s' % (cpu, os),
  349. )
  350. @imports('subprocess')
  351. def config_sub(shell, triplet):
  352. config_sub = os.path.join(os.path.dirname(__file__), '..',
  353. 'autoconf', 'config.sub')
  354. return subprocess.check_output([shell, config_sub, triplet]).strip()
  355. @depends('--host', shell)
  356. @checking('for host system type', lambda h: h.alias)
  357. @imports('subprocess')
  358. def host(value, shell):
  359. if not value:
  360. config_guess = os.path.join(os.path.dirname(__file__), '..',
  361. 'autoconf', 'config.guess')
  362. host = subprocess.check_output([shell, config_guess]).strip()
  363. else:
  364. host = value[0]
  365. return split_triplet(config_sub(shell, host))
  366. @depends('--target', host, shell)
  367. @checking('for target system type', lambda t: t.alias)
  368. def target(value, host, shell):
  369. if not value:
  370. return host
  371. return split_triplet(config_sub(shell, value[0]))
  372. @depends(host, target)
  373. @checking('whether cross compiling')
  374. def cross_compiling(host, target):
  375. return host != target
  376. set_config('CROSS_COMPILE', cross_compiling)
  377. set_define('CROSS_COMPILE', cross_compiling)
  378. add_old_configure_assignment('CROSS_COMPILE', cross_compiling)
  379. @depends(target)
  380. def have_64_bit(target):
  381. if target.bitness == 64:
  382. return True
  383. set_config('HAVE_64BIT_BUILD', have_64_bit)
  384. set_define('HAVE_64BIT_BUILD', have_64_bit)
  385. add_old_configure_assignment('HAVE_64BIT_BUILD', have_64_bit)
  386. # Autoconf needs these set
  387. @depends(host)
  388. def host_for_old_configure(host):
  389. return '--host=%s' % host.alias
  390. add_old_configure_arg(host_for_old_configure)
  391. @depends(host, target)
  392. def target_for_old_configure(host, target):
  393. target_alias = target.alias
  394. # old-configure does plenty of tests against $target and $target_os
  395. # and expects darwin for iOS, so make it happy.
  396. if target.os == 'iOS':
  397. target_alias = target_alias.replace('-ios', '-darwin')
  398. return '--target=%s' % target_alias
  399. add_old_configure_arg(target_for_old_configure)
  400. # These variables are for compatibility with the current moz.builds and
  401. # old-configure. Eventually, we'll want to canonicalize better.
  402. @depends(target)
  403. def target_variables(target):
  404. if target.kernel == 'kFreeBSD':
  405. os_target = 'GNU/kFreeBSD'
  406. os_arch = 'GNU_kFreeBSD'
  407. elif target.kernel == 'Darwin' or (target.kernel == 'Linux' and
  408. target.os == 'GNU'):
  409. os_target = target.kernel
  410. os_arch = target.kernel
  411. else:
  412. os_target = target.os
  413. os_arch = target.kernel
  414. if target.kernel == 'Darwin' and target.cpu == 'x86':
  415. os_test = 'i386'
  416. else:
  417. os_test = target.raw_cpu
  418. return namespace(
  419. OS_TARGET=os_target,
  420. OS_ARCH=os_arch,
  421. OS_TEST=os_test,
  422. INTEL_ARCHITECTURE=target.cpu in ('x86', 'x86_64') or None,
  423. )
  424. set_config('OS_TARGET', delayed_getattr(target_variables, 'OS_TARGET'))
  425. add_old_configure_assignment('OS_TARGET',
  426. delayed_getattr(target_variables, 'OS_TARGET'))
  427. set_config('OS_ARCH', delayed_getattr(target_variables, 'OS_ARCH'))
  428. add_old_configure_assignment('OS_ARCH',
  429. delayed_getattr(target_variables, 'OS_ARCH'))
  430. set_config('OS_TEST', delayed_getattr(target_variables, 'OS_TEST'))
  431. add_old_configure_assignment('OS_TEST',
  432. delayed_getattr(target_variables, 'OS_TEST'))
  433. set_config('CPU_ARCH', delayed_getattr(target, 'cpu'))
  434. add_old_configure_assignment('CPU_ARCH', delayed_getattr(target, 'cpu'))
  435. set_config('INTEL_ARCHITECTURE', delayed_getattr(target_variables,
  436. 'INTEL_ARCHITECTURE'))
  437. set_config('TARGET_CPU', delayed_getattr(target, 'raw_cpu'))
  438. set_config('TARGET_OS', delayed_getattr(target, 'raw_os'))
  439. @depends(host)
  440. def host_variables(host):
  441. if host.kernel == 'kFreeBSD':
  442. os_arch = 'GNU_kFreeBSD'
  443. else:
  444. os_arch = host.kernel
  445. return namespace(
  446. HOST_OS_ARCH=os_arch,
  447. )
  448. set_config('HOST_OS_ARCH', delayed_getattr(host_variables, 'HOST_OS_ARCH'))
  449. add_old_configure_assignment('HOST_OS_ARCH',
  450. delayed_getattr(host_variables, 'HOST_OS_ARCH'))
  451. @depends(target)
  452. def target_is_windows(target):
  453. if target.kernel == 'WINNT':
  454. return True
  455. set_define('_WINDOWS', target_is_windows)
  456. set_define('WIN32', target_is_windows)
  457. set_define('XP_WIN', target_is_windows)
  458. set_define('XP_WIN32', target_is_windows)
  459. @depends(target)
  460. def target_is_unix(target):
  461. if target.kernel != 'WINNT':
  462. return True
  463. set_define('XP_UNIX', target_is_unix)
  464. @depends(target)
  465. def target_is_linux(target):
  466. if target.kernel == 'Linux':
  467. return True
  468. set_define('XP_LINUX', target_is_linux)
  469. @depends(target)
  470. def target_is_solaris(target):
  471. if target.kernel == 'SunOS':
  472. return True
  473. set_define('XP_SOLARIS', target_is_solaris)
  474. @depends(target)
  475. def target_is_sparc(target):
  476. if target.cpu == 'sparc':
  477. return True
  478. set_define('SPARC', target_is_sparc)
  479. @depends(target)
  480. def target_is_sparc64(target):
  481. if target.cpu == 'sparc64':
  482. return True
  483. set_define('SPARC64', target_is_sparc64)
  484. # The application/project to build
  485. # ==============================================================
  486. option('--enable-application', nargs=1, env='MOZ_BUILD_APP',
  487. help='Application to build. Same as --enable-project.')
  488. @depends('--enable-application', '--help')
  489. def application(app, help):
  490. if app:
  491. return app
  492. imply_option('--enable-project', application)
  493. @depends(check_build_environment, '--help')
  494. def default_project(build_env, help):
  495. if build_env.topobjdir.endswith('/js/src'):
  496. return 'js'
  497. return 'application/xulrunner'
  498. option('--enable-project', nargs=1, default=default_project,
  499. help='Project to build')
  500. option('--with-external-source-dir', env='EXTERNAL_SOURCE_DIR', nargs=1,
  501. help='External directory containing additional build files')
  502. @depends('--enable-project', '--with-external-source-dir', check_build_environment, '--help')
  503. @imports(_from='os.path', _import='exists')
  504. def include_project_configure(project, external_source_dir, build_env, help):
  505. base_dir = build_env.topsrcdir
  506. if external_source_dir:
  507. base_dir = os.path.join(base_dir, external_source_dir[0])
  508. build_app = project[0]
  509. path_project_src_dir_root = os.path.join(base_dir, build_app, 'moz.configure')
  510. if exists(path_project_src_dir_root):
  511. return path_project_src_dir_root
  512. else:
  513. return os.path.join(build_env.topsrcdir, 'toolkit', 'moz.configure')
  514. @depends('--with-external-source-dir')
  515. def external_source_dir(value):
  516. if value:
  517. return value[0]
  518. set_config('EXTERNAL_SOURCE_DIR', external_source_dir)
  519. add_old_configure_assignment('EXTERNAL_SOURCE_DIR', external_source_dir)
  520. @depends('--enable-project', '--with-external-source-dir', check_build_environment, '--help')
  521. @imports(_from='os.path', _import='exists')
  522. def build_project(project, external_source_dir, build_env, help):
  523. if not project:
  524. die('--enable-project is required.')
  525. base_dir = build_env.topsrcdir
  526. if external_source_dir:
  527. base_dir = os.path.join(base_dir, external_source_dir[0])
  528. build_app = project[0]
  529. if not external_source_dir and build_app not in ('xulrunner', 'js'):
  530. die('Cannot find project %s', build_app)
  531. build_app_abspath = os.path.join(base_dir, build_app)
  532. if exists(build_app_abspath):
  533. return os.path.relpath(build_app_abspath, build_env.topsrcdir)
  534. else:
  535. die('Cannot find project %s', build_app)
  536. set_config('MOZ_BUILD_APP', build_project)
  537. set_define('MOZ_BUILD_APP', build_project)
  538. add_old_configure_assignment('MOZ_BUILD_APP', build_project)
  539. # set RELEASE_OR_BETA and NIGHTLY_BUILD variables depending on the cycle we're in
  540. # The logic works like this:
  541. # - if we have "a1" in GRE_MILESTONE, we're building Nightly (define NIGHTLY_BUILD)
  542. # - otherwise, if we have "a" in GRE_MILESTONE, we're building Nightly or Aurora
  543. # - otherwise, we're building Release/Beta (define RELEASE_OR_BETA)
  544. @depends(check_build_environment, '--help')
  545. @imports(_from='__builtin__', _import='open')
  546. def milestone(build_env, _):
  547. milestone_path = os.path.join(build_env.topsrcdir,
  548. 'config',
  549. 'milestone.txt')
  550. with open(milestone_path, 'r') as fh:
  551. milestone = fh.read().splitlines()[-1]
  552. is_nightly = is_release_or_beta = None
  553. if 'a1' in milestone:
  554. is_nightly = True
  555. elif 'a' not in milestone:
  556. is_release_or_beta = True
  557. return namespace(version=milestone,
  558. is_nightly=is_nightly,
  559. is_release_or_beta=is_release_or_beta)
  560. set_config('GRE_MILESTONE', delayed_getattr(milestone, 'version'))
  561. set_config('NIGHTLY_BUILD', delayed_getattr(milestone, 'is_nightly'))
  562. set_define('NIGHTLY_BUILD', delayed_getattr(milestone, 'is_nightly'))
  563. add_old_configure_assignment('NIGHTLY_BUILD',
  564. delayed_getattr(milestone, 'is_nightly'))
  565. set_config('RELEASE_OR_BETA', delayed_getattr(milestone, 'is_release_or_beta'))
  566. set_define('RELEASE_OR_BETA', delayed_getattr(milestone, 'is_release_or_beta'))
  567. add_old_configure_assignment('RELEASE_OR_BETA',
  568. delayed_getattr(milestone, 'is_release_or_beta'))
  569. # The app update channel is 'default' when not supplied. The value is used in
  570. # the application's confvars.sh (and is made available to a project specific
  571. # moz.configure).
  572. option('--enable-update-channel',
  573. nargs=1,
  574. help='Select application update channel',
  575. default='default')
  576. @depends('--enable-update-channel')
  577. def update_channel(channel):
  578. if channel[0] == '':
  579. return 'default'
  580. return channel[0].lower()
  581. set_config('MOZ_UPDATE_CHANNEL', update_channel)
  582. set_define('MOZ_UPDATE_CHANNEL', update_channel)
  583. add_old_configure_assignment('MOZ_UPDATE_CHANNEL', update_channel)
  584. # A template providing a shorthand for setting a variable. The created
  585. # option will only be settable with imply_option.
  586. # It is expected that a project-specific moz.configure will call imply_option
  587. # to set a value other than the default.
  588. # If required, the set_as_define and set_for_old_configure arguments
  589. # will additionally cause the variable to be set using set_define and
  590. # add_old_configure_assignment. util.configure would be an appropriate place for
  591. # this, but it uses add_old_configure_assignment, which is defined in this file.
  592. @template
  593. def project_flag(env=None, set_for_old_configure=False,
  594. set_as_define=False, **kwargs):
  595. if not env:
  596. configure_error("A project_flag must be passed a variable name to set.")
  597. opt = option(env=env, possible_origins=('implied',), **kwargs)
  598. @depends(opt.option)
  599. def option_implementation(value):
  600. if value:
  601. if len(value):
  602. return value
  603. return bool(value)
  604. set_config(env, option_implementation)
  605. if set_as_define:
  606. set_define(env, option_implementation)
  607. if set_for_old_configure:
  608. add_old_configure_assignment(env, option_implementation)
  609. # milestone.is_nightly corresponds to cases NIGHTLY_BUILD is set.
  610. @depends(milestone, '--help')
  611. def enabled_in_nightly(milestone, _):
  612. return milestone.is_nightly
  613. # Set the MOZ_CONFIGURE_OPTIONS variable with all the options that
  614. # were passed somehow (environment, command line, mozconfig)
  615. @depends(mozconfig_options)
  616. @imports(_from='mozbuild.shellutil', _import='quote')
  617. @imports('__sandbox__')
  618. def all_configure_options(_):
  619. result = []
  620. previous = None
  621. for option in __sandbox__._options.itervalues():
  622. # __sandbox__._options contains items for both option.name and
  623. # option.env. But it's also an OrderedDict, meaning both are
  624. # consecutive.
  625. # Also ignore OLD_CONFIGURE and MOZCONFIG because they're not
  626. # interesting.
  627. if option == previous or option.env in ('OLD_CONFIGURE', 'MOZCONFIG'):
  628. continue
  629. previous = option
  630. value = __sandbox__._value_for(option)
  631. # We only want options that were explicitly given on the command
  632. # line, the environment, or mozconfig, and that differ from the
  633. # defaults.
  634. if (value is not None and value.origin not in ('default', 'implied') and
  635. value != option.default):
  636. result.append(__sandbox__._raw_options[option])
  637. # We however always include options that are sent to old configure
  638. # because we don't know their actual defaults. (Keep the conditions
  639. # separate for ease of understanding and ease of removal)
  640. elif (option.help == 'Help missing for old configure options' and
  641. option in __sandbox__._raw_options):
  642. result.append(__sandbox__._raw_options[option])
  643. return quote(*result)
  644. set_config('MOZ_CONFIGURE_OPTIONS', all_configure_options)
  645. # This is temporary until js/src/configure and configure are merged.
  646. # Use instead of option() in js/moz.configure and more generally, for
  647. # options that are shared between configure and js/src/configure.
  648. @template
  649. def js_option(*args, **kwargs):
  650. opt = option(*args, **kwargs)
  651. @depends(opt.option, build_project)
  652. def js_option(value, build_project):
  653. if build_project != 'js':
  654. return value.format(opt.option)
  655. add_old_configure_arg(js_option)
  656. # Bug 1278542: This function is a workaround to resolve
  657. # |android_ndk_include|'s dependency on 'gonkdir.' The
  658. # actual implementation is located in b2g/moz.configure.
  659. # Remove this function as soon as 'android_ndk_include'
  660. # depends on 'target.'
  661. @depends('--help')
  662. def gonkdir(_):
  663. return None