-
-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SCons: Decode stdout from subprocess #2201
Conversation
build/mixxx.py
Outdated
@@ -213,15 +213,15 @@ def __init__(self, target, machine, build, toolchain, available_features): | |||
# Now that environment variables have been read, we can detect the compiler. | |||
import subprocess | |||
process = subprocess.Popen("%s %s" %(self.env['CC'], '--version'), stdout=subprocess.PIPE, shell=True) # nosec | |||
(stdout, stderr) = process.communicate() | |||
stdout = process.communicate()[0].rstrip().decode() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might make sense to use subprocess.check_output()
instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the hint!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I just read that process.run() is recommended instead of subprocess.check_output() since 3.5? I'm not able to decide what to choose here, considering that we need to support a variety of Python versions. Maybe someone else can take over and fix all those issues?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you only want to check the content of stdout anyway, there's no actual advantage from using subprocess.run()
other than being hip and modern. On the other hand, we'd lose compatibility with all Python versions < 3.5 (subprocess.check_output
even works on Python 2.7).
build/mixxx.py
Outdated
@@ -213,15 +213,15 @@ def __init__(self, target, machine, build, toolchain, available_features): | |||
# Now that environment variables have been read, we can detect the compiler. | |||
import subprocess | |||
process = subprocess.Popen("%s %s" %(self.env['CC'], '--version'), stdout=subprocess.PIPE, shell=True) # nosec |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shell=True
in combination with user input opens the door for command injections, e.g. if CC
is set to rm -rf /; gcc
.
Instead, something like this should be used:
process = subprocess.Popen([self.env['CC'], '--version'], stdout=subprocess.PIPE)`
# or:
stdout = subprocess.check_output([self.env['CC'], '--version'])`
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The shell=True argument has been added just recently by the NixOS build support, not sure why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@poelzi has explained it here:
https://github.com/mixxxdj/mixxx/pull/2144/files#r291847013
Unfortunately the comment was not added to the code. Maybe we can add a comment here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In that case IMHO it's still undesirable to invoke a shell because we don't know what crazy non-standard $SHELL
the user is using. shlex.split()
can be used to split the content of CC env var, so that shell=True
is not needed.
stdout = subprocess.check_output([*shlex.split(self.env['CC']), '--version'])`
# or the longer version
cmd = shlex.split(self.env['CC'])
cmd.append('--version')
stdout = subprocess.check_output(cmd)`
|
@uklotzde Sorry for the late answer, I'm currently traveling. Since I couldn't reproduce the issue from your second point, but have a look at this example: uklotzde/mixxx@scons...Holzhaus:scons |
Note that this changes the behaviour of the compiler check. It fails if a compiler doesn't support
Not sure if it's a real problem.. |
I can confirm that this still builds on my Ubuntu Xenial using Scons v2.4.1. |
I'm not experienced enough with Python and will not change this code again. Please take over if you know a better way. |
Imports that are not at the top of file are considered bad style in Python. See this for details: https://legacy.python.org/dev/peps/pep-0008/#imports
@uklotzde I made some smaller fixes and improvements: Build fine for me on Linux now (I had some problems with the pkg-config invocation so that Qt couldn't be found.) |
The build with Scons 3.0.4 / Python 2.7 fails now: python2-scons
Unfortunately the build fails due to another reason when using the same SCons version on Python 3.7 as reported on Launchpad: python3-scons
|
The additional repo_node kwarg is required since this commit: SCons/scons@f999d21#diff-ac9db0da66287699ffbaf33c370d2c85R1508
@uklotzde Sorry, I'm currently on my old and slow laptop, so I just Ctrl-C'ed after the configuration stage.
I also had to add another commit to fix compilation with SCons 3.1.1: I can confirm that compilation works with Scons 3.1.1 and Python 3.7. |
I intend to eventually remove that as part of #1705, but that PR still needs a lot of work before it is ready for merge so don't count on that happening soon. |
Ok, don't worry. It's not time critical since I remove the commit (that replaced the hardcoded sources with globbing) anyway. If we add it again, we could add a blacklist to exclude files instead, which would still be shorter than the hardcoded whitelist. @uklotzde Can we merge this or are there issues with older SCons/Python versions? Currently, compilation is completely broken for me without these changes (Scons 3.11, Python 3.7). |
This re-adds 'utf-8' to bytes.decode() calls and replaces FileNotFoundError with OSError to restore compatibility with Python 2.7. When Python 2.7 finally reaches EOL we can simply revert this commit.
@uklotzde I had a look at the TravisCI build log. Looks like it failed due to missing Python 2.7 compatibilty. Here are some more fixes that restores it: uklotzde/mixxx@scons...Holzhaus:scons Works with SCons 3.0.4/Python 2.7.16 and SCons 3.1.1/Python 3.7.4 (tested on Linux/AMD64). |
By the way, let's merge this ASAP. It's getting annoying that I need to apply/stash Scons-3.1-related fixes on every branch that I'm working on ;-) |
Let's wait until the CI build have successfully completed. Since no one else takes care of this rather urgent issues I will merge it asap!! Thanks for providing all these patches. I will try a clean Python 3 / SCons 3.0.4 build on fc30, although I don't expect it to succeed. |
As expected, a clean build with Python 3 / SCons 3.0.4 still fails:
I delete |
@uklotzde Sorry, I used However, this doesn't seem to be related to this PR, since it also happens when I try to build the current master branch with this patch:
I'll investigate. |
Definitely not caused by your changes. It's a known and long outstanding bug that we need to solve soon as Python 2 becomes deprecated: https://bugs.launchpad.net/mixxx/+bug/1817742 Not sure if anyone is working on this already? I didn't get any notice from "andy-xyz" after he has assigned the bug to himself. |
Unfortunately macOS/clang build now fails:
|
Sorry, I accidently grepped just
I found the issue. Python's Here are some more patches that should fix the remaining issues: Works with SCons 3.0.4/Python 2.7.16 and SCons 3.1.1/Python 3.7.4 (and this time i |
It just works now!! That was awesome, Jan 👍 I'm always afraid if we need to touch this brittle and hand-crafted build system. Let's wait for the CI builds. |
@@ -197,15 +199,16 @@ def uic(build): | |||
@staticmethod | |||
def find_framework_libdir(qtdir): | |||
# Try pkg-config on Linux | |||
import sys | |||
if sys.platform.startswith('linux') or sys.platform.find('bsd') >= 0: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like we musn't remove this line, because it makes the MacOS build fail...
Thank you for the detailed comments about how map() is supposed to work! This is not obvious for someone with hardly any Python knowledge like me. |
I confirm this works on Fedora 30 with the scons-3 binary. 👍 |
FWIW, Qt is finally dropping their hand-crafted build system for Qt 6 and switching to CMake. We may consider doing the same soon. |
@uklotzde Sorry that I need to bother you with so many changes, but I do not have MacOS and it looks like I can't I start builds on Travis CI manually without opening my own PR.
Sounds like a plan 👍 |
I don't want to switch to master for fc31/rawhide in RPM Fusion right now. But as soon as we branch out 2.3 we can remove the Python 2 workaround there. |
Are you volunteering to work on it? :) |
Don't mind. You are doing great work! I think if you register your own account on Travis you can build individual branches from your GitHub repositories. I have both AppVeyor and Travis accounts, just in case. But most of the time I'm too lazy and open some [WiP] PR if it's almost ready. |
We have a wiki page for that. |
Oops, I should RTFM in the future ;-)
I can't promise it, but the current SCons setup is super confusing so I probably should 😄 |
Looks like the MacOS build finally succeeded. |
The Windows build timed out, but otherwise it worked flawlessly. Let's wait another 30 minutes for the Ubuntu build, although I don't expect any new issues. |
LGTM. Since @Holzhaus has actually done most of the work I think I'm entitled to merge my own PR ;) Finally we are ready for Python 3 / SCons 3! |
Try to fix some issues with SCons 3 reported here: #1356 (comment)