alliedmodders / ambuild

AlliedModders C++ Build System
BSD 3-Clause "New" or "Revised" License
61 stars 32 forks source link

Introduce the AMBuild 2.2 API. #97

Closed dvander closed 4 years ago

dvander commented 4 years ago

The major feature with 2.2 is the ability to run multiple C++ compilers. This is important for supporting mixed builds in one objdir, as it allows us to build unified packages.

We can already do this on Linux/Mac by adding -m32/-m64 to the command-line as needed. But this doesn't work on Windows, where we have to actually invoke separate versions of cl.exe.

Unfortunately, this feature comes at a cost, which is that the API has to change significantly. The concept of a per-builder target no longer makes sense, as the target is now part of the compiler. This means "builder.cxx" has to go away. But fear not, because for simple single-target projects, a new pattern is available:

builder.cxx = builder.DetectCxx()

Build contexts can now hold user attributes, so this "cxx" field can be anything. These attributes are propagated down to child contexts. If one of these values implements ambuild2.frontend.Cloneable (which the Compiler object does), then it will be automatically cloned. This way, changes in the child script do not affect the parent script.

Properties defined this way can shadow the actual build API, but changes to the build API will not break user scripts. Note: this feature allows scripts to migrate off global variables if they wish.

Multiple compilers can now be defined as well:

builder.x86 = builder.DetectCxx(target_arch = 'x86')
builder.x64 = builder.DetectCxx(target_arch = 'x64')

Currently, builtin automatic detection exists for x86/x64 on Windows, as well as all gcc-like compilers. More architectures will be added as needed, and cross-platform support is planned as well.

To facilitate these changes, the output structure has changed slightly. The default objdir is now simply "objdir". The platform and arch tuple are embedded elsewhere. For example,

obj-windows-x86_64/spcomp/spcomp/spcomp.exe

Now becomes:

objdir/spcomp/spcomp/windows-x86_64/spcomp.exe

This way, multiple platforms and architectures can be built side-by-side.

There are a few more small changes to the 2.2 API. The options parser has been switched from optparse to argparse, which will break old configure.py scripts.

A new "HasFeature" method is available on build contexts. As we add new features to the 2.2 API, this will be useful for feature detection.

dvander commented 4 years ago

I was able to port SourcePawn and AMTL over to the new API, so I think this is ready to start dogfooding. I'm going to check this in, then post PRs for AMTL/SP/SM and make sure those are all working and passing CI.

Then, I'll start to write the documentation for the 2.2 API and bump the default version number. There will be a bit of a painful transition as folks will need to update AMBuild to build SourceMod. Maybe we can ease this with checkout-deps.

The oddness of "builder.target" was the only thing that really irked me in the 2.1 API, there's nothing else I can think of that I really want to remove. There are only things I want to add. So, I think it's safe to proceed with making it the default API.