#657401 dpkg-buildpackage: support output directory other than ..

#657401#5
Date:
2012-01-25 23:28:41 UTC
From:
To:
Currently, it is not trivial to have dpkg-buildpackage (or debuild)
output a build package to a directory other than '..'. Support of a
--output directory option with a default of '..' would avoid other
tools having to parse the .changes file generated to move output files
to a desired directory. [And would also avoid stomping on existing
files even if one were to parse the .changes file properly.]


Don Armstrong

#657401#10
Date:
2012-01-26 04:56:39 UTC
From:
To:
I implemented this, but then realized that it cannot be done cleanly,
as dpkg-deb is called from inside debian/rules and will always place
the binary packages under «..», so dpkg-buildpackage would need to
move the files itself afterwards. While that could be done, it might
not avoid the problem you refer to.

regards,
guillem

#657401#15
Date:
2012-01-26 05:04:35 UTC
From:
To:
Hrm; true. I actually wanted this primarily for debuild -S, but
solving it for everything is probably necessary to solve it at all.
The hack of sending an env option through to dpkg-deb is all kinds of
ugly...


Don Armstrong

#657401#20
Date:
2012-01-26 07:29:51 UTC
From:
To:
Hi,

Note that dpkg-source also creates files in the current directory and
expect to find files in the current directory (and dpkg-buildpackage
changes the current directory to ".." for the needs of dpkg-source).

So if you change the current directory to your output directory, you also
have to do something to ensure that dpkg-source keeps on finding the orig
tarballs.

Why would it be more ugly than dpkg-buildpackage -j setting
DEB_BUILD_OPTIONS="parallel"?

Of course, if there would be no constraints, I would not pick up an env
variable as preferred way to pass options but there are many tools
who are accepting options through the environment (think GZIP,
TAR_OPTIONS, etc.). I don't see why we couldn't do that.

Cheers,

#657401#25
Date:
2012-01-26 23:42:45 UTC
From:
To:
That's already handled by passing the sourcedir path to dpkg-source,
the only change I had to do was to switch from relative paths to
absolute ones in that case.

Well DEB_BUILD_OPTIONS is a variable to be used by debian/rules directly
if at all, which does not have other defined ways to pass options to it.
Passing default options to dpkg-deb which is a sub-child, might be
unreliable, depending on how the build process is handled, if there's
environment cleanup from whoever ends up calling it, it does not
necessarily need to be debian/rules for example, etc.

For starters all current invokations already use an explicit destination
path for the deb. Environment variables are always used to set
option defaults (not commands) that always get overridden by the
command line, doing otherwise would be extremely confusing, and it's
just ugly.

In the end this comes down to the way or build system is currently
designed, in that debian/rules is in charge of generating the resulting
binary packages, which makes some global changes more difficult.

regards,
guillem

#657401#30
Date:
2012-01-27 07:29:53 UTC
From:
To:
Right, this is the real blocker. In most cases, dpkg-deb doesn't decide of
the location, it's the caller that does (usually dh_builddeb).

Sure. But a directory to use would certainly be an option and not a
command...

Yes.

Cheers,

#657401#35
Date:
2012-01-27 09:01:30 UTC
From:
To:
Right, but the pathname is (optionally) passed as part of the command,
not as an option, in addition it (almost) always gets passed, at least
from source packages. So it would still go against the principle that
environment vars do not override command line options, because the
caller explicitly passed a pathname not a filename for the deb, an
output dir would override that.

So it would only be ok on invokations w/o an explicit pathname argument,
or I guess just a filename. For other cases consider we'd either have to
strip any directory components from the pathname given on the command
line or the user would need to pass an output dir one level down the
path so that the ../ would get neutralized.

To make this more explicit, this is something that has crossed my mind
several times, to look into a new design that would move things outside
the packaging, so that for example dpkg-deb would be done externally.

For example the RPM source format has some of these properties, but has
other problems of its own.

