wrap: Implement special wrap modes for use by packagers

Special wrap modes:
  nofallback: Don't download wraps for dependency() fallbacks
  nodownload: Don't download wraps for all subproject() calls

Subprojects are used for two purposes:
1. To download and build dependencies by using .wrap files if they
   are not provided by the system. This is usually expressed via
   dependency(..., fallback: ...).
2. To download and build 'copylibs' which are meant to be used by
   copying into your project. This is always done with an explicit
   subproject() call.

--wrap-mode=nofallback will never do (1)
--wrap-mode=nodownload will do neither (1) nor (2)

If you are building from a release tarball, you should be able to
safely use 'nodownload' since upstream is expected to ship all
required sources with the tarball.

If you are building from a git repository, you will want to use
'nofallback' so that any 'copylib' wraps will be download as
subprojects.

Note that these options do not affect subprojects that are git
submodules since those are only usable in git repositories, and you
almost always want to download them.
pull/1516/head
Nirbheek Chauhan 8 years ago
parent a60d688973
commit d5975cc683
  1. 2
      mesonbuild/coredata.py
  2. 9
      mesonbuild/interpreter.py
  3. 5
      mesonbuild/mesonmain.py
  4. 31
      mesonbuild/wrap/__init__.py
  5. 10
      mesonbuild/wrap/wrap.py
  6. 1
      run_unittests.py

@ -127,7 +127,7 @@ class CoreData:
self.cross_file = os.path.join(os.getcwd(), options.cross_file)
else:
self.cross_file = None
self.wrap_mode = options.wrap_mode
self.compilers = {}
self.cross_compilers = {}
self.deps = {}

@ -20,7 +20,7 @@ from . import mlog
from . import build
from . import optinterpreter
from . import compilers
from .wrap import wrap
from .wrap import wrap, WrapMode
from . import mesonlib
from .mesonlib import FileMode, Popen_safe
from .dependencies import InternalDependency, Dependency
@ -1499,7 +1499,7 @@ class Interpreter(InterpreterBase):
if dirname in self.subprojects:
return self.subprojects[dirname]
subproject_dir_abs = os.path.join(self.environment.get_source_dir(), self.subproject_dir)
r = wrap.Resolver(subproject_dir_abs)
r = wrap.Resolver(subproject_dir_abs, self.coredata.wrap_mode)
try:
resolved = r.resolve(dirname)
except RuntimeError as e:
@ -1911,6 +1911,11 @@ requirements use the version keyword argument instead.''')
return fbinfo
def dependency_fallback(self, name, kwargs):
if self.coredata.wrap_mode in (WrapMode.nofallback, WrapMode.nodownload):
mlog.log('Not looking for a fallback subproject for the dependency',
mlog.bold(name), 'because:\nAutomatic wrap-based fallback '
'dependency downloading is disabled.')
return None
dirname, varname = self.get_subproject_infos(kwargs)
# Try to execute the subproject
try:

@ -20,6 +20,7 @@ from . import build
import platform
from . import mlog, coredata
from .mesonlib import MesonException
from .wrap import WrapMode
parser = argparse.ArgumentParser()
@ -67,6 +68,10 @@ parser.add_argument('-D', action='append', dest='projectoptions', default=[],
help='Set project options.')
parser.add_argument('-v', '--version', action='version',
version=coredata.version)
# See the mesonlib.WrapMode enum for documentation
parser.add_argument('--wrap-mode', default=WrapMode.default,
type=lambda t: getattr(WrapMode, t), choices=WrapMode,
help='Special wrap mode to use')
parser.add_argument('directories', nargs='*')
class MesonApp:

@ -0,0 +1,31 @@
from enum import Enum
# Used for the --wrap-mode command-line argument
#
# Special wrap modes:
# nofallback: Don't download wraps for dependency() fallbacks
# nodownload: Don't download wraps for all subproject() calls
#
# subprojects are used for two purposes:
# 1. To download and build dependencies by using .wrap
# files if they are not provided by the system. This is
# usually expressed via dependency(..., fallback: ...).
# 2. To download and build 'copylibs' which are meant to be
# used by copying into your project. This is always done
# with an explicit subproject() call.
#
# --wrap-mode=nofallback will never do (1)
# --wrap-mode=nodownload will do neither (1) nor (2)
#
# If you are building from a release tarball, you should be
# able to safely use 'nodownload' since upstream is
# expected to ship all required sources with the tarball.
#
# If you are building from a git repository, you will want
# to use 'nofallback' so that any 'copylib' wraps will be
# download as subprojects.
#
# Note that these options do not affect subprojects that
# are git submodules since those are only usable in git
# repositories, and you almost always want to download them.
WrapMode = Enum('WrapMode', 'default nofallback nodownload')

@ -18,6 +18,7 @@ import urllib.request, os, hashlib, shutil
import subprocess
import sys
from pathlib import Path
from . import WrapMode
try:
import ssl
@ -94,7 +95,8 @@ class PackageDefinition:
return 'patch_url' in self.values
class Resolver:
def __init__(self, subdir_root):
def __init__(self, subdir_root, wrap_mode=WrapMode(1)):
self.wrap_mode = wrap_mode
self.subdir_root = subdir_root
self.cachedir = os.path.join(self.subdir_root, 'packagecache')
@ -120,6 +122,12 @@ class Resolver:
if self.resolve_git_submodule(dirname):
return packagename
# Don't download subproject data based on wrap file if requested.
# Git submodules are ok (see above)!
if self.wrap_mode is WrapMode.nodownload:
m = 'Automatic wrap-based subproject downloading is disabled'
raise RuntimeError(m)
# Check if there's a .wrap file for this subproject
fname = os.path.join(self.subdir_root, packagename + '.wrap')
if not os.path.isfile(fname):

@ -48,6 +48,7 @@ def get_fake_options(prefix):
import argparse
opts = argparse.Namespace()
opts.cross_file = None
opts.wrap_mode = None
opts.prefix = prefix
return opts

Loading…
Cancel
Save