<commit_before># Copyright (C) 2006, <NAME>
# See http://0install.net/0compile.html

import sys, os, __main__, time, shutil, glob, codecs, subprocess
from os.path import join
from logging import info
from xml.dom import minidom, XMLNS_NAMESPACE
from optparse import OptionParser

from support import *

def env(name, value):
	os.environ[name] = value
	print "%s=%s" % (name, value)

def do_env_binding(binding, path):
	env(binding.name, binding.get_value(path, os.environ.get(binding.name, None)))

def do_build_internal(options, args):
	"""build-internal"""
	# If a sandbox is being used, we're in it now.
	import getpass, socket, time

	buildenv = BuildEnv()
	sels = buildenv.get_selections()

	builddir = os.path.realpath('build')
	ensure_dir(buildenv.metadir)

	build_env_xml = join(buildenv.metadir, 'build-environment.xml')

	buildenv_doc = buildenv.get_selections().toDOM()

	# Create build-environment.xml file
	root = buildenv_doc.documentElement
	info = buildenv_doc.createElementNS(XMLNS_0COMPILE, 'build-info')
	root.appendChild(info)
	info.setAttributeNS(None, 'time', time.strftime('%Y-%m-%d %H:%M').strip())
	info.setAttributeNS(None, 'host', socket.getfqdn())
	info.setAttributeNS(None, 'user', getpass.getuser())
	uname = os.uname()
	info.setAttributeNS(None, 'arch', '%s-%s' % (uname[0], uname[4]))
	stream = file(build_env_xml, 'w')
	buildenv_doc.writexml(stream, addindent="  ", newl="\n")
	stream.close()

	# Create local binary interface file
	src_iface = iface_cache.get_interface(buildenv.interface)
	src_impl = buildenv.chosen_impl(buildenv.interface)
	write_sample_interface(buildenv, src_iface, src_impl)

	# Check 0compile is new enough
	min_version = parse_version(src_impl.attrs.get(XMLNS_0COMPILE + ' min-version', None))
	if min_version and min_version > parse_version(__main__.version):
		raise SafeException("%s-%s requires 0compile >= %s, but we are only version %s" %
				(src_iface.get_name(), src_impl.version, format_version(min_version), __main__.version))

	# Create the patch
	patch_file = join(buildenv.metadir, 'from-%s.patch' % src_impl.version)
	if buildenv.user_srcdir:
		# (ignore errors; will already be shown on stderr)
		os.system("diff -urN '%s' src > %s" %
			(buildenv.orig_srcdir.replace('\\', '\\\\').replace("'", "\\'"),
			 patch_file))
		if os.path.getsize(patch_file) == 0:
			os.unlink(patch_file)
	elif os.path.exists(patch_file):
		os.unlink(patch_file)

	env('BUILDDIR', builddir)
	env('DISTDIR', buildenv.distdir)
	env('SRCDIR', buildenv.user_srcdir or buildenv.orig_srcdir)
	os.chdir(builddir)
	print "cd", builddir

	for needed_iface in sels.selections:
		impl = buildenv.chosen_impl(needed_iface)
		assert impl
		for dep in impl.dependencies:
			dep_iface = sels.selections[dep.interface]
			for b in dep.bindings:
				if isinstance(b, EnvironmentBinding):
					dep_impl = buildenv.chosen_impl(dep.interface)
					do_env_binding(b, lookup(dep_impl.id))

	mappings = []
	for impl in sels.selections.values():
		new_mappings = impl.attrs.get(XMLNS_0COMPILE + ' lib-mappings', '')
		if new_mappings:
			new_mappings = new_mappings.split(' ')
			for mapping in new_mappings:
				assert ':' in mapping, "lib-mappings missing ':' in '%s' from '%s'" % (mapping, impl.feed)
				name, major_version = mapping.split(':', 1)
				assert '/' not in mapping, "lib-mappings '%s' contains a / in the version number (from '%s')!" % (mapping, impl.feed)
				mappings.append((name, major_version))
	
	if mappings:
		set_up_mappings(mappings)

	# Some programs want to put temporary build files in the source directory.
	# Make a copy of the source if needed.
	dup_src_type = src_impl.attrs.get(XMLNS_0COMPILE + ' dup-src', None)
	if dup_src_type == 'true':
		dup_src(shutil.copy2)
		env('SRCDIR', builddir)
	elif dup_src_type:
		raise Exception("Unknown dup-src value '%s'" % dup_src_type)

	if options.shell:
		spawn_and_check(find_in_path('sh'), [])
	else:
		command = src_impl.attrs[XMLNS_0COMPILE + ' command']

		# Remove any existing log files
		for log in ['build.log', 'build-success.log', 'build-failure.log']:
			if os.path.exists(log):
				os.unlink(log)

		# Run the command, copying output to a new log
		log = file('build.log', 'w')
		try:
			print >>log, "Build log for %s-%s" % (src_iface.get_name(),
							      src_impl.version)
			print >>log, "\nBuilt using 0compile-%s" % __main__.version<commit_msg>Intelligent handling of legacy PKG_CONFIG_PATH dirs<commit_after># Copyright (C) 2006, <NAME>
