Imported Upstream version 5.2.0.175

Former-commit-id: bb0468d0f257ff100aa895eb5fe583fb5dfbf900
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2017-06-07 13:16:24 +00:00
parent 4bdbaf4a88
commit 966bba02bb
8776 changed files with 346420 additions and 149650 deletions

52
external/bockbuild/bb vendored
View File

@@ -69,46 +69,47 @@ class Bockbuild:
def run(self):
self.name = 'bockbuild'
self.root = os.path.dirname (os.path.realpath(__file__)) # Bockbuild system root
config.protected_git_repos.append (self.root)
self.execution_root = os.getcwd()
config.absolute_root = os.path.commonprefix([self.root, self.execution_root])
self.resources = set([os.path.realpath(
os.path.join(self.root, 'packages'))]) # list of paths on where to look for packages, patches, etc.
self.build_root = os.path.join(self.root, 'builds')
self.staged_prefix = os.path.join(self.root, 'stage')
self.toolchain_root = os.path.join(self.root, 'toolchain')
self.artifact_root = os.path.join(self.root, 'artifacts')
self.package_root = os.path.join(self.root, 'distribution')
self.scratch = os.path.join(self.root, 'scratch')
self.logs = os.path.join(self.root, 'logs')
self.env_file = os.path.join(self.root, 'last-successful-build.env')
config.state_root = self.root # root path for all storage; artifacts, build I/O, cache, storage and output
config.protected_git_repos.append (self.root)
config.absolute_root = os.path.commonprefix([self.root, self.execution_root])
self.build_root = os.path.join(config.state_root, 'builds')
self.staged_prefix = os.path.join(config.state_root, 'stage')
self.toolchain_root = os.path.join(config.state_root, 'toolchain')
self.artifact_root = os.path.join(config.state_root, 'artifacts')
self.package_root = os.path.join(config.state_root, 'distribution')
self.scratch = os.path.join(config.state_root, 'scratch')
self.logs = os.path.join(config.state_root, 'logs')
self.env_file = os.path.join(config.state_root, 'last-successful-build.env')
self.source_cache = os.getenv('BOCKBUILD_SOURCE_CACHE') or os.path.realpath(
os.path.join(self.root, 'cache'))
os.path.join(config.state_root, 'cache'))
self.cpu_count = get_cpu_count()
self.host = get_host()
self.uname = backtick('uname -a')
self.full_rebuild = False
self.toolchain = []
find_git(self)
self.bockbuild_rev = git_get_revision(self, self.root)
self.bockbuild_rev = git_shortid(self, self.root)
self.profile_root = git_rootdir (self, self.execution_root)
self.profiles = find_profiles (self.profile_root)
for profile in self.profiles:
self.resources.add(profile.path)
loginit('bockbuild (%s)' % (git_shortid(self, self.root)))
loginit('bockbuild (%s)' % (self.bockbuild_rev))
info('cmd: %s' % ' '.join(sys.argv))
if len (sys.argv) < 2:
info ('Profiles in %s --' % self.git ('config --get remote.origin.url', self.profile_root)[0])
info(map (lambda x: '\t%s: %s' % (x.name, x.description), self.profiles))
finish()
finish (exit_codes.FAILURE)
global active_profile
Package.profile = active_profile = self.load_profile (sys.argv[1])
@@ -184,6 +185,9 @@ class Bockbuild:
build_list = []
stage_invalidated = False #if anything is dirty we flush the stageination path and fill it again
if self.full_rebuild:
ensure_dir (stage, purge = True)
progress('Fetching packages')
for package in packages.values():
package.build_artifact = os.path.join(
@@ -219,7 +223,7 @@ class Bockbuild:
package.deploy_requests.append (stage)
for package in packages.values():
package.start_build(arch, stage, stage)
package.start_build(arch, dest, stage)
# make artifact in scratch
# delete artifact + buildstring
with open(package.buildstring_file, 'w') as output:
@@ -298,6 +302,8 @@ class Bockbuild:
profile.process_release(self.package_root)
profile.package()
finish(exit_codes.SUCCESS)
def track_env(self):
env = active_profile.env
env.compile()
@@ -306,8 +312,6 @@ class Bockbuild:
self.root, self.profile_name) + '_env.sh'
env.write_source_script(self.env_script)
if not os.path.exists (self.env_file):
return False
self.tracked_env.extend(env.serialize())
return is_changed(self.tracked_env, self.env_file)
@@ -318,7 +322,6 @@ class Bockbuild:
fullpath = None
for i in self.resources:
candidate_fullpath = os.path.join(i, source + '.py')
trace (candidate_fullpath)
if os.path.exists(candidate_fullpath):
if fullpath is not None:
error ('Package "%s" resolved in multiple locations (search paths: %s' % (source, self.resources))
@@ -329,6 +332,7 @@ class Bockbuild:
Package.last_instance = None
trace(fullpath)
execfile(fullpath, globals())
if Package.last_instance is None:
@@ -385,8 +389,12 @@ if __name__ == "__main__":
exc_type, exc_value, exc_traceback = sys.exc_info()
error('%s (%s)' % (e, exc_type.__name__), more_output=True)
error(('%s:%s @%s\t\t"%s"' % p for p in traceback.extract_tb(
exc_traceback)[-5:]), more_output=True)
exc_traceback)[-5:]))
except KeyboardInterrupt:
error('Interrupted.')
finally:
finish()
if config.exit_code == exit_codes.NOTSET:
print 'spurious sys.exit() call'
if config.exit_code == exit_codes.SUCCESS:
logprint('\n** %s **\n' % 'Goodbye!', bcolors.BOLD)
sys.exit (config.exit_code)

