-
-
Notifications
You must be signed in to change notification settings - Fork 18k
python: add C++ compiler support for distutils #19585
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,260 @@ | ||
| --- a/Lib/distutils/cygwinccompiler.py | ||
| +++ b/Lib/distutils/cygwinccompiler.py | ||
| @@ -117,8 +117,10 @@ | ||
| # dllwrap 2.10.90 is buggy | ||
| if self.ld_version >= "2.10.90": | ||
| self.linker_dll = "gcc" | ||
| + self.linker_dll_cxx = "g++" | ||
| else: | ||
| self.linker_dll = "dllwrap" | ||
| + self.linker_dll_cxx = "dllwrap" | ||
|
|
||
| # ld_version >= "2.13" support -shared so use it instead of | ||
| # -mdll -static | ||
| @@ -132,9 +134,13 @@ | ||
| self.set_executables(compiler='gcc -mcygwin -O -Wall', | ||
| compiler_so='gcc -mcygwin -mdll -O -Wall', | ||
| compiler_cxx='g++ -mcygwin -O -Wall', | ||
| + compiler_so_cxx='g++ -mcygwin -mdll -O -Wall', | ||
| linker_exe='gcc -mcygwin', | ||
| linker_so=('%s -mcygwin %s' % | ||
| - (self.linker_dll, shared_option))) | ||
| + (self.linker_dll, shared_option)), | ||
| + linker_exe_cxx='g++ -mcygwin', | ||
| + linker_so_cxx=('%s -mcygwin %s' % | ||
| + (self.linker_dll_cxx, shared_option))) | ||
|
|
||
| # cygwin and mingw32 need different sets of libraries | ||
| if self.gcc_version == "2.91.57": | ||
| @@ -160,8 +166,12 @@ | ||
| raise CompileError, msg | ||
| else: # for other files use the C-compiler | ||
| try: | ||
| - self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + | ||
| - extra_postargs) | ||
| + if self.detect_language(src) == 'c++': | ||
| + self.spawn(self.compiler_so_cxx + cc_args + [src, '-o', obj] + | ||
| + extra_postargs) | ||
| + else: | ||
| + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + | ||
| + extra_postargs) | ||
| except DistutilsExecError, msg: | ||
| raise CompileError, msg | ||
|
|
||
| @@ -327,9 +337,14 @@ | ||
| self.set_executables(compiler='gcc%s -O -Wall' % no_cygwin, | ||
| compiler_so='gcc%s -mdll -O -Wall' % no_cygwin, | ||
| compiler_cxx='g++%s -O -Wall' % no_cygwin, | ||
| + compiler_so_cxx='g++%s -mdll -O -Wall' % no_cygwin, | ||
| linker_exe='gcc%s' % no_cygwin, | ||
| linker_so='%s%s %s %s' | ||
| % (self.linker_dll, no_cygwin, | ||
| + shared_option, entry_point), | ||
| + linker_exe_cxx='g++%s' % no_cygwin, | ||
| + linker_so_cxx='%s%s %s %s' | ||
| + % (self.linker_dll_cxx, no_cygwin, | ||
| shared_option, entry_point)) | ||
| # Maybe we should also append -mthreads, but then the finished | ||
| # dlls need another dll (mingwm10.dll see Mingw32 docs) | ||
| --- a/Lib/distutils/emxccompiler.py | ||
| +++ b/Lib/distutils/emxccompiler.py | ||
| @@ -65,8 +65,12 @@ | ||
| # XXX optimization, warnings etc. should be customizable. | ||
| self.set_executables(compiler='gcc -Zomf -Zmt -O3 -fomit-frame-pointer -mprobe -Wall', | ||
| compiler_so='gcc -Zomf -Zmt -O3 -fomit-frame-pointer -mprobe -Wall', | ||
| + compiler_cxx='g++ -Zomf -Zmt -O3 -fomit-frame-pointer -mprobe -Wall', | ||
| + compiler_so_cxx='g++ -Zomf -Zmt -O3 -fomit-frame-pointer -mprobe -Wall', | ||
| linker_exe='gcc -Zomf -Zmt -Zcrtdll', | ||
| - linker_so='gcc -Zomf -Zmt -Zcrtdll -Zdll') | ||
| + linker_so='gcc -Zomf -Zmt -Zcrtdll -Zdll', | ||
| + linker_exe_cxx='g++ -Zomf -Zmt -Zcrtdll', | ||
| + linker_so_cxx='g++ -Zomf -Zmt -Zcrtdll -Zdll') | ||
|
|
||
| # want the gcc library statically linked (so that we don't have | ||
| # to distribute a version dependent on the compiler we have) | ||
| @@ -83,8 +87,12 @@ | ||
| raise CompileError, msg | ||
| else: # for other files use the C-compiler | ||
| try: | ||
| - self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + | ||
| - extra_postargs) | ||
| + if self.detect_language(src) == 'c++': | ||
| + self.spawn(self.compiler_so_cxx + cc_args + [src, '-o', obj] + | ||
| + extra_postargs) | ||
| + else: | ||
| + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + | ||
| + extra_postargs) | ||
| except DistutilsExecError, msg: | ||
| raise CompileError, msg | ||
|
|
||
| --- a/Lib/distutils/sysconfig.py | ||
| +++ b/Lib/distutils/sysconfig.py | ||
| @@ -170,10 +170,12 @@ | ||
| _osx_support.customize_compiler(_config_vars) | ||
| _config_vars['CUSTOMIZED_OSX_COMPILER'] = 'True' | ||
|
|
||
| - (cc, cxx, opt, cflags, ccshared, ldshared, so_ext, ar, ar_flags) = \ | ||
| - get_config_vars('CC', 'CXX', 'OPT', 'CFLAGS', | ||
| - 'CCSHARED', 'LDSHARED', 'SO', 'AR', | ||
| - 'ARFLAGS') | ||
| + (cc, cxx, ccshared, ldshared, ldcxxshared, so_ext, ar, ar_flags) = \ | ||
| + get_config_vars('CC', 'CXX', 'CCSHARED', 'LDSHARED', 'LDCXXSHARED', | ||
| + 'SO', 'AR', 'ARFLAGS') | ||
| + | ||
| + cflags = '' | ||
| + cxxflags = '' | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand this part very well. The hunk of the original patch that I removed, namely: seems to set CFLAGS in these config vars, however this chunk seems to make it so that the CFLAGS value from the makefile is ignored. So this looks like an inconsistency in original patch. Perhaps a gentoo bug https://bugs.gentoo.org/show_bug.cgi?id=548776 needs to be tried out. |
||
|
|
||
| if 'CC' in os.environ: | ||
| newcc = os.environ['CC'] | ||
| @@ -188,19 +190,27 @@ | ||
| cxx = os.environ['CXX'] | ||
| if 'LDSHARED' in os.environ: | ||
| ldshared = os.environ['LDSHARED'] | ||
| + if 'LDCXXSHARED' in os.environ: | ||
| + ldcxxshared = os.environ['LDCXXSHARED'] | ||
| if 'CPP' in os.environ: | ||
| cpp = os.environ['CPP'] | ||
| else: | ||
| cpp = cc + " -E" # not always | ||
| if 'LDFLAGS' in os.environ: | ||
| ldshared = ldshared + ' ' + os.environ['LDFLAGS'] | ||
| + ldcxxshared = ldcxxshared + ' ' + os.environ['LDFLAGS'] | ||
| if 'CFLAGS' in os.environ: | ||
| - cflags = opt + ' ' + os.environ['CFLAGS'] | ||
| + cflags = os.environ['CFLAGS'] | ||
| ldshared = ldshared + ' ' + os.environ['CFLAGS'] | ||
| + if 'CXXFLAGS' in os.environ: | ||
| + cxxflags = os.environ['CXXFLAGS'] | ||
| + ldcxxshared = ldcxxshared + ' ' + os.environ['CXXFLAGS'] | ||
| if 'CPPFLAGS' in os.environ: | ||
| cpp = cpp + ' ' + os.environ['CPPFLAGS'] | ||
| cflags = cflags + ' ' + os.environ['CPPFLAGS'] | ||
| + cxxflags = cxxflags + ' ' + os.environ['CPPFLAGS'] | ||
| ldshared = ldshared + ' ' + os.environ['CPPFLAGS'] | ||
| + ldcxxshared = ldcxxshared + ' ' + os.environ['CPPFLAGS'] | ||
| if 'AR' in os.environ: | ||
| ar = os.environ['AR'] | ||
| if 'ARFLAGS' in os.environ: | ||
| @@ -209,13 +219,17 @@ | ||
| archiver = ar + ' ' + ar_flags | ||
|
|
||
| cc_cmd = cc + ' ' + cflags | ||
| + cxx_cmd = cxx + ' ' + cxxflags | ||
| compiler.set_executables( | ||
| preprocessor=cpp, | ||
| compiler=cc_cmd, | ||
| compiler_so=cc_cmd + ' ' + ccshared, | ||
| - compiler_cxx=cxx, | ||
| + compiler_cxx=cxx_cmd, | ||
| + compiler_so_cxx=cxx_cmd + ' ' + ccshared, | ||
| linker_so=ldshared, | ||
| linker_exe=cc, | ||
| + linker_so_cxx=ldcxxshared, | ||
| + linker_exe_cxx=cxx, | ||
| archiver=archiver) | ||
|
|
||
| compiler.shared_lib_extension = so_ext | ||
| --- a/Lib/distutils/unixccompiler.py | ||
| +++ b/Lib/distutils/unixccompiler.py | ||
| @@ -55,14 +55,17 @@ | ||
| # are pretty generic; they will probably have to be set by an outsider | ||
| # (eg. using information discovered by the sysconfig about building | ||
| # Python extensions). | ||
| - executables = {'preprocessor' : None, | ||
| - 'compiler' : ["cc"], | ||
| - 'compiler_so' : ["cc"], | ||
| - 'compiler_cxx' : ["cc"], | ||
| - 'linker_so' : ["cc", "-shared"], | ||
| - 'linker_exe' : ["cc"], | ||
| - 'archiver' : ["ar", "-cr"], | ||
| - 'ranlib' : None, | ||
| + executables = {'preprocessor' : None, | ||
| + 'compiler' : ["cc"], | ||
| + 'compiler_so' : ["cc"], | ||
| + 'compiler_cxx' : ["c++"], | ||
| + 'compiler_so_cxx' : ["c++"], | ||
| + 'linker_so' : ["cc", "-shared"], | ||
| + 'linker_exe' : ["cc"], | ||
| + 'linker_so_cxx' : ["c++", "-shared"], | ||
| + 'linker_exe_cxx' : ["c++"], | ||
| + 'archiver' : ["ar", "-cr"], | ||
| + 'ranlib' : None, | ||
| } | ||
|
|
||
| if sys.platform[:6] == "darwin": | ||
| @@ -112,12 +115,19 @@ | ||
|
|
||
| def _compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts): | ||
| compiler_so = self.compiler_so | ||
| + compiler_so_cxx = self.compiler_so_cxx | ||
| if sys.platform == 'darwin': | ||
| compiler_so = _osx_support.compiler_fixup(compiler_so, | ||
| cc_args + extra_postargs) | ||
| + compiler_so_cxx = _osx_support.compiler_fixup(compiler_so_cxx, | ||
| + cc_args + extra_postargs) | ||
| try: | ||
| - self.spawn(compiler_so + cc_args + [src, '-o', obj] + | ||
| - extra_postargs) | ||
| + if self.detect_language(src) == 'c++': | ||
| + self.spawn(compiler_so_cxx + cc_args + [src, '-o', obj] + | ||
| + extra_postargs) | ||
| + else: | ||
| + self.spawn(compiler_so + cc_args + [src, '-o', obj] + | ||
| + extra_postargs) | ||
| except DistutilsExecError, msg: | ||
| raise CompileError, msg | ||
|
|
||
| @@ -174,23 +184,16 @@ | ||
| ld_args.extend(extra_postargs) | ||
| self.mkpath(os.path.dirname(output_filename)) | ||
| try: | ||
| - if target_desc == CCompiler.EXECUTABLE: | ||
| - linker = self.linker_exe[:] | ||
| + if target_lang == "c++": | ||
| + if target_desc == CCompiler.EXECUTABLE: | ||
| + linker = self.linker_exe_cxx[:] | ||
| + else: | ||
| + linker = self.linker_so_cxx[:] | ||
| else: | ||
| - linker = self.linker_so[:] | ||
| - if target_lang == "c++" and self.compiler_cxx: | ||
| - # skip over environment variable settings if /usr/bin/env | ||
| - # is used to set up the linker's environment. | ||
| - # This is needed on OSX. Note: this assumes that the | ||
| - # normal and C++ compiler have the same environment | ||
| - # settings. | ||
| - i = 0 | ||
| - if os.path.basename(linker[0]) == "env": | ||
| - i = 1 | ||
| - while '=' in linker[i]: | ||
| - i = i + 1 | ||
| - | ||
| - linker[i] = self.compiler_cxx[i] | ||
| + if target_desc == CCompiler.EXECUTABLE: | ||
| + linker = self.linker_exe[:] | ||
| + else: | ||
| + linker = self.linker_so[:] | ||
|
|
||
| if sys.platform == 'darwin': | ||
| linker = _osx_support.compiler_fixup(linker, ld_args) | ||
| --- a/Lib/_osx_support.py | ||
| +++ b/Lib/_osx_support.py | ||
| @@ -14,13 +14,13 @@ | ||
| # configuration variables that may contain universal build flags, | ||
| # like "-arch" or "-isdkroot", that may need customization for | ||
| # the user environment | ||
| -_UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'LDFLAGS', 'CPPFLAGS', 'BASECFLAGS', | ||
| - 'BLDSHARED', 'LDSHARED', 'CC', 'CXX', | ||
| - 'PY_CFLAGS', 'PY_LDFLAGS', 'PY_CPPFLAGS', | ||
| - 'PY_CORE_CFLAGS') | ||
| +_UNIVERSAL_CONFIG_VARS = ('CFLAGS', 'CXXFLAGS', 'LDFLAGS', 'CPPFLAGS', | ||
| + 'BASECFLAGS', 'BLDSHARED', 'LDSHARED', 'LDCXXSHARED', | ||
| + 'CC', 'CXX', 'PY_CFLAGS', 'PY_LDFLAGS', | ||
| + 'PY_CPPFLAGS', 'PY_CORE_CFLAGS') | ||
|
|
||
| # configuration variables that may contain compiler calls | ||
| -_COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'CC', 'CXX') | ||
| +_COMPILER_CONFIG_VARS = ('BLDSHARED', 'LDSHARED', 'LDCXXSHARED', 'CC', 'CXX') | ||
|
|
||
| # prefix added to original configuration variable names | ||
| _INITPRE = '_OSX_SUPPORT_INITIAL_' | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| diff --git a/tests/run/numpy_math.pyx b/tests/run/numpy_math.pyx | ||
| index eafd23a..4a15522 100644 | ||
| --- a/tests/run/numpy_math.pyx | ||
| +++ b/tests/run/numpy_math.pyx | ||
| @@ -37,8 +37,8 @@ def test_fp_classif(): | ||
| assert not npmath.isnan(d_zero) | ||
| assert not npmath.isnan(f_zero) | ||
|
|
||
| - assert npmath.isinf(npmath.INFINITY) == 1 | ||
| - assert npmath.isinf(-npmath.INFINITY) == -1 | ||
| + assert npmath.isinf(npmath.INFINITY) != 0 | ||
| + assert npmath.isinf(-npmath.INFINITY) != 0 | ||
| assert npmath.isnan(npmath.NAN) | ||
|
|
||
| assert npmath.signbit(npmath.copysign(1., -1.)) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| diff --git a/numpy/distutils/unixccompiler.py b/numpy/distutils/unixccompiler.py | ||
| index a92ccd3..9630e91 100644 | ||
| --- a/numpy/distutils/unixccompiler.py | ||
| +++ b/numpy/distutils/unixccompiler.py | ||
| @@ -43,10 +43,15 @@ def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts | ||
| if opt not in llink_s: | ||
| self.linker_so = llink_s.split() + opt.split() | ||
|
|
||
| - display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src) | ||
| try: | ||
| - self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + | ||
| - extra_postargs, display = display) | ||
| + if self.detect_language(src) == 'c++': | ||
| + display = '%s: %s' % (os.path.basename(self.compiler_so_cxx[0]), src) | ||
| + self.spawn(self.compiler_so_cxx + cc_args + [src, '-o', obj] + | ||
| + extra_postargs, display = display) | ||
| + else: | ||
| + display = '%s: %s' % (os.path.basename(self.compiler_so[0]), src) | ||
| + self.spawn(self.compiler_so + cc_args + [src, '-o', obj] + | ||
| + extra_postargs, display = display) | ||
| except DistutilsExecError: | ||
| msg = str(get_exception()) | ||
| raise CompileError(msg) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| {lib, python, buildPythonPackage, isPyPy, gfortran, nose, blas}: | ||
| {lib, python, buildPythonPackage, isPy27, isPyPy, gfortran, nose, blas}: | ||
|
|
||
| args: | ||
|
|
||
|
|
@@ -12,6 +12,12 @@ in buildPythonPackage (args // rec { | |
| buildInputs = args.buildInputs or [ gfortran nose ]; | ||
| propagatedBuildInputs = args.propagatedBuildInputs or [ passthru.blas ]; | ||
|
|
||
| patches = lib.optionals isPy27 [ | ||
| # See cpython 2.7 patches. | ||
| # numpy.distutils is used by cython during it's check phase | ||
| ./numpy-distutils-C++.patch | ||
|
||
| ]; | ||
|
|
||
| preConfigure = '' | ||
| sed -i 's/-faltivec//' numpy/distutils/system_info.py | ||
| ''; | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -4146,9 +4146,16 @@ in { | |
| # For testing | ||
| nativeBuildInputs = with self; [ numpy pkgs.ncurses ]; | ||
|
|
||
| # cython's testsuite requires npy_isinf to return sign of the infinity, but | ||
| # a C99 conformant is only required to return a non zero value | ||
| patches = [ ../development/python-modules/cython_test.patch ]; | ||
|
||
|
|
||
| # cython's testsuite is not working very well with libc++ | ||
| # We are however optimistic about things outside of testsuite still working | ||
| checkPhase = '' | ||
| export HOME="$NIX_BUILD_TOP" | ||
| ${python.interpreter} runtests.py | ||
| ${python.interpreter} runtests.py \ | ||
| ${if stdenv.cc.isClang or false then ''--exclude="(cpdef_extern_func|libcpp_algo)"'' else ""} | ||
| ''; | ||
|
|
||
| meta = { | ||
|
|
||
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.
Is this patch accepted upstream? How does this affect non-Darwin? Does this fix anything on non-Darwin?
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.
and how about other Python versions?
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.
You can see in the original issue http://bugs.python.org/issue1222585 that distutils were considered frozen at the time, so this has became a won't fix. This Arfrever person was maintaining it outside of the source tree. The patch is supposed to fix things that get compiled with non-gcc on any platform, but the main target is of course Darwin.
There are also patches presented for python 3.3 and 3.4, it doesn't look like it made to python 3.5. I personally don't consciously use any python3 software and I don't know if they use distutils or if they use C++ code at all.
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.
If its not accepted upstream, then I think we should only use it when it is necessary. If I understand correctly, it is necessary on Darwin, so I suggest using an
optional stdenv.isDarwinfor appending this patch and the others as well.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.
How about
optional !(stdenv.cc.isGCC or false)?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.
That's fine as well.
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 don't understand the "or false" part. Wouldn't
!(stdenv.cc.isGCC)yield the same result?Uh oh!
There was an error while loading. Please reload this page.
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.
or falseis a special syntax for the case when isGNU is not defined to prevent evaluation from failing