#!/usr/bin/perl =head1 NAME dh_gencontrol - generate and install control file =cut use strict; use warnings; use Debian::Debhelper::Dh_Lib; our $VERSION = DH_BUILTIN_VERSION; =head1 SYNOPSIS B [S>] [S I>] =head1 DESCRIPTION B is a debhelper program that is responsible for generating control files, and installing them into the I directory with the proper permissions. This program is merely a wrapper around L, which calls it once for each package being acted on (plus related dbgsym packages), and passes in some additional useful flags. B that if you use B, you must also use L to build the packages. Otherwise, your build may fail to build as B (via L) declares which packages are built. As debhelper automatically generates dbgsym packages, it some times adds additional packages, which will be built by L. =head1 OPTIONS =over 4 =item B<--> I Pass I to L. =item B<-u>I, B<--dpkg-gencontrol-params=>I This is another way to pass I to L. It is deprecated; use B<--> instead. =back =cut init(options => { "dpkg-gencontrol-params=s", => \$dh{U_PARAMS}, }); if (not compat(13)) { # Load once early, so each child does not have to load these again (they are expensive # compared to Debian::Debhelper::Dh_Lib). require Dpkg::Control; require Dpkg::Control::Fields; } # The `substvars` file ius not quite a pkgfile, but it works similar enough that people might # be surprised if it was not detected. # INTROSPECTABLE: CONFIG-FILES pkgfile(substvars) on_pkgs_in_parallel { foreach my $package (@_) { my $tmp=tmpdir($package); my $ext=pkgext($package); my $dbgsym_info_dir = "debian/.debhelper/${package}"; my $dbgsym_tmp = dbgsym_tmpdir($package); my $substvars="debian/${ext}substvars"; my $changelog = pkgfile( { 'internal-nameless-variant-handling' => 1, 'named' => 0, 'support-architecture-restriction' => 0, }, $package, 'changelog', ); install_dir("$tmp/DEBIAN"); # avoid gratuitous warnings ensure_substvars_are_present($substvars, 'misc:Depends', 'misc:Pre-Depends') if compat(14); my (@debug_info_params, $build_ids, @pkg_gencontrol_args); if ( -d $dbgsym_info_dir ) { $build_ids = read_dbgsym_build_ids($dbgsym_info_dir); } my $has_dbgsym = -d $dbgsym_tmp; my ($dctrl, $added_dbgsym_version); ($dctrl, $added_dbgsym_version) = Debian::Debhelper::Dh_Lib::dh_gencontrol_automatic_substvars($package, $substvars, $has_dbgsym) if not compat(13); $dctrl //= 'debian/control'; if ($has_dbgsym) { my $dbgsym_package = $added_dbgsym_version ? "${package}-dbgsym" : $package; my $dbgsym_ctrl = $added_dbgsym_version ? $dctrl : 'debian/control'; my $dbgsym_substvar = $added_dbgsym_version ? '/dev/null' : $substvars; my $multiarch = package_multiarch($package); my $section = package_section($package); my $replaces = read_dbgsym_migration($dbgsym_info_dir); my $component = ''; if ($section =~ m{^(.*)/[^/]+$}) { $component = "${1}/"; # This should not happen, but lets not propagate the error # if does. $component = '' if $component eq 'main/'; } # Remove and override more or less every standard field. my @dbgsym_options = (qw( -UPre-Depends -URecommends -USuggests -UEnhances -UProvides -UEssential -UConflicts -DPriority=optional -UHomepage -UImportant -DAuto-Built-Package=debug-symbols -UProtected -UBuilt-Using -UStatic-Built-Using ), "-DPackage=${package}-dbgsym", "-DDepends=${package} (= \${binary:Version})", "-DDescription=debug symbols for ${package}", "-DBuild-Ids=${build_ids}", "-DSection=${component}debug", ); push(@dbgsym_options, "-DPackage-Type=${\DBGSYM_PACKAGE_TYPE}") if DBGSYM_PACKAGE_TYPE ne DEFAULT_PACKAGE_TYPE; # Disable multi-arch unless the original package is an # multi-arch: same package. In all other cases, we do not # need a multi-arch value. if ($multiarch ne 'same') { push(@dbgsym_options, '-UMulti-Arch'); } # If the dbgsym package is replacing an existing -dbg package, # then declare the necessary Breaks + Replaces. Otherwise, # clear the fields. if ($replaces) { push(@dbgsym_options, "-DReplaces=${replaces}", "-DBreaks=${replaces}"); } else { push(@dbgsym_options, '-UReplaces', '-UBreaks'); } install_dir("${dbgsym_tmp}/DEBIAN"); eval { doit("dpkg-gencontrol", "-p${dbgsym_package}", "-l$changelog", "-T${dbgsym_substvar}", "-c${dbgsym_ctrl}", "-P${dbgsym_tmp}", @{$dh{U_PARAMS}}, @dbgsym_options); }; if (my $err = "$@") { if ($dbgsym_ctrl ne 'debian/control') { warning('The dpkg-control command failed. Here is the content of the rewritten d/control file'); warning(' used to add relationship substvars for you (in case that is part of the problem).'); print(" --- Content of $dbgsym_ctrl\n"); system('cat', $dbgsym_ctrl); print(" --- End of content for $dbgsym_ctrl\n"); } error($err); } reset_perm_and_owner(0644, "${dbgsym_tmp}/DEBIAN/control"); } elsif ($build_ids) { # Only include the build-id if there is no dbgsym package (if # there is a dbgsym package, the build-ids into the control # file of the dbgsym package) push(@debug_info_params, "-DBuild-Ids=${build_ids}"); } # Remove explicit "Multi-Arch: no" headers to avoid auto-rejects by dak. push (@pkg_gencontrol_args, '-UMulti-Arch') if (package_multiarch($package) eq 'no'); # Generate and install control file. eval { doit("dpkg-gencontrol", "-p$package", "-l$changelog", "-T$substvars", "-c${dctrl}", "-P$tmp", @debug_info_params, @pkg_gencontrol_args, @{$dh{U_PARAMS}}); }; if (my $err = "$@") { if ($dctrl ne 'debian/control') { warning('The dpkg-control command failed. Here is the content of the rewritten d/control file'); warning(' used to add relationship substvars for you (in case that is part of the problem).'); print(" --- Content of $dctrl\n"); system('cat', $dctrl); print(" --- End of content for $dctrl\n"); } error($err); } # This chmod is only necessary if the user sets the umask to # something odd. reset_perm_and_owner(0644, "${tmp}/DEBIAN/control"); } }; sub read_dbgsym_file { my ($dbgsym_info_file, $dbgsym_info_dir) = @_; my $dbgsym_path = "${dbgsym_info_dir}/${dbgsym_info_file}"; my $result; if (-f $dbgsym_path) { open(my $fd, '<', $dbgsym_path) or error("open $dbgsym_path failed: $!"); chomp($result = <$fd>); $result =~ s/\s++$//; close($fd); } return $result; } sub read_dbgsym_migration { return read_dbgsym_file('dbgsym-migration', @_); } sub read_dbgsym_build_ids { my $res = read_dbgsym_file('dbgsym-build-ids', @_); my (%seen, @unique); return '' if not defined($res); for my $id (split(' ', $res)) { next if $seen{$id}++; push(@unique, $id); } return join(' ', @unique); } =head1 SEE ALSO L This program is a part of debhelper. =head1 AUTHOR Joey Hess =cut