View File

@@ -69,46 +69,47 @@ class Bockbuild:
def run(self):
self.name = 'bockbuild'
self.root = os.path.dirname (os.path.realpath(__file__)) # Bockbuild system root
config.protected_git_repos.append (self.root)
self.execution_root = os.getcwd()
config.absolute_root = os.path.commonprefix([self.root, self.execution_root])
self.resources = set([os.path.realpath(
os.path.join(self.root, 'packages'))]) # list of paths on where to look for packages, patches, etc.
self.build_root = os.path.join(self.root, 'builds')
self.staged_prefix = os.path.join(self.root, 'stage')
self.toolchain_root = os.path.join(self.root, 'toolchain')
self.artifact_root = os.path.join(self.root, 'artifacts')
self.package_root = os.path.join(self.root, 'distribution')
self.scratch = os.path.join(self.root, 'scratch')
self.logs = os.path.join(self.root, 'logs')
self.env_file = os.path.join(self.root, 'last-successful-build.env')
config.state_root = self.root # root path for all storage; artifacts, build I/O, cache, storage and output
config.protected_git_repos.append (self.root)
config.absolute_root = os.path.commonprefix([self.root, self.execution_root])
self.build_root = os.path.join(config.state_root, 'builds')
self.staged_prefix = os.path.join(config.state_root, 'stage')
self.toolchain_root = os.path.join(config.state_root, 'toolchain')
self.artifact_root = os.path.join(config.state_root, 'artifacts')
self.package_root = os.path.join(config.state_root, 'distribution')
self.scratch = os.path.join(config.state_root, 'scratch')
self.logs = os.path.join(config.state_root, 'logs')
self.env_file = os.path.join(config.state_root, 'last-successful-build.env')
self.source_cache = os.getenv('BOCKBUILD_SOURCE_CACHE') or os.path.realpath(
os.path.join(self.root, 'cache'))
os.path.join(config.state_root, 'cache'))
self.cpu_count = get_cpu_count()
self.host = get_host()
self.uname = backtick('uname -a')
self.full_rebuild = False
self.toolchain = []
find_git(self)
self.bockbuild_rev = git_get_revision(self, self.root)
self.bockbuild_rev = git_shortid(self, self.root)
self.profile_root = git_rootdir (self, self.execution_root)
self.profiles = find_profiles (self.profile_root)
for profile in self.profiles:
self.resources.add(profile.path)
loginit('bockbuild (%s)' % (git_shortid(self, self.root)))
loginit('bockbuild (%s)' % (self.bockbuild_rev))
info('cmd: %s' % ' '.join(sys.argv))
if len (sys.argv) < 2:
info ('Profiles in %s --' % self.git ('config --get remote.origin.url', self.profile_root)[0])
info(map (lambda x: '\t%s: %s' % (x.name, x.description), self.profiles))
finish()
finish (exit_codes.FAILURE)
global active_profile
Package.profile = active_profile = self.load_profile (sys.argv[1])
@@ -184,6 +185,9 @@ class Bockbuild:
build_list = []
stage_invalidated = False #if anything is dirty we flush the stageination path and fill it again
if self.full_rebuild:
ensure_dir (stage, purge = True)
progress('Fetching packages')
for package in packages.values():
package.build_artifact = os.path.join(
@@ -219,7 +223,7 @@ class Bockbuild:
package.deploy_requests.append (stage)
for package in packages.values():
package.start_build(arch, stage, stage)
package.start_build(arch, dest, stage)
# make artifact in scratch
# delete artifact + buildstring
with open(package.buildstring_file, 'w') as output:
@@ -298,6 +302,8 @@ class Bockbuild:
profile.process_release(self.package_root)
profile.package()
finish(exit_codes.SUCCESS)
def track_env(self):
env = active_profile.env
env.compile()
@@ -306,8 +312,6 @@ class Bockbuild:
self.root, self.profile_name) + '_env.sh'
env.write_source_script(self.env_script)
if not os.path.exists (self.env_file):
return False
self.tracked_env.extend(env.serialize())
return is_changed(self.tracked_env, self.env_file)
@@ -318,7 +322,6 @@ class Bockbuild:
fullpath = None
for i in self.resources:
candidate_fullpath = os.path.join(i, source + '.py')
trace (candidate_fullpath)
if os.path.exists(candidate_fullpath):
if fullpath is not None:
error ('Package "%s" resolved in multiple locations (search paths: %s' % (source, self.resources))
@@ -329,6 +332,7 @@ class Bockbuild:
Package.last_instance = None
trace(fullpath)
execfile(fullpath, globals())
if Package.last_instance is None:
@@ -385,8 +389,12 @@ if __name__ == "__main__":
exc_type, exc_value, exc_traceback = sys.exc_info()
error('%s (%s)' % (e, exc_type.__name__), more_output=True)
error(('%s:%s @%s\t\t"%s"' % p for p in traceback.extract_tb(
exc_traceback)[-5:]), more_output=True)
exc_traceback)[-5:]))
except KeyboardInterrupt:
error('Interrupted.')
finally:
finish()
if config.exit_code == exit_codes.NOTSET:
print 'spurious sys.exit() call'
if config.exit_code == exit_codes.SUCCESS:
logprint('\n** %s **\n' % 'Goodbye!', bcolors.BOLD)
sys.exit (config.exit_code)