# See http://0install.net/0compile.html

import sys, os, __main__, time, shutil, glob, codecs, subprocess
from os.path import join
from logging import info
from xml.dom import minidom, XMLNS_NAMESPACE
from optparse import OptionParser

from support import *

# If we have to modify any pkg-config files, we put the new versions in $TMPDIR/PKG_CONFIG_OVERRIDES
PKG_CONFIG_OVERRIDES = 'pkg-config-overrides'

def env(name, value):
	os.environ[name] = value
	print "%s=%s" % (name, value)

def do_env_binding(binding, path):
	env(binding.name, binding.get_value(path, os.environ.get(binding.name, None)))

def correct_for_64bit(base, rel_path):
	"""If rel_path starts lib or usr/lib and doesn't exist, try with lib64 instead."""
	if os.path.exists(os.path.join(base, rel_path)):
		return rel_path

	if rel_path.startswith('lib/') or rel_path.startswith('usr/lib/'):
		new_rel_path = rel_path.replace('lib/', 'lib64/', 1)
		if os.path.exists(os.path.join(base, new_rel_path)):
			return new_rel_path

	return rel_path

def write_pc(name, lines):
	overrides_dir = os.path.join(os.environ['TMPDIR'], PKG_CONFIG_OVERRIDES)
	if not os.path.isdir(overrides_dir):
		os.mkdir(overrides_dir)
	stream = open(os.path.join(overrides_dir, name), 'w')
	stream.write(''.join(lines))
	stream.close()

def do_pkg_config_binding(binding, impl):
	feed_name = impl.feed.split('/')[-1]
	path = lookup(impl.id)
	new_insert = correct_for_64bit(path, binding.insert)
	if new_insert != binding.insert:
		print "PKG_CONFIG_PATH dir <%s>/%s not found; using %s instead" % (feed_name, binding.insert, new_insert)
		binding = model.EnvironmentBinding(binding.name,
					new_insert,
					binding.default,
					binding.mode)

	orig_path = os.path.join(path, binding.insert)
	if os.path.isdir(orig_path):
		for pc in os.listdir(orig_path):
			stream = open(os.path.join(orig_path, pc))
			lines = stream.readlines()
			stream.close()
			for i, line in enumerate(lines):
				if '=' not in line: continue
				name, value = [x.strip() for x in line.split('=', 1)]
				if name == 'prefix' and value.startswith('/'):
					print "Absolute prefix=%s in %s; overriding..." % (value, feed_name)
					lines[i] = 'prefix=%s/%s\n' % (path, value[1:])
					write_pc(pc, lines)
					break
	do_env_binding(binding, path)

