[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    [Patch] Correct relative-path issue in PyQt-builder that can lead to build failures
From:       FeRD <ferdnyc () gmail ! com>
Date:       2020-08-03 11:02:39
Message-ID: CAN1OggWW9z1+1E14C=k+C-WZnh2UktVn=TNaFobfhLRsFYMf+A () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


Building a PyQt5 wheel on Linux using sip-wheel, with Qt's official
`5.15.0` binary distribution and the downloaded PyQt5-5.15.0.tar.xz tarball
contents as my build components, I managed to blunder myself into a perfect
storm of factors that triggered a relatively obscure bug in the
pyqtbuilder/builder.py code. It seems that if you:

   1. Are running in a virtualenv, or otherwise choose to invoke sip-wheel
   via a relative path instead of relying on $PATH
   2. Are using a non-PEP 517 build system like sip-wheel
   3. Also give sip-wheel a *build directory* argument, so that the build
   Makefile is written at a *different* location relative to where
   bin/sip-wheel is located in the venv

Then the install_distinfo target of the Makefile will get written out with
a sip-distinfo command that gets prefixed with the same (now incorrect)
relative path that you originally used to invoke sip-wheel. Which means
that, *waaaaay* at the end of a very long build, the process will suddenly
error out when it fails to execute sip-distinfo.

In concrete terms:

$ cd /tmp
$ python3 -m venv .
$ . ./bin/activate
$ ./bin/pip3 install PyQt-builder sip setuptools dbus-python
$ tar xf PyQt5-5.15.0.tar.xz
$ cd PyQt5-5.15.0
$ ../bin/sip-wheel --qmake /path/to/5.15.0/gcc_64/bin/qmake --build-dir
build/

Will leave you with a /tmp/PyQt5-5.15.0/build/Makefile containing:

install_distinfo: install_subtargets install_uic install_init FORCE
        @test -d $(INSTALL_ROOT)/tmp/PyQt5-5.15.0/build/wheel || mkdir -p
$(INSTALL_ROOT)/tmp/PyQt5-5.15.0/build/wheel
        *../bin/sip-distinfo* --inventory
/tmp/PyQt5-5.15.0/build/inventory.txt
--project-root /tmp/PyQt5-5.15.0 --prefix "$(INSTALL_ROOT)" --generator
sip-wheel
--wheel-tag cp35.cp36.cp37.cp38-abi3-linux_x86_64 --console-script
pylupdate5=PyQt5.pylupdate_main:main --console-script
pyrcc5=PyQt5.pyrcc_main:main
--console-script pyuic5=PyQt5.uic.pyuic:main --requires-dist "PyQt5-sip
(>=12.8, <13)"
/tmp/PyQt5-5.15.0/build/wheel/PyQt5-5.15.0.dist-info

...Which will ultimately fail, because sip-distinfo is located at
../../bin/sip-distinfo, relative to the build directory.

The attached patch changes builder.py to first take the os.path.abspath()
of os.path.dirname(sys.argv[0]), before prepending it to 'sip-distinfo' and
inserting it into the Makefile. This ensures the build is viable from
anywhere in the filesystem.

[Attachment #5 (text/html)]

<div dir="ltr">Building a PyQt5 wheel on Linux using sip-wheel, with Qt&#39;s \
official `5.15.0` binary distribution and the downloaded PyQt5-5.15.0.tar.xz tarball \
contents as my build components, I managed to blunder myself into a perfect storm of \
factors that triggered a relatively obscure bug in the pyqtbuilder/builder.py code. \
It seems that if you:<div><ol><li>Are running in a virtualenv, or otherwise choose to \
invoke sip-wheel via a relative path instead of relying on $PATH</li><li>Are using a \
non-PEP 517  build system like sip-wheel</li><li>Also give sip-wheel a <b>build \
directory</b>  argument, so that the build Makefile is written  at a <i>different</i> \
location relative to where bin/sip-wheel is located in the venv</li></ol><div>Then \
the install_distinfo target of the Makefile will get written out with a sip-distinfo \
command that gets prefixed with the same (now incorrect) relative path that you \
originally  used to invoke sip-wheel. Which means that, <i>waaaaay</i>  at the end of \
a very long build, the process will suddenly error out when it fails to execute \
sip-distinfo.</div></div><div><br></div><div>In concrete terms:</div><div><font \
face="monospace"><br></font></div><div><font face="monospace">$ cd \
/tmp</font></div><div><font face="monospace">$ python3 -m venv \
.</font></div><div><font face="monospace">$ . ./bin/activate</font></div><div><font \
face="monospace">$ ./bin/pip3 install PyQt-builder sip setuptools \
dbus-python</font></div><div><font face="monospace">$ tar xf \
PyQt5-5.15.0.tar.xz</font></div><div><font face="monospace">$ cd \
PyQt5-5.15.0</font></div><div><font face="monospace">$ ../bin/sip-wheel --qmake \
/path/to/5.15.0/gcc_64/bin/qmake --build-dir \
build/</font></div><div><br></div><div>Will leave you with a \
/tmp/PyQt5-5.15.0/build/Makefile containing:</div><div><br></div><div><font \
face="monospace">install_distinfo: install_subtargets install_uic install_init \
FORCE<br>            @test -d $(INSTALL_ROOT)/tmp/PyQt5-5.15.0/build/wheel || mkdir \
-p  </font></div><div><font \
face="monospace">$(INSTALL_ROOT)/tmp/PyQt5-5.15.0/build/wheel<br>            <b><font \
color="#ff0000">../bin/sip-distinfo</font></b> --inventory \
/tmp/PyQt5-5.15.0/build/inventory.txt  </font></div><div><font \
face="monospace">--project-root /tmp/PyQt5-5.15.0 --prefix \
&quot;$(INSTALL_ROOT)&quot; --generator sip-wheel  </font></div><div><font \
face="monospace">--wheel-tag cp35.cp36.cp37.cp38-abi3-linux_x86_64 --console-script  \
</font></div><div><font face="monospace">pylupdate5=PyQt5.pylupdate_main:main \
--console-script pyrcc5=PyQt5.pyrcc_main:main  </font></div><div><font \
face="monospace">--console-script pyuic5=PyQt5.uic.pyuic:main --requires-dist \
&quot;PyQt5-sip (&gt;=12.8, &lt;13)&quot;  </font></div><div><font \
face="monospace">/tmp/PyQt5-5.15.0/build/wheel/PyQt5-5.15.0.dist-info</font><br></div><div><font \
face="monospace"><br></font></div><div><font face="arial, sans-serif">...Which will \
ultimately fail, because sip-distinfo is located at ../../bin/sip-distinfo, relative \
to the build directory.</font></div><div><font face="arial, \
sans-serif"><br></font></div><div><font face="arial, sans-serif">The attached patch \
changes builder.py to first take the os.path.abspath() of \
os.path.dirname(sys.argv[0]), before prepending it to &#39;sip-distinfo&#39; and \
inserting it into the Makefile. This ensures the build is viable from anywhere in the \
filesystem.</font></div><div><font face="arial, sans-serif"><br></font></div></div>


["0001-builder-Use-absolute-paths-in-Makefile.patch" (text/x-patch)]

From 113ea6c306d5cc4953cbddf25295fab00b70806b Mon Sep 17 00:00:00 2001
From: "FeRD (Frank Dana)" <ferdnyc@gmail.com>
Date: Mon, 3 Aug 2020 03:56:38 -0400
Subject: [PATCH] builder: Use absolute paths in Makefile

---
 builder.py | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/builder.py b/builder.py
index 64bf61c..a8f3132 100644
--- a/builder.py
+++ b/builder.py
@@ -58,7 +58,8 @@ class QmakeBuilder(Builder):
             # be on PATH).
             if tool != 'pep517':
                 self._sip_distinfo = os.path.join(
-                        os.path.dirname(sys.argv[0]), self._sip_distinfo)
+                    os.path.abspath(os.path.dirname(sys.argv[0])),
+                    self._sip_distinfo)
 
             # Check we have a qmake.
             if self.qmake is None:
-- 
2.26.2



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic