swig generation

Hi all,

I’d like to do a few things with our swig generation and handling:

  • Create a maintainer-mode style setup where the swig Python bindings are generated and checked into the repo (I’ll call it the static python binding).

This will be used by default, removing the need for most people and all builders/bots from having swig on their system just for lldb. In the event that Windows needs a different version (e.g. for, say, Python 3.5 support that is incompatible with the swig-1.3.40-generated bindings), we can support multiple source bindings, or we can post process the swig-1.3.x generated bindings.

We’ll keep them by swig-{swig-major}-{swig-minor}. Internally over at Apple, we will stick with the swig-1.x bindings. I don’t think we will care about the dot release (1.3.40 vs. 1.3.39, for example). We’ll just make sure to use the latest for a {swig-major}.{swig-minor}. As always, SB API changes generated by swig need to remain swig-1.3 compatible (i.e. swig-1.3 must be capable of generating usable Python wrappers).

Ideally we don’t need more than one set of bindings so we can avoid needing to generate multiple ones when we do it.

  • Add an explicit Python binding generation step.

This would only be used by those who are touching the bindings (adding SB API or adjusting the documentation of existing SB API). In the event that we need two bindings, we may just need a handshake that says “okay, we’ll take care of the swig 1.3 bindings, and {somebody who needs the other binding} generates it for the other.” As SBAPI is additive only, this should generally be fine as the worst case I can think of that would happen would be failure to see new SBAPI in Python for a very brief time. Since maintainers will be writing Python tests to check their new SBAPIs, failure to do the explicit generation step will be immediately obvious as a test failure. (The challenge here will likely be the swig 1.3.x requirement).

If generating and testing new binding content with the right swig (i.e. swig 1.3.x) becomes a real issue, we may be able to support a "please use my local swig, whatever it is, but don’t check in the static binding), with a handshake that says "somebody with swig 1.3, please generate the modified binding and check in). We’ll see if this becomes an issue. I don’t see this as insurmountable.

  • Clean up the swig generation scripts

These look to have been implemented as direct ports of the older OS X style bash scripts. This Python script is very much the essence of using the paradigms of one language in another, and being the worse for it. It implements features that are already present in the standard Python lib, and is more verbose than it needs to be.

Also, it is likely the script needs to be broken out into a few parts. The scripts don’t just generate the python binding using swig, they also setup (for OS X) some packaging and other bits. Right now none of that is clearly broken out. When we move to an explicit binding generation mode, this does need to be broken out better.

  • Get OS X Xcode build using the same bindings machinery as others.

I tried this a while back (having Xcode adopt the Python-based swig wrapper handling code), but gave up after hitting a few bugs where the translated behavior was incorrect for Xcode. I will move over to adopting this on Xcode if possible while going through these changes.

The primary goal here is to remove the requirement of having swig on the system (e.g. for builders and most developers), shifting that burden a bit more to those who actually modify the Python binding.

As a potential added benefit, this opens us up to easier modification of that binding generation step, which may prove to be useful later.

Let me know if you have any feedback before I dive into this.

Hi all,

I’d like to do a few things with our swig generation and handling:

  • Create a maintainer-mode style setup where the swig Python bindings are generated and checked into the repo (I’ll call it the static python binding).

This will be used by default, removing the need for most people and all builders/bots from having swig on their system just for lldb. In the event that Windows needs a different version (e.g. for, say, Python 3.5 support that is incompatible with the swig-1.3.40-generated bindings), we can support multiple source bindings, or we can post process the swig-1.3.x generated bindings. We’ll keep them by swig-{swig-major}-{swig-minor}. Internally over at Apple, we will stick with the swig-1.x bindings. I don’t think we will care about the dot release (1.3.40 vs. 1.3.39, for example). We’ll just make sure to use the latest for a {swig-major}.{swig-minor}. As always, SB API changes generated by swig need to remain swig-1.3 compatible (i.e. swig-1.3 must be capable of generating usable Python wrappers).

