1 # A debhelper build system class for building Python Distutils based
2 # projects. It prefers out of source tree building.
4 # Copyright: © 2008 Joey Hess
5 # © 2008-2009 Modestas Vainius
8 package Debian::Debhelper::Buildsystem::python_distutils;
12 use Debian::Debhelper::Dh_Lib qw(error);
13 use base 'Debian::Debhelper::Buildsystem';
16 "Python Distutils (setup.py)"
19 sub DEFAULT_BUILD_DIRECTORY {
21 return $this->canonpath($this->get_sourcepath("build"));
26 my $this=$class->SUPER::new(@_);
27 # Out of source tree building is preferred.
28 $this->prefer_out_of_source_building(@_);
32 sub check_auto_buildable {
34 return -e $this->get_sourcepath("setup.py") ? 1 : 0;
40 if (open(my $cfg, $this->get_buildpath(".pydistutils.cfg"))) {
41 $ret = not "# Created by dh_auto\n" eq <$cfg>;
49 if (open(my $cfg, ">", $this->get_buildpath(".pydistutils.cfg"))) {
50 print $cfg "# Created by dh_auto", "\n";
51 print $cfg "[build]\nbuild-base=", $this->get_build_rel2sourcedir(), "\n";
58 sub pre_building_step {
62 return unless grep /$step/, qw(build install clean);
64 if ($this->get_buildpath() ne $this->DEFAULT_BUILD_DIRECTORY()) {
65 # --build-base can only be passed to the build command. However,
66 # it is always read from the config file (really weird design).
67 # Therefore create such a cfg config file.
68 # See http://bugs.python.org/issue818201
69 # http://bugs.python.org/issue1011113
70 not $this->not_our_cfg() or
71 error("cannot set custom build directory: .pydistutils.cfg is in use");
72 $this->mkdir_builddir();
73 $this->create_cfg() or
74 error("cannot set custom build directory: unwritable .pydistutils.cfg");
75 # Distutils reads $HOME/.pydistutils.cfg
76 $ENV{HOME} = Cwd::abs_path($this->get_buildpath());
79 $this->SUPER::pre_building_step($step);
82 sub dbg_build_needed {
86 # Return a list of python-dbg package which are listed
87 # in the build-dependencies. This is kinda ugly, but building
88 # dbg extensions without checking if they're supposed to be
89 # built may result in various FTBFS if the package is not
90 # built in a clean chroot.
93 open (CONTROL, 'debian/control') ||
94 error("cannot read debian/control: $!\n");
95 foreach my $builddeps (join('', <CONTROL>) =~
96 /^Build-Depends[^:]*:.*\n(?:^[^\w\n].*\n)*/gmi) {
97 while ($builddeps =~ /(python[^, ]*-dbg)/g) {
111 # We need to to run setup.py with the default python last
112 # as distutils/setuptools modifies the shebang lines of scripts.
113 # This ensures that #!/usr/bin/python is installed last and
115 # Take into account that the default Python must not be in
116 # the requested Python versions.
117 # Then, run setup.py with each available python, to build
118 # extensions for each.
120 my $python_default = `pyversions -d`;
122 error("failed to run pyversions")
126 error("pyversions -d failed [$ecode]")
128 $python_default =~ s/^\s+//;
129 $python_default =~ s/\s+$//;
130 my @python_requested = split ' ', `pyversions -r`;
132 error("failed to run pyversions")
136 error("pyversions -r failed [$ecode]")
138 if (grep /^\Q$python_default\E/, @python_requested) {
139 @python_requested = (
140 grep(!/^\Q$python_default\E/, @python_requested),
146 my @dbg_build_needed = $this->dbg_build_needed();
147 foreach my $python (map { $_."-dbg" } @python_requested) {
148 if (grep /^(python-all-dbg|\Q$python\E)/, @dbg_build_needed) {
149 push @python_dbg, $python;
151 elsif (($python eq "python-dbg")
152 and (grep /^\Q$python_default\E/, @dbg_build_needed)) {
153 push @python_dbg, $python_default."-dbg";
157 foreach my $python (@python_dbg, @python_requested) {
158 if (-x "/usr/bin/".$python) {
159 # To allow backports of debhelper we don't pass
160 # --install-layout=deb to 'setup.py install` for
161 # those Python versions where the option is
162 # ignored by distutils/setuptools.
163 if ( $act eq "install" and not
164 ( ($python =~ /^python(?:-dbg)?$/
165 and $python_default =~ /^python2\.[2345]$/)
166 or $python =~ /^python2\.[2345](?:-dbg)?$/ )) {
167 $this->doit_in_sourcedir($python, "setup.py",
168 $act, @_, "--install-layout=deb");
171 $this->doit_in_sourcedir($python, "setup.py",
180 $this->setup_py("build",
188 $this->setup_py("install",
198 $this->setup_py("clean", "-a", @_);
200 # Config file will remain if it was created by us
201 if (!$this->not_our_cfg()) {
202 unlink($this->get_buildpath(".pydistutils.cfg"));
203 $this->rmdir_builddir(1); # only if empty
205 # The setup.py might import files, leading to python creating pyc
207 $this->doit_in_sourcedir('find', '.', '-name', '*.pyc', '-exec', 'rm', '{}', ';');