On Mon, Jul 23, 2012 at 8:01 PM, Robert Bradshaw <
robe...@gmail.com> wrote:
> Yep. This is pretty typical (we try hard to make a single .c file that
> can compile in a wide variety of environments) and one of the defects
> of using IF/DEF.
>
> So, if I understand correctly, cythonpp.py propagates #ifdef et al. to
> the .c file. I can see how that would be handy.
Yes, that's what it produces. What it actually does is quite simple:
it generates a Cython source (post-preprocesor) for each possible
configuration and then runs Cython on each of those sources. (which is
slow - as it is exponential to the number of preprocessor variables in
use, but what else you are going to do if you really need that
self-sufficient .c source with platform specific stuff?).
Then it combines all that individual .c files in a single .c file,
generating equivalent of this:
#if ... configuration1 ...
cython output for configuration1
#elif .. configurtation 2 ...
cython output for configuration 2
...
#endif
I said equivalent, because it tries to be smart and excludes common
parts from inside #if.
>> When it's possible to do so, it's great. Some functionality cannot be
>> wrapped though. For instance, you cannot provide a wrapper for fork()
>> on Windows. In such case, you simply remove corresponding
>> functionality from the Python module. In gevent, some functionality is
>> not available on Windows and it looks like this in the source:
>>
https://bitbucket.org/denis/gevent/src/8c9722b1fc2a/gevent/core.ppyx#cl-419
>
> Yes, but defining a child() and install_sigchld() that raise an error
> on Windows and guarding against/avoiding it at runtime will allow you
> to create a .c file that still compiles everywhere.
True, but, arguably, not providing the function/class at all is nicer.
For example, os.fork is not available on Windows, as well as many
other platform-specific functions/classes in Python stdlib.
This allows you to find out that certain functionality is not
available earlier rather than later, e.g.
try:
fork = os.fork
except AttributeError:
fork = None
if fork:
...
else:
...
Cheers,
Denis.