I know you said you plan to stay on 1.x, but in this world of having SWIG bindings checked in, does that open the door to potentially moving beyond SWIG 1.x for the upstream? I feel like the SWIG 1.x requirement holds the upstream back, because there are a lot of hacks to workaround bugs and limitations in SWIG, and it only understands the absolute most basic C / C++ language constructs. So we end up being limited in how we can design SB APIs, all for reasons that having nothing to do with the upstream project requirements, which is kind of a bummer. It seems like there could be a path here for the upstream to move forward, and anyone who is forced to stay on an earlier version of SWIG could maintain whatever changes are necessary to make this possible in a local repository.

  • Clean up the swig generation scripts

These look to have been implemented as direct ports of the older OS X style bash scripts. This Python script is very much the essence of using the paradigms of one language in another, and being the worse for it. It implements features that are already present in the standard Python lib, and is more verbose than it needs to be.

Ugh, +1000. Every time I have to crack these files open my head explodes. More than happy to help with whatever porting is necessary.

Also, it is likely the script needs to be broken out into a few parts. The scripts don’t just generate the python binding using swig, they also setup (for OS X) some packaging and other bits. Right now none of that is clearly broken out. When we move to an explicit binding generation mode, this does need to be broken out better.

  • Get OS X Xcode build using the same bindings machinery as others.

Yay.

Hi all,

I'd like to do a few things with our swig generation and handling:

* Create a maintainer-mode style setup where the swig Python bindings are
generated and checked into the repo (I'll call it the static python
binding).

This will be used by default, removing the need for most people and all
builders/bots from having swig on their system just for lldb. In the event
that Windows needs a different version (e.g. for, say, Python 3.5 support
that is incompatible with the swig-1.3.40-generated bindings), we can
support multiple source bindings, or we can post process the swig-1.3.x
generated bindings. We'll keep them by swig-{swig-major}-{swig-minor}.
Internally over at Apple, we will stick with the swig-1.x bindings. I
don't think we will care about the dot release (1.3.40 vs. 1.3.39, for
example). We'll just make sure to use the latest for a
{swig-major}.{swig-minor}. As always, SB API changes generated by swig
need to remain swig-1.3 compatible (i.e. swig-1.3 must be capable of
generating usable Python wrappers).

I know you said you plan to stay on 1.x, but in this world of having SWIG
bindings checked in, does that open the door to potentially moving beyond
SWIG 1.x for the upstream? I feel like the SWIG 1.x requirement holds the
upstream back, because there are a lot of hacks to workaround bugs and
limitations in SWIG, and it only understands the absolute most basic C /
C++ language constructs. So we end up being limited in how we can design
SB APIs, all for reasons that having nothing to do with the upstream
project requirements, which is kind of a bummer. It seems like there could
be a path here for the upstream to move forward, and anyone who is forced
to stay on an earlier version of SWIG could maintain whatever changes are
necessary to make this possible in a local repository.

I may leave Greg to discuss that aspect (w/r/t using newer features). The
SB API itself is intended to be a very bare-bones linkage environment that
does not break linkage requirements in ways that typical C++ binary
libraries do (i.e. it does not use virtuals and follows a number of rules
about data members so that it remains binary compatible across
compiler/linker changes).

* Clean up the swig generation scripts

These look to have been implemented as direct ports of the older OS X
style bash scripts. This Python script is very much the essence of using
the paradigms of one language in another, and being the worse for it. It
implements features that are already present in the standard Python lib,
and is more verbose than it needs to be.

Ugh, +1000. Every time I have to crack these files open my head
explodes. More than happy to help with whatever porting is necessary.

Haha that's exactly how I feel :slight_smile:

Hi all,

I'd like to do a few things with our swig generation and handling:

* Create a maintainer-mode style setup where the swig Python bindings
are generated and checked into the repo (I'll call it the static python
binding).

This will be used by default, removing the need for most people and all
builders/bots from having swig on their system just for lldb. In the event
that Windows needs a different version (e.g. for, say, Python 3.5 support
that is incompatible with the swig-1.3.40-generated bindings), we can
support multiple source bindings, or we can post process the swig-1.3.x
generated bindings. We'll keep them by swig-{swig-major}-{swig-minor}.
Internally over at Apple, we will stick with the swig-1.x bindings. I
don't think we will care about the dot release (1.3.40 vs. 1.3.39, for
example). We'll just make sure to use the latest for a
{swig-major}.{swig-minor}. As always, SB API changes generated by swig
need to remain swig-1.3 compatible (i.e. swig-1.3 must be capable of
generating usable Python wrappers).