def do_build_internal(options, args):
	"""build-internal"""
	# If a sandbox is being used, we're in it now.
	import getpass, socket, time

	buildenv = BuildEnv()
	sels = buildenv.get_selections()

	builddir = os.path.realpath('build')
	ensure_dir(buildenv.metadir)

	build_env_xml = join(buildenv.metadir, 'build-environment.xml')

	buildenv_doc = buildenv.get_selections().toDOM()

	# Create build-environment.xml file
	root = buildenv_doc.documentElement
	info = buildenv_doc.createElementNS(XMLNS_0COMPILE, 'build-info')
	root.appendChild(info)
	info.setAttributeNS(None, 'time', time.strftime('%Y-%m-%d %H:%M').strip())
	info.setAttributeNS(None, 'host', socket.getfqdn())
	info.setAttributeNS(None, 'user', getpass.getuser())
	uname = os.uname()
	info.setAttributeNS(None, 'arch', '%s-%s' % (uname[0], uname[4]))
	stream = file(build_env_xml, 'w')
	buildenv_doc.writexml(stream, addindent="  ", newl="\n")
	stream.close()

	# Create local binary interface file
	src_iface = iface_cache.get_interface(buildenv.interface)
	src_impl = buildenv.chosen_impl(buildenv.interface)
	write_sample_interface(buildenv, src_iface, src_impl)

	# Check 0compile is new enough
	min_version = parse_version(src_impl.attrs.get(XMLNS_0COMPILE + ' min-version', None))
	if min_version and min_version > parse_version(__main__.version):
		raise SafeException("%s-%s requires 0compile >= %s, but we are only version %s" %
				(src_iface.get_name(), src_impl.version, format_version(min_version), __main__.version))

	# Create the patch
	patch_file = join(buildenv.metadir, 'from-%s.patch' % src_impl.version)
	if buildenv.user_srcdir:
		# (ignore errors; will already be shown on stderr)
		os.system("diff -urN '%s' src > %s" %
			(buildenv.orig_srcdir.replace('\\', '\\\\').replace("'", "\\'"),
			 patch_file))
		if os.path.getsize(patch_file) == 0:
			os.unlink(patch_file)
	elif os.path.exists(patch_file):
		os.unlink(patch_file)

	env('BUILDDIR', builddir)
	env('DISTDIR', buildenv.distdir)
	env('SRCDIR', buildenv.user_srcdir or buildenv.orig_srcdir)
	os.chdir(builddir)
	print "cd", builddir

	for needed_iface in sels.selections:
		impl = buildenv.chosen_impl(needed_iface)
		assert impl
		for dep in impl.dependencies:
			dep_iface = sels.selections[dep.interface]
			for b in dep.bindings:
				if isinstance(b, EnvironmentBinding):
					dep_impl = buildenv.chosen_impl(dep.interface)
					if b.name == 'PKG_CONFIG_PATH':
						do_pkg_config_binding(b, dep_impl)
					else:
						do_env_binding(b, lookup(dep_impl.id))

	mappings = []
	for impl in sels.selections.values():
		new_mappings = impl.attrs.get(XMLNS_0COMPILE + ' lib-mappings', '')
		if new_mappings:
			new_mappings = new_mappings.split(' ')
			for mapping in new_mappings:
				assert ':' in mapping, "lib-mappings missing ':' in '%s' from '%s'" % (mapping, impl.feed)
				name, major_version = mapping.split(':', 1)
				assert '/' not in mapping, "lib-mappings '%s' contains a / in the version number (from '%s')!" % (mapping, impl.feed)
				mappings.append((name, major_version))

	if mappings:
		set_up_mappings(mappings)

	overrides_dir = os.path.join(os.environ['TMPDIR'], PKG_CONFIG_OVERRIDES)
	if os.path.isdir(overrides_dir):
		add_overrides = model.EnvironmentBinding('PKG_CONFIG_PATH', PKG_CONFIG_OVERRIDES)
		do_env_binding(add_overrides, os.environ['TMPDIR'])

	# Some programs want to put temporary build files in the source directory.
	# Make a copy of the source if needed.
	dup_src_type = src_impl.attrs.get(XMLNS_0COMPILE + ' dup-src', None)
	if dup_src_type == 'true':
		dup_src(shutil.copy2)
		env('SRCDIR', builddir)
	elif dup_src_type:
		raise Exception("Unknown dup-src value '%s'" % dup_src_type)

	if options.shell:
		spawn_and_check(find_in_path('sh'), [])
	else:
		command = src_impl.attrs[XMLNS_0COMPILE + ' command']

		# Remove any existing log files
		for log in ['build.log', 'build-success.log', 'build-failure.log']:
			if os.path.exists(log):
				os.unlink(log)

		# Run the command, copying output to a new log
		log = file('build.log', 'w')
		try:
			print >>log, "Build log for %s-%s" % (src_iface.get_name(),
							      src_impl.version)
			print >>log, "\nBuilt using 0compile-%s" % __main__.version
{'fraction_non_alphanumeric': 0.14076648678313364, 'fraction_numerical': 0.00457331016189518, 'mean_word_length': 4.706680584551148, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 12}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '269147', 'n_tokens_mistral': 4184, 'n_tokens_neox': 3936, 'n_words': 900}