<div dir="ltr"><br><div class="gmail_extra"><div class="gmail_quote">On Sat, Mar 12, 2016 at 6:38 AM, Martin Panter <span dir="ltr"><<a href="mailto:vadmium+py@gmail.com" target="_blank">vadmium+py@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Hi Russell. Sorry for the minor ~1 month delay in replying :)<br>
<br>
I have been doing some experimenting to see what is involved in<br>
cross-compiling Python (Native host = Linux, target = Windows via<br>
mingw and some patches). So I have a slightly better understanding of<br>
the problem than before.<br>
<br>
On 16 February 2016 at 01:41, Russell Keith-Magee<br>
<span class=""><<a href="mailto:russell@keith-magee.com">russell@keith-magee.com</a>> wrote:<br>
> In order to build for a host platform, you have to compile for a local<br>
> platform first - for example, to compile an iOS ARM64 binary, you have to<br>
> compile for OS X x86_64 first. This gives you a local platform version of<br>
> Python you can use when building the iOS version.<br>
><br>
> Early in the Makefile, the variable PYTHON_FOR_BUILD is set. This points at<br>
> the CPU-local version of Python that can be invoked, which is used for<br>
> module builds, and for compiling the standard library source code. This is<br>
> set by —host and —build flags to configure, plus the use of CC and LDFLAGS<br>
> environment variables to point at the compiler and libraries for the<br>
> platform you’re compiling for, and a PATH variable that provides the local<br>
> platform’s version of Python.<br>
<br>
</span>So far I haven’t succeeded with my Min GW cross build and am<br>
temporarily giving up due to incompatibilities. But my attempts looked<br>
a bit like this:<br>
<br>
make clean  # Work around confusion with existing in-source build<br>
mkdir native<br>
(cd native/ && ../configure)<br>
make -C native/ Parser/pgen<br>
mkdir mingw<br>
(cd mingw/ && ../configure --host=i486-mingw32 --build=x86)<br>
make -C mingw/ PGEN=../native/Parser/pgen<br>
<br>
Actually it was not as smooth as the above commands, because pgen<br>
tends to get overwritten with a cross-compiled version. Perhaps we<br>
could add a PGEN_FOR_BUILD override, like HOSTPGEN in the patch used<br>
at <<a href="https://wayback.archive.org/web/20160131224915/http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html" rel="noreferrer" target="_blank">https://wayback.archive.org/web/20160131224915/http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html</a>>.<br>
<span class=""><br></span></blockquote><div>That might fix the pgen problem,  but _freeze_importlib still remains. I suppose the same thing might be possible for _freeze_importlib as well…</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> There are two places where special handling is required: the compilation and<br>
> execution of the parser generator, and _freeze_importlib. In both cases, the<br>
> tool needs to be compiled for the local platform, and then executed.<br>
> Historically (i.e., Py3.4 and earlier), this has been done by spawning a<br>
> child MAKE to compile the tool; this runs the compilation phase with the<br>
> local CPU environment, before returning to the master makefile and executing<br>
> the tool. By spawning the child MAKE, you get a “clean” environment, so the<br>
> tool is built natively. However, as I understand it, it causes problems with<br>
> parallel builds due to race conditions on build rules. The change in<br>
> Python3.5 simplified the rule so that child MAKE calls weren’t used, but<br>
> that means that pgen and _freeze_importlib are compiled for ARM64, so they<br>
> won’t run on the local platform.<br>
<br>
</span>You suggest that the child Make command happened to compile pgen etc<br>
natively, rather than with the cross compiler. But my understanding is<br>
that when you invoke $(MAKE), all the environment variables, configure<br>
settings, etc, including the cross compiler, would be inherited by the<br>
child.<br>
<br>
Would it be more correct to say instead that in 3.4 you did a separate<br>
native build step, precompiling pgen and _freeze_importlib for the<br>
native build host? Then you hoped that the child Make was _not_<br>
invoked in the cross-compilation stage and your precompiled<br>
executables would not be rebuilt?<span class=""><br></span></blockquote><div><br></div><div>Yes - as far as I can make out (with my admittedly hazy understanding), that appears to be what is going on. Although it’s not that I “hoped” the build wouldn’t happen on the second pass - it was the behavior that was previously relied, and on was altered.</div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> As best as I can work out, the solution is to:<br>
><br>
> (1) Include the parser generator and _freeze_importlib as part of the<br>
> artefacts of local platform. That way, you could use the version of pgen and<br>
> _freeze_importlib that was compiled as part of the local platform build. At<br>
> present, pgen and _freeze_importlib are used during the build process, but<br>
> aren’t preserved at the end of the build; or<br>
<br>
</span>I don’t understand. After I run Make, it looks like I get working<br>
executables leftover at Programs/_freeze_importlib and Parser/pgen. Do<br>
you mean to install these programs with “make install” or something?<br></blockquote><div><br></div><div>Making them part of the installable artefacts would be one option, but they don’t have to be installed, just preserved.</div><div><br></div><div>For example, as a nasty hack, I’ve been able to use this approach to get the build working for 3.5. After the native build, I copy _freeze_importlib to a “safe” location. I then copy it back into place prior to the target build. It works, but it’s in no way suitable for a final build.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">
> (2) Include some concept of the “local compiler” in the build process, which<br>
> can be used to compile pgen and _freeze_importlib; or<br>
<br>
</span>On the surface solution (2) sounds like the ideal fix. But I guess the<br>
local native compiler might also require a separate set of CPPFLAGS,<br>
pyconfig.h settings etc. In other words it is sounding like a whole<br>
separate “configure” run. I am thinking it might be simplest to just<br>
require this native “configure” run to be done manually.<br>
</blockquote></div><br></div><div class="gmail_extra">That run is going to happen anyway, since you have to compile and build for the native platform. </div><div class="gmail_extra"><br></div><div class="gmail_extra">Yours,</div><div class="gmail_extra">Russ Magee %-)</div></div>