I know you said you plan to stay on 1.x, but in this world of having SWIG
bindings checked in, does that open the door to potentially moving beyond
SWIG 1.x for the upstream? I feel like the SWIG 1.x requirement holds the
upstream back, because there are a lot of hacks to workaround bugs and
limitations in SWIG,

We do have the ability to post-process this any way we want after the swig
generation. I see no reason why we couldn't get move advanced with what we
post-process, especially since that can be limited to the
maintainer-mode-style "update the static checked-in product after
generating the bindings" step).

I will probably tackle this as two phases:

Phase 1:

  • Python script modernization (the python swig wrapper generation)
  • Move Xcode onto it.

Phase 2:

  • The maintainer-mode, static Python binding generation changes for cmake and Xcode.

I want to make sure we have proven, still-functional Python from the new Python script before we move forward. I will also probably turn on the Green Dragon OS X public builder’s test running at this stage so we can also see that.

And I want to work out any issues with the current script logic and what OS X was doing before shifting any of this around.

There’s a couple of examples that come to mind. C++11 is completely out, for example. In general this isn’t a huge deal. Nobody’s going to be passing rvalue references through the SB API or anything. But even simple things like enum classes are out. 1.x also doesn’t support specifying the underlying type of an enum, because it can’t parse it. In other words, SWIG won’t accept this:

enum Foo : unsigned {
};

This is actually important in MSVC because its algorithm for choosing the underlying type and size of the enum differs from other compilers. We’ve got hundreds of warnings silenced in CMake because of this, and there’s no solution except upgrade SWIG.

We’re also forced to use the archaic “const char* str, int len” syntax for every single string, when we could be passing std strings or llvm StringRefs.

No nested classes, namespace support doesn’t work, and also missing out on a ton of bugfixes and performance improvements of generated code. Many languages like Go aren’t supported in 1.x, etc. If I check the release notes I could probably come up with more examples.

I don’t mean to say that we have to do this with haste or anything, but I think at some point there should probably be a path off of 1.x for the upstream

Hi all,

I'd like to do a few things with our swig generation and handling:

* Create a maintainer-mode style setup where the swig Python bindings are
generated and checked into the repo (I'll call it the static python
binding).

This will be used by default, removing the need for most people and all
builders/bots from having swig on their system just for lldb. In the event
that Windows needs a different version (e.g. for, say, Python 3.5 support
that is incompatible with the swig-1.3.40-generated bindings), we can
support multiple source bindings, or we can post process the swig-1.3.x
generated bindings.

We'll keep them by swig-{swig-major}-{swig-minor}. Internally over at
Apple, we will stick with the swig-1.x bindings. I don't think we will
care about the dot release (1.3.40 vs. 1.3.39, for example). We'll just
make sure to use the latest for a {swig-major}.{swig-minor}. As always, SB
API changes generated by swig need to remain swig-1.3 compatible (i.e.
swig-1.3 must be capable of generating usable Python wrappers).

Ideally we don't need more than one set of bindings so we can avoid
needing to generate multiple ones when we do it.

* Add an explicit Python binding generation step.

This would only be used by those who are touching the bindings (adding SB
API or adjusting the documentation of existing SB API). In the event that
we need two bindings, we may just need a handshake that says "okay, we'll
take care of the swig 1.3 bindings, and {somebody who needs the other
binding} generates it for the other." As SBAPI is additive only, this
should generally be fine as the worst case I can think of that would happen
would be failure to see new SBAPI in Python for a very brief time. Since
maintainers will be writing Python tests to check their new SBAPIs, failure
to do the explicit generation step will be immediately obvious as a test
failure. (The challenge here will likely be the swig 1.3.x requirement).

If generating and testing new binding content with the right swig (i.e.
swig 1.3.x) becomes a real issue, we may be able to support a "please use
my local swig, whatever it is, but don't check in the static binding), with
a handshake that says "somebody with swig 1.3, please generate the modified
binding and check in). We'll see if this becomes an issue. I don't see
this as insurmountable.

* Clean up the swig generation scripts

These look to have been implemented as direct ports of the older OS X
style bash scripts. This Python script is very much the essence of using
the paradigms of one language in another, and being the worse for it. It
implements features that are already present in the standard Python lib,
and is more verbose than it needs to be.

