Message239934
Let me try and explain what is trying to be done in the original code,
what the fix was, and then discuss some possible better solutions.
Original code:
if target_lang == "c++" and self.compiler_cxx:
linker[0] = self.compiler_cxx[0]
Current code:
if target_lang == "c++" and self.compiler_cxx:
i = 0
if os.path.basename(linker[0]) == "env":
i = 1
while '=' in linker[i]:
i += 1
linker[i] = self.compiler_cxx[i]
Basically, what we have, is two variables, linker, and self.compiler_cxx.
By default on my linux system these are:
linker=['gcc', '-pthread', '-shared']
self.compiler_cxx=['g++', '-pthread']
So under the current code, since self.compiler_cxx[0] != "env"
i=0 so
linker[0] = self.compiler_cxx[0]
so linker=['g++', '-pthread', '-shared']
So the goal is to switch the linker to something that works better with c++.
In the original code:
linker[0] = self.compiler_cxx[0]
improves things if the first element in the linker variable is the linker executable, and the first element in compiler_cxx is a compiler executable, and the compiler executable works better at linking c++ code than the c linker executable.
Next we switch to the current code.
I am guessing that Ronald had something like this:
linker=['env','BAR=FOO','gcc', '-pthread', '-shared']
self.compiler_cxx=['env','BAR=FOO','g++', '-pthread']
and so with the current code we end up with i=2, and the linker variable ends up with:
linker=['env','BAR=FOO','g++', '-pthread', '-shared']
Now, what is the problem we are encountering with the current code?
Basically, people want to use things like CXX="ccache g++"
So if
linker=['gcc', '-pthread', '-shared']
self.compiler_cxx=['ccache', 'g++']
we have i=0,
linker[0]=self.compiler_cxx[0] = 'ccache'
resulting in
linker=['ccache', '-pthread', '-shared']
which will fail, because ccache expects the first argument to be the compiler executable (that is 'g++' not '-pthread')
So, how can we fix this?
If the linker can link c++ code, then the optimal solution is to do nothing,
as in remove the entire
if target_lang == "c++" and self.compiler_cxx:
...
(The fix-distutils-* patches I have created do this solution)
We could special case ccache:
if target_lang == "c++" and self.compiler_cxx:
if os.path.basename(self.compiler_cxx[0]) == "ccache":
linker[0:1] = self.compiler_cxx[0:2]
elif os.path.basename(linker[0]) == "env":
...
We could hope that what we actually want is the entire compiler_cxx:
if target_lang == "c++" and self.compiler_cxx:
linker[0:1] = self.compiler_cxx[:]
Maybe we could special case c++ a little earlier (since linker_exe is just cc by default):
if target_desc == CCompiler.EXECUTABLE and target_lang == "c++" and self.compiler_cxx:
linker = self.compiler_cxx[:]
elif target_desc == CCompiler.EXECUTABLE:
linker = self.linker_exe[:]
else:
linker = self.linker_so[:]
None of these solutions make me feel awesome.
The real problem is that we have no way to set the c++ linker. I don't see any variable listed like this Make's implicit variables section.
A secondary problem is that we string concatenate the LDSHARED and LDFLAGS
(in the line: ldshared = ldshared + ' ' + os.environ['LDFLAGS'] in sysconfig.py)
Another secondary problem is that we don't look for a CXXFLAGS varible, and so people stuff parameters into CXX instead.
If the two secondary issues did not exist we could reasonably reliably do something like
linker = cxx + ldflags
which might actually work for all the cases that are currently covered and work where cxx=['ccache','g++']
The current code is broken, how do we want to fix it? |
|
Date |
User |
Action |
Args |
2015-04-02 17:49:29 | Joshua.J.Cogliati | set | recipients:
+ Joshua.J.Cogliati, ronaldoussoren, tarek, ned.deily, eric.araujo, jrincayc, Xuefer.x, Alexander.Sulfrian, dstufft |
2015-04-02 17:49:29 | Joshua.J.Cogliati | set | messageid: <1427996969.51.0.0201883208751.issue8027@psf.upfronthosting.co.za> |
2015-04-02 17:49:29 | Joshua.J.Cogliati | link | issue8027 messages |
2015-04-02 17:49:28 | Joshua.J.Cogliati | create | |
|