Hello. The migration of most [α] Ada packages to gcc-7 to the testing distribution should be completed in a few hours. Thanks to all maintainers implied in this update. You may be interested in what follows if you maintain a library. The policy requires a change of the ALI version in the name of a -dev binary package when the Ada source change (β). The attached python script may be run after a successful build of your source package. It attempts to automatically warn about such issues by downloading a previous version of each -dev package, and comparing the ALI checksums. If a package with the same ALI version is available with different ALI checksums, it exits with a non-zero exit status. If a -dev package requires a renaming, the attached map should help finding its reverse dependencies. Each node represents a source package, and each arrow from A to B means that B mentions the ALI version of A in its build, run-time or test dependencies. Feel free to test and report any problem or suggestion. [α] The only exception for now is blocked by a trivial, unrelated and patched issue that I must admit I am fully responsible for :-). (β) GNAT is granted an exception to spare a passage through the NEW queue for all GCC packages. In other words, libgnat7-dev will *not* change its name when it breaks all other Ada -dev packages.
Attachment:
debian_ada_library_dependencies.pdf
Description: Adobe PDF document
#!/usr/bin/python3
# Each Ada -dev package must be renamed when a .ali file changes
# compared to the current version in unstable.
# This script should be executed in the source tree after a build.
# For each -dev package in the control file, it opens the freshly built .deb
# and searches for the directory containing the .ali files.
# If no such directory found, the package is ignored.
# If no package with the same name is available via apt-get, a warning
# is displayed. The -dev package has probably already been renamed.
# Else, any difference is reported and the exit status is 1.
# It requires the python3-debian package.
# The gnat-BV binary, from the gcc-BV source, uses an unusual scheme
# for the Ada standard library, so it must be handled as a special case.
import os
import re
import subprocess
import sys
import tempfile
import debian.deb822
import debian.debfile
# Global constants
# I use pbuilder. Adapt to your needs.
# fresh_binary_dir = ".."
fresh_binary_dir = "/var/cache/pbuilder/result"
def output (args):
return subprocess.run (args, check=True, stdout=subprocess.PIPE) \
.stdout.rstrip ().decode ()
arch = output (("dpkg-architecture", "-qDEB_HOST_ARCH"))
multiarch = output (("dpkg-architecture", "-qDEB_HOST_MULTIARCH"))
deb_source = output (("dpkg-parsechangelog", "-SSource"))
deb_version = output (("dpkg-parsechangelog", "-SVersion"))
exit_status = 0
def error (message):
global exit_status
print ("error: " + message)
exit_status = 1
# Store all temp files in a common temp directory.
with tempfile.TemporaryDirectory () as tempdir:
# Select 1 or 2 consecutive lines in ali_file matching pattern, then
# extract the first subgroup of each one. Concatenate the results.
def checksum (pattern, ali_file):
previous = None
for line in ali_file:
match = re.match (pattern, line.decode ())
if match:
checksum = match.group (1)
if previous:
return previous + checksum
else:
previous = checksum
elif previous:
return previous
assert False, "failed to parse a .ali file"
def check_binary (package, ali_dir):
global exit_status
new_deb = package + "_" + deb_version + "_" + arch + ".deb"
new = debian.debfile.DebFile (filename = fresh_binary_dir + "/" + new_deb)
if new.data.has_file (ali_dir):
# This test fails for non-Ada -dev packages.
# Check if the package exists in unstable. "apt-get -t unstable" would
# look in experimental when no match exists in unstable.
aptitude = subprocess.run (("aptitude", "search", "-q",
"?and(?exact-name(" + package + "),?archive(unstable))"))
assert aptitude.returncode in (0, 1) # report normal errors
if aptitude.returncode == 1:
print ("Package {} not in unstable, assuming a new aliversion.".format (package))
else:
subprocess.run (("apt-get", "download", "-q", "-t", "unstable", package),
cwd = tempdir, check = True)
for old_deb in os.listdir (tempdir):
if old_deb.startswith (package + "_") \
and old_deb.endswith ("_" + arch + ".deb"):
break
old = debian.debfile.DebFile (filename = tempdir + "/" + old_deb)
print ("Comparing .ali files with {}.".format (new_deb))
for ali in old.data:
match = re.fullmatch ("\./" + ali_dir + "/(.*)\.ali", ali)
if match:
if new.data.has_file (ali):
unit = match.group (1)
pattern = "D " + unit + "\.ad[bs][ \t]+([0-9]{14} [0-9a-f]{8}) "
old_cs = checksum (pattern, old.data.get_file (ali))
new_cs = checksum (pattern, new.data.get_file (ali))
if old_cs != new_cs:
error ("{} has changed.".format (unit))
else:
error ("{} is missing".format (unit))
# Is the source package gcc-BV?
match = re.fullmatch ("gcc-([0-9]+(?:\.[0-9]+)*)", deb_source)
if match:
BV = match.group (1)
check_binary (package = "gnat-" + BV,
ali_dir = "usr/lib/gcc/" + multiarch + "/" + BV + "/adalib")
# The default behaviour below would only find libgnatvsnBV-dev,
# spare many package extractions by hardcoding the result.
check_binary (package = "libgnatvsn" + BV + "-dev",
ali_dir = "usr/lib/" + multiarch + "/ada/adalib/gnatvsn")
else:
with open ("debian/control") as control_file:
paragraphs = debian.deb822.Deb822.iter_paragraphs (control_file)
next (paragraphs) # Skip source paragraph.
for paragraph in paragraphs:
package = paragraph ["Package"]
match = re.fullmatch ("lib(.*[a-z])[0-9]+(?:\.[0-9]+)*-dev", package)
if match:
library = match.group (1).replace ("-", "_")
check_binary (package = package,
ali_dir = "usr/lib/" + multiarch + "/ada/adalib/" + library)
sys.exit (exit_status)