View File

@@ -5,6 +5,7 @@ from util.util import *
from unixprofile import UnixProfile
from profile import Profile
import stat
from distutils.version import LooseVersion, StrictVersion
# staging helper functions
@@ -56,20 +57,39 @@ class DarwinProfile (UnixProfile):
'gtk-doc'
]
def use_Xcode(self, min_version='5.1.1', xcodebuild_version_prefix='Xcode '):
xcrun_cc_str = backtick('xcrun cc --version')[0]
cc_str = backtick('cc --version')[0]
if xcrun_cc_str != cc_str:
error('Multiple "cc" compiler versions found. (XCode-selected: "%s";"cc" at $PATH: "%s"' % (
xcrun_cc_str, cc_str))
xcodebuild_str = backtick('xcodebuild -version')[0] # output: "Xcode X.X.X"
if not xcodebuild_str.startswith(xcodebuild_version_prefix):
error('Unexpected output from "xcodebuild" (first line: "%s"' % (xcodebuild_str))
xcode_version = StrictVersion(xcodebuild_str[len(xcodebuild_version_prefix):])
if xcode_version < StrictVersion(min_version):
error('Xcode version required %s, installed %s' % (min_version, xcode_version))
self.env.set('xcode_version', str(xcode_version))
return xcode_version
def attach (self, bockbuild):
UnixProfile.attach (self, bockbuild)
bockbuild.toolchain = list (DarwinProfile.default_toolchain)
self.name = 'darwin'
xcode_version = backtick('xcodebuild -version')[0]
self.env.set('xcode_version', xcode_version)
osx_sdk = backtick('xcrun --show-sdk-path')[0]
self.env.set('osx_sdk', osx_sdk)
xcode_version = self.use_Xcode ()
osx_sdk = backtick('xcrun --show-sdk-path')[0]
if not os.path.exists(osx_sdk):
error('Mac OS X SDK not found under %s' % osx_sdk)
info('%s, %s' % (xcode_version, os.path.basename(osx_sdk)))
info('Using Xcode %s, SDK %s' % (xcode_version, os.path.basename(osx_sdk)))
if xcode_version >= '8.0':
# based on https://github.com/Homebrew/brew/pull/970. This applies to XCode 8, OS X 10.11 and the 10.12 SDK. The following symbols will be unresolved
# when running binaries on a system of lower version than 10.12.
map(lambda t : self.configure_flags.append ('ac_cv_func_%s=no' % t), 'basename_r clock_getres clock_gettime clock_settime dirname_r getentropy mkostemp mkostemps'.split(' '))
self.gcc_flags.extend([
'-D_XOPEN_SOURCE',
@@ -127,6 +147,8 @@ class DarwinProfile (UnixProfile):
package.local_configure_flags.extend(
['--cache-file=%s' % configure_cache])
package.local_configure_flags.extend(self.configure_flags)
if package.name in self.debug_info:
package.local_gcc_flags.extend(['-g'])

View File

@@ -37,7 +37,7 @@ class Environment:
expand_macros(self, self._profile)
def write_source_script(self, filename):
trace (filename)
envscript = '#!/bin/sh\n'
for k in self.get_names():
@@ -45,6 +45,7 @@ class Environment:
with open(filename, 'w') as f:
f.write(envscript)
trace(envscript)
os.chmod(filename, 0o755)

View File

@@ -95,6 +95,7 @@ class Package:
self.__dict__[k] = v
self.makeinstall = self.makeinstall or 'make install DESTDIR=%{stage_root}'
self.fetched = False
def extract_organization(self, source):
if (not "git" in source) or ("http" in source):
@@ -140,6 +141,9 @@ class Package:
@retry
def fetch(self, dest):
if self.fetched and os.path.lexists(dest):
return
scratch = self.profile.bockbuild.scratch
resources = self.profile.bockbuild.resources
source_cache_dir = self.profile.bockbuild.source_cache
@@ -148,11 +152,16 @@ class Package:
scratch_workspace = os.path.join(scratch, '%s.workspace' % self.name)
self.rm_if_exists(scratch_workspace)
if os.path.exists(dest):
shutil.move(dest, scratch_workspace)
if os.path.lexists(dest):
if os.path.islink(dest):
delete(dest)
elif os.path.isdir(dest):
shutil.move(dest, scratch_workspace)
else:
error ('Unexpected workspace found at %s' % dest)
def checkout(self, source_url, cache_dir, workspace_dir):
self.is_local = os.path.isdir (source_url)
def clean_git_workspace(dir):
trace('Cleaning git workspace: ' + self.name)
self.git('reset --hard', dir, hazard = True)
@@ -171,7 +180,7 @@ class Package:
self.rm(workspace_dir)
progress('Cloning git repo: %s' % source_url)
self.git('clone --mirror %s %s' %
(source_url, cache_dir), scratch)
(source_url, cache_dir), self.profile.bockbuild.root)
def update_cache():
trace('Updating cache: ' + cache_dir)
@@ -181,7 +190,7 @@ class Package:
self.git('fetch origin %s' % self.git_branch, cache_dir)
def create_workspace():
self.git('clone --local --shared %s %s' %
self.git('clone --local --shared --recursive %s %s' %
(cache_dir, workspace_dir), cache_dir)
def update_workspace():
@@ -221,6 +230,7 @@ class Package:
if target_revision and (current_revision != target_revision):
self.git('reset --hard %s' %
target_revision, workspace_dir, hazard = True)
self.git('submodule update --recursive', workspace_dir)
current_revision = git_get_revision(self, workspace_dir)
@@ -244,25 +254,28 @@ class Package:
self.buildstring = ['%s <%s>' % (str, source_url)]
if self.is_local:
link_dir (workspace_dir, source_url)
if git_is_dirty (self, workspace_dir):
self.rm_if_exists(workspace_dir)
work_committed = False
if git_is_dirty (self, source_url):
if self.profile.bockbuild.cmd_options.release_build:
error ('Release builds cannot have uncommitted local changes!')
else:
info ('The repository is dirty, your changes will be committed.')
bockbuild_commit_msg = 'Bockbuild'
top_commit_msg = git_get_commit_msg (self, workspace_dir)
bockbuild_commit_msg = '"WIP (auto-committed by bockbuild)"'
top_commit_msg = git_get_commit_msg (self, source_url)
if top_commit_msg == bockbuild_commit_msg:
self.git ('commit -a --allow-empty --amend -m %s' % bockbuild_commit_msg, workspace_dir)
self.git ('commit -a --allow-empty --amend -m', source_url, options = [bockbuild_commit_msg])
else:
self.git('commit -a --allow-empty -m %s' % bockbuild_commit_msg, workspace_dir)
self.git('commit -a --allow-empty -m', source_url, options = [bockbuild_commit_msg])
work_committed = True
self.shadow_copy (source_url, workspace_dir)
if work_committed:
self.git ('reset HEAD~1', source_url)
else:
if os.path.exists(cache_dir):
update_cache()
else:
create_cache()
if os.path.exists(workspace_dir):
if self.dont_clean == True: # previous workspace was left dirty, delete
clean_git_workspace(workspace_dir)
@@ -289,13 +302,18 @@ class Package:
pass
def create_workspace(dir):
self.extract_archive(cache_dest, scratch, validate_only=False)
expected_path = os.path.join(scratch, self.source_dir_name)
if not os.path.exists(expected_path):
error('Archive %s was extracted but not found at workspace path %s' % (
cache_dest, expected_path))
if expected_path != dir:
shutil.move(expected_path, dir)
filetype = get_filetype(cache_dest).lower()
if filetype.startswith(('gzip', 'xz', 'zip', 'bzip2')):
self.extract_archive(cache_dest, scratch, validate_only=False)
expected_path = os.path.join(scratch, self.source_dir_name)
if not os.path.exists(expected_path):
error('Archive %s was extracted but not found at workspace path %s' % (
cache_dest, expected_path))
if expected_path != dir:
shutil.move(expected_path, dir)
else: # create the directory and just place the downloaded file inside
ensure_dir(scratch_workspace)
shutil.copy(cache_dest, scratch_workspace)
def update_workspace():
pass
@@ -375,7 +393,11 @@ class Package:
resolved_source = scratch_workspace
elif source.startswith(('git://', 'file://', 'ssh://')) or source.endswith('.git') or (os.path.isdir(source) and git_isrootdir (self, source)):
cache = get_git_cache_path()
if os.path.isdir(source):
self.is_local = True
cache = None
else:
cache = get_git_cache_path()
clean_func = checkout(
self, source, cache, scratch_workspace)
resolved_source = scratch_workspace
@@ -430,6 +452,10 @@ class Package:
self.workspace = dest
shutil.move(scratch_workspace, self.workspace)
if not os.path.exists(self.workspace):
error ('Workspace was not created')
self.fetched = True
def request_build(self, reason):
self.needs_build = reason
@@ -463,7 +489,7 @@ class Package:
self.rm_if_exists(workspace_x64)
shutil.move(workspace, workspace_x86)
shutil.copytree(workspace_x86, workspace_x64)
self.shadow_copy(workspace_x86, workspace_x64)
self.link(workspace_x86, workspace)
package_stage = self.do_build(
@@ -491,10 +517,6 @@ class Package:
self.make_artifact(package_stage, build_artifact)
for target in self.deploy_requests:
self.deploy_package(build_artifact, target)
if self.is_local:
verbose ('Cleaning local repo')
self.git ('reset --hard', workspace)
def deploy_package(self, artifact, dest):
trace('Deploying (%s -> %s)' %
@@ -582,7 +604,7 @@ class Package:
except (Exception, KeyboardInterrupt) as e:
self.rm_if_exists(self.stage_root)
if isinstance(e, CommandException):
if os.path.exists(self.workspace) and not self.is_local:
if os.path.exists(self.workspace):
for path in self.aux_files:
self.rm_if_exists(path)
problem_dir = os.path.join(
@@ -619,6 +641,9 @@ class Package:
if not isinstance(command, str):
error('command arg must be a string: %s' % repr(command))
if not os.path.isdir(cwd):
error('Directory does not exist: %s' % cwd)
try:
env_command = '%s %s' % (
self.build_env, expand_macros(command, self))
@@ -775,6 +800,38 @@ class Package:
else:
warn("lipo: 32-bit version of file %s not found" % file)
#creates a deep hardlink copy of a directory
def shadow_copy (self, source, dest, exclude_git = False):
trace ('shadow_copy %s %s' % (source , dest))
if os.path.exists(dest):
error ('Destination directory must not exist')
# Bockbuild state may be under the directory if we are copying a local workspace. Avoid recursive copying
stateroot_parent = os.path.dirname (config.state_root)
stateroot_name = os.path.basename (config.state_root)
stateroot_found = False
if not os.path.commonprefix ([source, config.state_root]) == source:
stateroot_found = True
for root, subdirs, filelist in os.walk (source):
relpath = os.path.relpath(root, source) # e.g. 'lib/mystuff'
destpath = os.path.join(dest, relpath)
os.makedirs(destpath)
if exclude_git:
subdirs[:] = [dir for dir in subdirs if dir != '.git']
if not stateroot_found and root == stateroot_parent:
subdirs [:] = [dir for dir in subdirs if dir != stateroot_name]
stateroot_found = True
for file in filelist:
fullpath = os.path.join (root, file)
if os.path.islink(fullpath):
target = os.path.join(os.path.dirname(fullpath), os.readlink(fullpath))
if not os.path.exists(fullpath) or os.path.commonprefix ([config.state_root, target]) == config.state_root:
break
os.link (fullpath, os.path.join (destpath, file))
trace ('shadow_copy done')
def copy_side_by_side(self, src_dir, dest_dir, bin_subdir, suffix, orig_suffix=None):
def add_suffix(filename, sfx):
fileparts = filename.split('.', 1)

View File

@@ -1,5 +1,6 @@
from profile import Profile
from bockbuild.environment import Environment
from bockbuild.util.util import *
class UnixProfile (Profile):
@@ -13,7 +14,9 @@ class UnixProfile (Profile):
self.gcc_flags = ['-I%s/include' % self.staged_prefix]
self.ld_flags = ['-L%s/lib' % self.staged_prefix]
self.configure_flags = []
self.env.set('bockbuild version', git_shortid(bockbuild, bockbuild.root))
self.env.set('BUILD_PREFIX', '%{prefix}')
self.env.set('PATH', ':',

View File

@@ -27,6 +27,10 @@ class bcolors:
BOLD = '\033[1m'
UNDERLINE = '\033[4m'
class exit_codes:
NOTSET = -1
SUCCESS = 0
FAILURE = 1
class config:
trace = False
@@ -38,7 +42,8 @@ class config:
verbose = False
protected_git_repos = [] # we do not allow modifying behavior on our profile repo or bockbuild repo.
absolute_root = None # there is no file resolution beneath this path. Displayed paths are shortened by omitting this segment.
state_root = None
exit_code = exit_codes.NOTSET
class CommandException (Exception): # shell command failure
@@ -116,8 +121,8 @@ def loginit(message):
Logger.monkeywrench = True
elif sys.stdout.isatty():
Logger.print_color = True
logprint('** %s **' % message, bcolors.BOLD)
print
logprint('** %s **' % message, bcolors.BOLD)
print
def colorprint(message, color):
@@ -183,6 +188,10 @@ def warn(message):
message = '%s %s' % ('(bockbuild warning)', message)
logprint(message, bcolors.FAIL, header=get_caller())
def finish (exit_code):
if exit_code > config.exit_code:
config.exit_code = exit_code
sys.exit(config.exit_code)
def error(message, more_output=False):
config.trace = False
@@ -190,12 +199,7 @@ def error(message, more_output=False):
message = '%s %s' % ('(bockbuild error)', message)
logprint(message, bcolors.FAIL, header=get_caller(), summary=True)
if not more_output:
sys.exit(255)
def finish():
logprint('\n** %s **\n' % 'Goodbye!', bcolors.BOLD)
sys.exit(0)
finish(exit_codes.FAILURE)
def trace(message, skip=0):
if config.trace == False:
@@ -206,7 +210,7 @@ def trace(message, skip=0):
if config.filter is not None and config.filter not in caller:
return
logprint(message, bcolors.FAIL, summary=True, header=caller, trace=True)
logprint(message, bcolors.FAIL, summary=False, header=caller, trace=True)
def test(func):
@@ -325,6 +329,15 @@ def which(program):
return None
def parse_rootdir(result, cwd):
# http://stackoverflow.com/a/18339166
if os.path.basename(result) == '.git': # normal repo
return os.path.dirname(result)
elif result == '.':
return cwd
else:
return result
def find_git(self, echo=False):
git_bin = which('git')
@@ -332,14 +345,45 @@ def find_git(self, echo=False):
error('git not found in PATH')
@retry
def git_func(self, args, cwd, hazard = False):
def git_operation(self, args, cwd, hazard = False, allow_fail = False, singleline_output = False, options = None, allow_nonrootdir = False):
try:
cwd = os.path.realpath(cwd)
(exit, out, err) = run(git_bin, ['rev-parse', '--show-toplevel'], cwd)
if len(out) > 0:
root = out
else:
(exit, out, err) = run(git_bin, ['rev-parse', '--git-dir'], cwd)
root = parse_rootdir(out, cwd)
except:
raise
if root != cwd and not allow_nonrootdir:
error ('Git operations allowed only on the root directory of the repo (root: %s cwd: %s)' % (root, cwd))
if hazard:
root = git_rootdir (self, cwd)
assert_modifiable_repo (root)
(exit, out, err) = run(git_bin, args.split(' '), cwd)
return out.split('\n')
try:
fullargs = args.split(' ')
if options:
if not isinstance(options, list):
error ('options argument must be a list')
fullargs = fullargs + options
(exit, out, err) = run(git_bin, fullargs, cwd)
except CommandException:
if allow_fail:
return None
else:
raise
self.git = git_func.__get__(self, self.__class__)
lines = out.split('\n')
if singleline_output:
if len(lines) > 1:
error ('Single line output expected from git. Received the following:\n%s' % out)
else:
return lines[0]
return lines
self.git = git_operation.__get__(self, self.__class__)
self.git_bin = git_bin
@@ -360,14 +404,7 @@ def git_get_revision(self, cwd):
def git_get_branch(self, cwd):
revision = git_get_revision(self, cwd)
try:
output = self.git('symbolic-ref -q --short HEAD', cwd)
except:
return None # detached HEAD
else:
return output[0]
return self.git('symbolic-ref -q --short HEAD', cwd, allow_fail = True, singleline_output = True)
def git_is_dirty(self, cwd):
return 'dirty' in git_shortid (self, cwd)
@@ -383,17 +420,24 @@ def git_shortid(self, cwd):
if branch is None:
return short_rev
else:
return '%s-%s' % (branch, short_rev)
return '%s@%s' % (branch, short_rev)
def git_rootdir(self, cwd):
# http://stackoverflow.com/a/18339166
result = self.git('rev-parse --show-toplevel', cwd, allow_nonrootdir=True, singleline_output=True)
if len(result) > 0:
return result
else:
result = self.git('rev-parse --git-dir', cwd, allow_nonrootdir=True, singleline_output=True)
return parse_rootdir(result)
def git_isrootdir(self, cwd):
try:
root = self.git('rev-parse --show-toplevel', cwd)[0]
return root == cwd
return git_rootdir (self, cwd) == cwd
except:
return False
error('git_isrootdir')
def git_rootdir(self, cwd):
return self.git('rev-parse --show-toplevel', cwd)[0]
def git_get_commit_msg(self, cwd):
return self.git('show -s --format=%B HEAD', cwd)[0]
@@ -637,9 +681,9 @@ def run(cmd, args, cwd, env=None):
if not exit_code == 0:
raise CommandException('"%s" failed, error code %s\nstderr:\n%s' % (
cmd, exit_code, stderr), cwd=cwd)
cmd + str(args), exit_code, stderr), cwd=cwd)
return (exit_code, stdout, stderr)
return (exit_code, stdout[:-1], stderr)
def run_shell(cmd, print_cmd=False, cwd=None):

View File

@@ -188,7 +188,14 @@ class GtkPackage (GnomeGitPackage):
'patches/gtk/emit-container-add.patch',
'patches/gtk/create-accessibility-object.patch',
'patches/gtk/make-gtkpaned-emit-signals.patch'
'patches/gtk/make-gtkpaned-emit-signals.patch',
'patches/gtk/0001-A11y-Fix-dialog-accessibility.patch',
'patches/gtk/0001-A11y-Emit-the-container-add-signal-when-inserting-a-.patch',
# https://bugzilla.xamarin.com/show_bug.cgi?id=51382
# https://bugzilla.xamarin.com/show_bug.cgi?id=51375
'patches/gtk/recompute-viewport-allocation-for-overlay-scrollbars.patch'
])
def prep(self):

View File

@@ -4,7 +4,7 @@ class GtkSharp212ReleasePackage (Package):
Package.__init__(self, 'gtk-sharp',
sources=['git://github.com/mono/gtk-sharp.git'],
git_branch='gtk-sharp-2-12-branch',
revision='f092864bce996c4ac51a13281069067d1e7e6d4b',
revision='e0ce4b3210ad6a910453b25e7b49b3f249fdce9c',
override_properties={
'configure': './bootstrap-2.12 --prefix=%{package_prefix}',
}

View File

@@ -1,8 +1,18 @@
class LibJpegPackage (Package):
def __init__(self):
Package.__init__(self, 'libjpeg', '8', sources=[
'http://www.ijg.org/files/jpegsrc.v8.tar.gz'])
Package.__init__(
self,
'libjpeg',
'8',
sources=[
'http://www.ijg.org/files/jpegsrc.v8.tar.gz',
'patches/libjpeg8.patch'])
self.source_dir_name = 'jpeg-8'
def prep(self):
Package.prep(self)
for p in range(1, len(self.local_sources)):
self.sh('patch -p1 < "%{local_sources[' + str(p) + ']}"')
LibJpegPackage()

View File

@@ -1,7 +1,7 @@
class LibTiffPackage (Package):
def __init__(self):
Package.__init__(self, 'tiff', '4.0.3',
Package.__init__(self, 'tiff', '4.0.8',
configure_flags=[
],
sources=[

View File

@@ -0,0 +1,38 @@
From c0198befd34288a1c2c6ae6f2523076b8bd8b0d4 Mon Sep 17 00:00:00 2001
From: iain holmes <iain@xamarin.com>
Date: Tue, 24 Jan 2017 10:53:39 +0000
Subject: [PATCH 1/1] [A11y] Emit the container::add signal when inserting a
menu
---
gtk/gtkmenushell.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/gtk/gtkmenushell.c b/gtk/gtkmenushell.c
index a7ad7b5..cd170fe 100644
--- a/gtk/gtkmenushell.c
+++ b/gtk/gtkmenushell.c
@@ -521,6 +521,9 @@ gtk_menu_shell_real_insert (GtkMenuShell *menu_shell,
menu_shell->children = g_list_insert (menu_shell->children, child, position);
gtk_widget_set_parent (child, GTK_WIDGET (menu_shell));
+
+ // Emit the container::add signal so the accessibility system can pick it up
+ g_signal_emit_by_name (G_OBJECT (menu_shell), "add", child);
}
void
@@ -1039,6 +1042,10 @@ static void
gtk_menu_shell_add (GtkContainer *container,
GtkWidget *widget)
{
+ if (widget->parent == container) {
+ return;
+ }
+
gtk_menu_shell_append (GTK_MENU_SHELL (container), widget);
}
--
2.10.1 (Apple Git-78)

View File

@@ -0,0 +1,33 @@
From 3d3ee2f91bbcb364891e82b99e932d918c605658 Mon Sep 17 00:00:00 2001
From: iain holmes <iain@xamarin.com>
Date: Thu, 24 Nov 2016 11:30:23 +0000
Subject: [PATCH] [A11y] Fix dialog accessibility
Composite widgets like the dialog need to have their accessibility element
created before they start building themselves.
---
gtk/gtkdialog.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/gtk/gtkdialog.c b/gtk/gtkdialog.c
index a2756f6..41fc9b1 100644
--- a/gtk/gtkdialog.c
+++ b/gtk/gtkdialog.c
@@ -275,6 +275,14 @@ gtk_dialog_init (GtkDialog *dialog)
priv = GET_PRIVATE (dialog);
priv->ignore_separator = FALSE;
+ /* If we don't create the accessible now, then the accessibility subsystem
+ * will never know about vbox being added. This is a bit of a hack as
+ * every composite widget that builds itself in _init will need to do this
+ * or else it will be inaccessible, but I can't think of a better way at
+ * present
+ */
+ gtk_widget_get_accessible (GTK_WIDGET (dialog));
+
/* To avoid breaking old code that prevents destroy on delete event
* by connecting a handler, we have to have the FIRST signal
* connection on the dialog.
--
2.9.3 (Apple Git-75)

View File

@@ -0,0 +1,31 @@
commit 391fcf5868dac9aa28992cd62fae9cb104364835
Author: Cody Russell <cody@jhu.edu>
Date: Sat Jan 14 14:49:14 2017 -0600
Recompute viewport allocation when updating overlay scrollbars
https://bugzilla.xamarin.com/show_bug.cgi?id=51375
https://bugzilla.xamarin.com/show_bug.cgi?id=51382
diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c
index 3999d7d..0a2cb67 100644
--- a/gtk/gtkscrolledwindow.c
+++ b/gtk/gtkscrolledwindow.c
@@ -270,6 +270,8 @@ static void gtk_scrolled_window_get_scroll_areas (GtkScrolledWindow *scrol
GdkRectangle *hslider_rect);
static void gtk_scrolled_window_update_scrollbars (GtkScrolledWindow *scrolled_window);
+static void gtk_scrolled_window_compute_viewport_allocation (GtkScrolledWindow *scrolled_window);
+
static void gtk_scrolled_window_overlay_scrollbars_changed (GtkSettings *settings,
GParamSpec *arg,
gpointer user_data);
@@ -1391,6 +1393,8 @@ gtk_scrolled_window_update_scrollbars (GtkScrolledWindow *scrolled_window)
if (!priv->overlay_scrollbars || !gtk_widget_get_realized (widget))
return;
+ gtk_scrolled_window_compute_viewport_allocation (scrolled_window);
+
window = gtk_widget_get_window (gtk_widget_get_toplevel (widget));
window_height = gdk_window_get_height (window);

View File

@@ -0,0 +1,49 @@
diff --git a/jdmarker.c b/jdmarker.c
index f2a9cc4..2edebc2 100644
--- a/jdmarker.c
+++ b/jdmarker.c
@@ -305,7 +305,7 @@ get_sos (j_decompress_ptr cinfo)
/* Process a SOS marker */
{
INT32 length;
- int i, ci, n, c, cc;
+ int i, j, ci, n, c, cc;
jpeg_component_info * compptr;
INPUT_VARS(cinfo);
@@ -340,7 +340,11 @@ get_sos (j_decompress_ptr cinfo)
ERREXIT1(cinfo, JERR_BAD_COMPONENT_ID, cc);
id_found:
-
+ for (j = 0; j < i; j++) {
+ if (cinfo->cur_comp_info[j] == compptr) {
+ ERREXIT1(cinfo, JERR_DUP_COMPONENT_ID, cc);
+ }
+ }
cinfo->cur_comp_info[i] = compptr;
compptr->dc_tbl_no = (c >> 4) & 15;
compptr->ac_tbl_no = (c ) & 15;
@@ -480,7 +484,9 @@ get_dht (j_decompress_ptr cinfo)
*htblptr = jpeg_alloc_huff_table((j_common_ptr) cinfo);
MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
- MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
+ MEMCOPY((*htblptr)->huffval, huffval, count);
+
+ MEMZERO((*htblptr)->huffval + count, SIZEOF( (*htblptr)->huffval) - count);
}
if (length != 0)
diff --git a/jerror.h b/jerror.h
index 1cfb2b1..4007c49 100644
--- a/jerror.h
+++ b/jerror.h
@@ -77,6 +77,7 @@ JMESSAGE(JERR_DAC_INDEX, "Bogus DAC index %d")
JMESSAGE(JERR_DAC_VALUE, "Bogus DAC value 0x%x")
JMESSAGE(JERR_DHT_INDEX, "Bogus DHT index %d")
JMESSAGE(JERR_DQT_INDEX, "Bogus DQT index %d")
+JMESSAGE(JERR_DUP_COMPONENT_ID, "Duplicate component ID")
JMESSAGE(JERR_EMPTY_IMAGE, "Empty JPEG image (DNL not supported)")
JMESSAGE(JERR_EMS_READ, "Read from EMS failed")
JMESSAGE(JERR_EMS_WRITE, "Write to EMS failed")

View File

@@ -1,4 +1,3 @@
Package('xz', '5.0.4', sources=[
'http://tukaani.org/xz/xz-%{version}.tar.bz2'],
override_properties={'build_dependency': True}
)
'http://tukaani.org/xz/xz-%{version}.tar.bz2'], configure_flags = ['--disable-nls'])