Also, it is likely the script needs to be broken out into a few parts.
The scripts don't just generate the python binding using swig, they also
setup (for OS X) some packaging and other bits. Right now none of that is
clearly broken out. When we move to an explicit binding generation mode,
this does need to be broken out better.

* Get OS X Xcode build using the same bindings machinery as others.

I tried this a while back (having Xcode adopt the Python-based swig
wrapper handling code), but gave up after hitting a few bugs where the
translated behavior was incorrect for Xcode. I will move over to adopting
this on Xcode if possible while going through these changes.

I've begun this process. I've got Xcode build (and the Xcode build only)
wired up to scripts/prepare_bindings.py. This, and the Python-specific
binding preparation script, are considerably shorter than the older
implementation. It also addresses the bugs that prevented the former from
working with the Xcode build. The new scripts are pylint clean (with
stock configuration) except for a small handful of places that I intend to
revisit when I have a few cycles to really tidy things up. (Right now I'm
just going for the 90% wins).

Tomorrow I will fix up the tail end (the finalization) in a similar manner
and plug it into the Xcode build. I'll also try it locally on Linux and
work out any issues there.

I'll be tackling the static binding area (and will put up for review) only
after I know the cleaned up binding preparation scripts are working
properly everywhere. I just didn't want to tackle that until I really
understood what the scripts were already doing and it was in a state I felt
I could maintain.

Hi all,

I'd like to do a few things with our swig generation and handling:

* Create a maintainer-mode style setup where the swig Python bindings are
generated and checked into the repo (I'll call it the static python
binding).

This will be used by default, removing the need for most people and all
builders/bots from having swig on their system just for lldb. In the event
that Windows needs a different version (e.g. for, say, Python 3.5 support
that is incompatible with the swig-1.3.40-generated bindings), we can
support multiple source bindings, or we can post process the swig-1.3.x
generated bindings.

We'll keep them by swig-{swig-major}-{swig-minor}. Internally over at
Apple, we will stick with the swig-1.x bindings. I don't think we will
care about the dot release (1.3.40 vs. 1.3.39, for example). We'll just
make sure to use the latest for a {swig-major}.{swig-minor}. As always, SB
API changes generated by swig need to remain swig-1.3 compatible (i.e.
swig-1.3 must be capable of generating usable Python wrappers).

Ideally we don't need more than one set of bindings so we can avoid
needing to generate multiple ones when we do it.

* Add an explicit Python binding generation step.

This would only be used by those who are touching the bindings (adding SB
API or adjusting the documentation of existing SB API). In the event that
we need two bindings, we may just need a handshake that says "okay, we'll
take care of the swig 1.3 bindings, and {somebody who needs the other
binding} generates it for the other." As SBAPI is additive only, this
should generally be fine as the worst case I can think of that would happen
would be failure to see new SBAPI in Python for a very brief time. Since
maintainers will be writing Python tests to check their new SBAPIs, failure
to do the explicit generation step will be immediately obvious as a test
failure. (The challenge here will likely be the swig 1.3.x requirement).

If generating and testing new binding content with the right swig (i.e.
swig 1.3.x) becomes a real issue, we may be able to support a "please use
my local swig, whatever it is, but don't check in the static binding), with
a handshake that says "somebody with swig 1.3, please generate the modified
binding and check in). We'll see if this becomes an issue. I don't see
this as insurmountable.

* Clean up the swig generation scripts

These look to have been implemented as direct ports of the older OS X
style bash scripts. This Python script is very much the essence of using
the paradigms of one language in another, and being the worse for it. It
implements features that are already present in the standard Python lib,
and is more verbose than it needs to be.

Also, it is likely the script needs to be broken out into a few parts.
The scripts don't just generate the python binding using swig, they also
setup (for OS X) some packaging and other bits. Right now none of that is
clearly broken out. When we move to an explicit binding generation mode,
this does need to be broken out better.

* Get OS X Xcode build using the same bindings machinery as others.

I tried this a while back (having Xcode adopt the Python-based swig
wrapper handling code), but gave up after hitting a few bugs where the
translated behavior was incorrect for Xcode. I will move over to adopting
this on Xcode if possible while going through these changes.

I've begun this process.

With r253317, that is.