thanks,
guillem

#657401#40
Date:
2020-05-03 05:57:35 UTC
From:
To:
This weekend I has a look at this issue and mostly got it working, but
at the end failed on two issues:

1. `dpkg-source --build $path` allows absolute paths. The `.orig.tar`
files must be placed in the directory from where `dpkg-source` is
invoked from.

2. Most packages nowadays use debhelper, so `dh_builddeb` is used to
invoke `dpkg-deb`. The former has the option `--destdir` but that one
clashes with the same option being used by `dh_auto_install`, so it MUST
NOT be passed through `$DH_OPTIONS`.

3. `dpkg-genbuildinfo` and `dpkg-genchanges` both have the option `-u`
to specify a different directory for the build artifacts.

4. The last missing part is the hard-coded path for the `.changes` file:
`dpkg-buildpackage` has no option to change that.

This is my summary for now as of May 2020.
More details of my experiment at
<https://pmhahn.github.io/debian-oot-build/>.

#657401#45
Date:
2021-03-15 19:26:14 UTC
From:
To:
I could imagine the patch below, which I started looking at some time ago
but never
got around to coming back to, could form a start at implementing this.
It was just the obvious paths within the script itself, but the various
calls to dpkg-source,
dpkg-genbuildinfo, dpkg-genchanges, that all accept output options, still
need to be
modified to pass this new argument.

diff --git a/scripts/dpkg-buildpackage.pl b/scripts/dpkg-buildpackage.pl
index aacb831..af50b75 100755
--- a/scripts/dpkg-buildpackage.pl
+++ b/scripts/dpkg-buildpackage.pl
@@ -80,6 +80,7 @@ sub usage {
   -d, --no-check-builddeps    do not check build dependencies and
conflicts.
       --ignore-builtin-builddeps
                               do not check builtin build dependencies.
+  -o, --output-dir=<dir>      path to put output files in. (default is ../)
   -P, --build-profiles=<profiles>
                               assume comma-separated build <profiles> as
active.
       --rules-requires-root   assume legacy Rules-Requires-Root field
value.
@@ -182,6 +183,7 @@ my $changedby;
 my $desc;
 my @buildinfo_opts;
 my @changes_opts;
+my $outdir = "..";
 my %target_legacy_root = map { $_ => 1 } qw(
     clean binary binary-arch binary-indep
 );
@@ -301,6 +303,8 @@ while (@ARGV) {
         $postclean = 0;
     } elsif (/^--sanitize-env$/) {
         $sanitize_env = 1;
+    } elsif (/^-o(.*)$/ or /^--output-dir=(.*)$/) {
+        $outdir = $1;
     } elsif (/^-t$/ or /^--host-type$/) {
        $host_type = shift; # Order DOES matter!
     } elsif (/^-t(.*)$/ or /^--host-type=(.*)$/) {
@@ -598,7 +602,7 @@ push @changes_opts, "-e$changedby" if defined
$changedby;
 push @changes_opts, "-v$since" if defined $since;
 push @changes_opts, "-C$desc" if defined $desc;

#657401#50
Date:
2021-03-18 01:13:19 UTC
From:
To:
This is pretty close to what I initially did, and mentioned on my first
reply to the bug.

  <https://git.hadrons.org/cgit/debian/dpkg/dpkg.git/commit/?h=pu/dpkg-buildpackage-build-outputdir>

The actual problem are none of these, but the dpkg-deb calls performed
from within debian/rules, directly or indirectly via debhelper. Where
even if debhelper would handle this as Philipp Hahn suggested, dpkg
could not rely on that as this is a package-specific implementation
detail.

Until and iff dpkg-buildpackage starts handling the dpkg-deb calls by
itself, this bug cannot be solved. I didn't feel like marking as
wontfix because I think the request make sense, it's just that I don't
see how to implement it as things stand right now.

Thanks,
Guillem