-
Notifications
You must be signed in to change notification settings - Fork 72
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
Distutils C++ support #228
Conversation
@sciyoshi Would you be willing to investigate the two failures and suggest a fix? |
@jaraco sure. Not sure why the tests would have started failing after, but this patch fixes the tests for me: diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py
index bc579163..4e1cd3ac 100644
--- a/distutils/sysconfig.py
+++ b/distutils/sysconfig.py
@@ -335,7 +335,7 @@ def customize_compiler(compiler): # noqa: C901
ldshared = ldshared + ' ' + os.environ['LDFLAGS']
ldcxxshared = ldcxxshared + ' ' + os.environ['LDFLAGS']
if 'CFLAGS' in os.environ:
- cflags = os.environ['CFLAGS']
+ cflags = cflags + ' ' + os.environ['CFLAGS']
ldshared = ldshared + ' ' + os.environ['CFLAGS']
if 'CXXFLAGS' in os.environ:
cxxflags = os.environ['CXXFLAGS']
diff --git a/distutils/tests/test_sysconfig.py b/distutils/tests/test_sysconfig.py
index 6cbf5168..3177c6e1 100644
--- a/distutils/tests/test_sysconfig.py
+++ b/distutils/tests/test_sysconfig.py
@@ -133,7 +133,7 @@ class TestSysconfig:
assert comp.exes['compiler_so'] == (
'env_cc --sc-cflags ' '--env-cflags ' '--env-cppflags --sc-ccshared'
)
- assert comp.exes['compiler_cxx'] == 'env_cxx --env-cxx-flags'
+ assert comp.exes['compiler_cxx'] == 'env_cxx --env-cxx-flags --sc-cflags --env-cppflags'
assert comp.exes['linker_exe'] == 'env_cc'
assert comp.exes['linker_so'] == (
'env_ldshared --env-ldflags --env-cflags' ' --env-cppflags'
@@ -161,7 +161,7 @@ class TestSysconfig:
assert comp.exes['preprocessor'] == 'sc_cc -E'
assert comp.exes['compiler'] == 'sc_cc --sc-cflags'
assert comp.exes['compiler_so'] == 'sc_cc --sc-cflags --sc-ccshared'
- assert comp.exes['compiler_cxx'] == 'sc_cxx'
+ assert comp.exes['compiler_cxx'] == 'sc_cxx --sc-cflags'
assert comp.exes['linker_exe'] == 'sc_cc'
assert comp.exes['linker_so'] == 'sc_ldshared'
assert comp.shared_lib_extension == 'sc_shutil_suffix'
diff --git a/distutils/tests/test_unixccompiler.py b/distutils/tests/test_unixccompiler.py
index c1e57a01..165d9944 100644
--- a/distutils/tests/test_unixccompiler.py
+++ b/distutils/tests/test_unixccompiler.py
@@ -247,9 +247,13 @@ class TestUnixCCompiler(support.TempdirManager):
def gcv(v):
if v == 'LDSHARED':
return 'gcc-4.2 -bundle -undefined dynamic_lookup '
+ elif v == 'LDCXXSHARED':
+ return 'g++-4.2 -bundle -undefined dynamic_lookup '
elif v == 'CXX':
return 'g++-4.2'
- return 'gcc-4.2'
+ elif v == 'CC':
+ return 'gcc-4.2'
+ return ''
def gcvs(*args, _orig=sysconfig.get_config_vars):
if args: Again, I'm not fully familiar with the intricacies involved, but the change in sysconfig.py seems to probably be an oversight, and the remaining changes in the tests are probably expected differences. |
Thanks! After applying that patch, there's one remaining failure in the pypy tests.
It appears that LDCXXSHARED is not defined in pypy:
|
@jaraco yes I'm not sure how that would have worked before, but in any case it's probably easiest to change it like this: diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py
index 4e1cd3ac..937482a4 100644
--- a/distutils/sysconfig.py
+++ b/distutils/sysconfig.py
@@ -296,7 +296,6 @@ def customize_compiler(compiler): # noqa: C901
cflags,
ccshared,
ldshared,
- ldcxxshared,
shlib_suffix,
ar,
ar_flags,
@@ -306,13 +305,13 @@ def customize_compiler(compiler): # noqa: C901
'CFLAGS',
'CCSHARED',
'LDSHARED',
- 'LDCXXSHARED',
'SHLIB_SUFFIX',
'AR',
'ARFLAGS',
)
cxxflags = cflags
+ ldcxxshared = ""
if 'CC' in os.environ:
newcc = os.environ['CC'] |
More test failures? 😭 |
I applied that diff, but unfortunately, that led to more failures in
Probably we should figure out why that test is reliant on other tests and fix that too. |
At main, that test runs fine in isolation.
|
The issue seems to be surfaced by this change, where the fallback value is now distutils/distutils/sysconfig.py Lines 285 to 291 in e651e53
That code attempts to mutate a global variable, which, if it wasn't initialized by another test, will lead to the error. I believe the proposed diff is safer and more correct. We'll want to fix that undesirable entanglement. |
Upstreamed fix from nix, see patch here: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/setuptools/setuptools-distutils-C%2B%2B.patch
59e1f5d
to
5174927
Compare
After fixing #231 and rebasing onto those changes, I'm now able to elicit the intrinsic error by invoking the test selectively:
|
The issue seems to be that
|
@sciyoshi Since the issue is in the proposed diff, can you investigate? |
Apply ruff/refurb rules (FURB)
…the different return types one might expect.
Wrap linker arg handling to restore prior expectation.
Remove extra quotes from litteral strings
7bfb9d5
to
93ab2a5
Compare
Any thougths on the remaining failing test? I'll try to take a look but won't have much time. |
It looks like in I need someone to figure out what this test was asserting before and what it needs to be asserting now, and is it catching a legitimate bug, or does the test need to be changed to accommodate the new behavior? |
I do see an asymmetry in these lines: distutils/distutils/sysconfig.py Lines 301 to 322 in 95088c5
There, I see |
It looks like making the behavior symmetrical allows the tests to pass: diff --git a/distutils/sysconfig.py b/distutils/sysconfig.py
index 31bdbec1b..847a26ba4 100644
--- a/distutils/sysconfig.py
+++ b/distutils/sysconfig.py
@@ -304,6 +304,7 @@ def customize_compiler(compiler): # noqa: C901
cflags,
ccshared,
ldshared,
+ ldcxxshared,
shlib_suffix,
ar,
ar_flags,
@@ -313,13 +314,13 @@ def customize_compiler(compiler): # noqa: C901
'CFLAGS',
'CCSHARED',
'LDSHARED',
+ 'LDCXXSHARED',
'SHLIB_SUFFIX',
'AR',
'ARFLAGS',
)
cxxflags = cflags
- ldcxxshared = ""
if 'CC' in os.environ:
newcc = os.environ['CC'] I'm unsure if that's the correct implementation, but since tests are passing, it feels more correct and at least makes the PR acceptable. |
Seems that's what the upstream patch does as well. This was probably a mistake on my end when I was updating it. Nice catch! |
Actually, I think the new error in |
In PyPy only, it seems. Seems to be that PyPy has a different definition for |
@jaraco I may be wrong, but it looks like PyPy doesn't preserve CPython does that explicitely here: https://github.com/python/cpython/blob/5a7f7c48644baf82988f30bcb43e03dcfceb75dd/configure.ac#L3395. |
@jaraco I also checked PyPy, and I don't see any reference to |
My first instinct was to replace My next instinct is not to My next thought was to just skip this test on PyPy, but that probably will cause compilers to break on PyPy on Unix. Another thought was to inject LDCXXSHARED when it's missing, similar to how is done for add_ext_suffix_39. The problem is, what value to present? Again, an empty string is wrong. And the default value isn't a string at all but a list. @mattip Do you have any insight into why PyPy doesn't have LDCXXSHARED set in sysconfig? Will PyPy users ever expect to be taking advantage of compiling C++ shared libraries under PyPy? |
…_add_flags logic. Reduces cyclomatic complexity so it passes QA checks.
In fcef963, I found a satisfactory workaround - don't attempt to add flags if the value is None. It first required a refactor in 3e4b457. With this change, |
The only remaining failure is in diffcov, which is ignorable, since there's no coverage aggregation. |
The values there have been added on an as-needed basis, in response to issues. PyPy does not use a Makefile or On CPython windows it is not defined. I'm not sure how PyPY would create that value, it appears to want to invoke a compiler. How does CPython know what compiler is available on the host platform? What happens if clang is installed instead of gcc? |
Thank you @jaraco! Really appreciate all of the hard work. |
This particular code path is only for Unix, so that's why the discrepancy hasn't been an issue.
It looks like it's built from
|
We don't use c++ in PyPy, so the best we could do would be to copy that value (and the one for linux) into the |
Here are the hard-coded PyPy values https://github.com/pypy/pypy/blob/py3.9/lib_pypy/_sysconfigdata.py |
Upstreamed fix from nix, see patch here:
https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/python-modules/setuptools/setuptools-distutils-C%2B%2B.patch
Resubmit of #221.