Difference between revisions of "AMBuild Tutorial"

From AlliedModders Wiki
Jump to: navigation, search
Line 25: Line 25:
 
prep = run.PrepareBuild(sys.path[0])
 
prep = run.PrepareBuild(sys.path[0])
 
prep.Configure()
 
prep.Configure()
 +
</pre>
 +
 +
Now, we're ready to actually make a build script for our project. The master build script must be a file called <tt>AMBuildScript</tt>, and it must be written in [http://python.org/ Python] syntax. The full Python API on your system is available to AMBuild scripts, but the important aspect we'll deal with here is the AMBuild API.
 +
 +
The first step is to tell AMBuild to detect the first available C or C++ compiler. This is done with the following line:
 +
<Python>
 +
builder.DetectCompilers()
 +
</Python>
 +
 +
With just this line in your build script, you can now try to configure build. You should see something like:
 +
<pre>
 +
$ mkdir build
 +
$ cd build
 +
$ python ../configure.py
 +
Checking CC compiler (vendor test gcc)... ['cc', 'test.c', '-o', 'test']
 +
found gcc version 4.7
 +
Checking CXX compiler (vendor test gcc)... ['c++', '-fno-exceptions', '-fno-rtti', 'test.cpp', '-o', 'testp']
 +
found gcc version 4.7
 +
$
 +
</pre>
 +
 +
If you get an error - either you don't have a compatible C or C++ compiler installed, or AMBuild has a bug (please [https://bugs.alliedmods.net/ report it!]).
 +
 +
Now, we're ready to complete our AMBuildScript:
 +
<Python>
 +
program = builder.compiler.Program("hello")
 +
program.sources = [
 +
  'main.cpp',
 +
  'helpers.cpp',
 +
]
 +
builder.Add(program)
 +
</Python>
 +
 +
The <tt>builder</tt> object is an instance of an AMBuild ''context'' - more about this is in the [[AMBuild API]] documentation. Every AMBuild script has access to a <tt>builder</tt>. The <tt>builder.compiler</tt> object has information about the C/C++ compiler for the configure session. The <tt>Program()</tt> method will return an object used to create C++ compilation tasks. In this case, we're asking to build an executable that will be named 'hello' (or <tt>hello.exe</tt> on Windows). You can also specified shared libraries with <tt>Library</tt>, and static libraries with <tt>StaticLibrary</tt>.
 +
 +
You can attach a list of source files to your Program via the <tt>sources</tt> attribute. Finally, use <tt>builder.Add</tt> to take your C++ configuration and construct the necessary dependency graph and build steps.
 +
 +
Now, we can actually attempt to build. First, let's make sure AMBuild computed our graph and dependencies correctly:
 +
<pre>
 +
$ python ../configure.py
 +
$ ambuild --show-graph
 +
: mkdir "hello"
 +
- hello/hello
 +
  - c++ main.o helpers.o -o hello
 +
    - hello/main.o
 +
      - [gcc] -> c++ -H -c /home/dvander/projects/ambuild/ambuild2/main.cpp -o main.o
 +
        - /home/dvander/projects/ambuild/ambuild2/main.cpp
 +
    - hello/helpers.o
 +
      - [gcc] -> c++ -H -c /home/dvander/projects/ambuild/ambuild2/helpers.cpp -o helpers.o
 +
        - /home/dvander/projects/ambuild/ambuild2/helpers.cpp
 +
$ ambuild --show-steps
 +
mkdir -p hello
 +
task 0: [gcc] -> c++ -H -c /home/dvander/projects/ambuild/ambuild2/main.cpp -o main.o
 +
  -> hello/main.o
 +
task 1: [gcc] -> c++ -H -c /home/dvander/projects/ambuild/ambuild2/helpers.cpp -o helpers.o
 +
  -> hello/helpers.o
 +
task 2: c++ main.o helpers.o -o hello
 +
  -> hello/hello
 +
</pre>
 +
 +
It looks good! Now we can build:
 +
<pre>
 +
mkdir -p hello
 +
Spawned task master (pid: 15563)
 +
Spawned worker (pid: 15564)
 +
Spawned worker (pid: 15565)
 +
[15564] c++ -H -c /home/dvander/projects/ambuild/ambuild2/helpers.cpp -o helpers.o
 +
[15565] c++ -H -c /home/dvander/projects/ambuild/ambuild2/main.cpp -o main.o
 +
[15565] c++ main.o helpers.o -o hello
 +
[15565] Child process terminating normally.
 +
[15564] Child process terminating normally.
 +
[15563] Child process terminating normally.
 +
Build succeeded.
 
</pre>
 
</pre>

Revision as of 16:26, 15 October 2013

Writing project files with AMBuild is fairly easy. This tutorial will guide you through making simple AMBuild scripts to compile and package a C++ project.

Simple Project

To begin, let's say we have a sample project with the following files:

$ ls
goodbye.cpp  helpers.cpp  README.txt

To start, we need to generate a default AMBuild configure script. This is the script that will perform the "configure" step for your build. You can generate one with the following command:

$ ambuild --gen-configure
$ ls
configure.py  goodbye.cpp  helpers.cpp  README.txt

The configure script simply invokes AMBuild. It can be modified (as we'll see later) to take extra command line options.

$ cat configure.py
# vim: set ts=2 sw=2 tw=99 noet:
import sys, ambuild2.run

prep = run.PrepareBuild(sys.path[0])
prep.Configure()

Now, we're ready to actually make a build script for our project. The master build script must be a file called AMBuildScript, and it must be written in Python syntax. The full Python API on your system is available to AMBuild scripts, but the important aspect we'll deal with here is the AMBuild API.

The first step is to tell AMBuild to detect the first available C or C++ compiler. This is done with the following line:

builder.DetectCompilers()

With just this line in your build script, you can now try to configure build. You should see something like:

$ mkdir build
$ cd build
$ python ../configure.py
Checking CC compiler (vendor test gcc)... ['cc', 'test.c', '-o', 'test']
found gcc version 4.7
Checking CXX compiler (vendor test gcc)... ['c++', '-fno-exceptions', '-fno-rtti', 'test.cpp', '-o', 'testp']
found gcc version 4.7
$

If you get an error - either you don't have a compatible C or C++ compiler installed, or AMBuild has a bug (please report it!).

Now, we're ready to complete our AMBuildScript:

program = builder.compiler.Program("hello")
program.sources = [
  'main.cpp',
  'helpers.cpp',
]
builder.Add(program)

The builder object is an instance of an AMBuild context - more about this is in the AMBuild API documentation. Every AMBuild script has access to a builder. The builder.compiler object has information about the C/C++ compiler for the configure session. The Program() method will return an object used to create C++ compilation tasks. In this case, we're asking to build an executable that will be named 'hello' (or hello.exe on Windows). You can also specified shared libraries with Library, and static libraries with StaticLibrary.

You can attach a list of source files to your Program via the sources attribute. Finally, use builder.Add to take your C++ configuration and construct the necessary dependency graph and build steps.

Now, we can actually attempt to build. First, let's make sure AMBuild computed our graph and dependencies correctly:

$ python ../configure.py
$ ambuild --show-graph
 : mkdir "hello"
 - hello/hello
   - c++ main.o helpers.o -o hello
     - hello/main.o
       - [gcc] -> c++ -H -c /home/dvander/projects/ambuild/ambuild2/main.cpp -o main.o
         - /home/dvander/projects/ambuild/ambuild2/main.cpp
     - hello/helpers.o
       - [gcc] -> c++ -H -c /home/dvander/projects/ambuild/ambuild2/helpers.cpp -o helpers.o
         - /home/dvander/projects/ambuild/ambuild2/helpers.cpp
$ ambuild --show-steps
mkdir -p hello
task 0: [gcc] -> c++ -H -c /home/dvander/projects/ambuild/ambuild2/main.cpp -o main.o
  -> hello/main.o
task 1: [gcc] -> c++ -H -c /home/dvander/projects/ambuild/ambuild2/helpers.cpp -o helpers.o
  -> hello/helpers.o
task 2: c++ main.o helpers.o -o hello
  -> hello/hello

It looks good! Now we can build:

mkdir -p hello
Spawned task master (pid: 15563)
Spawned worker (pid: 15564)
Spawned worker (pid: 15565)
[15564] c++ -H -c /home/dvander/projects/ambuild/ambuild2/helpers.cpp -o helpers.o
[15565] c++ -H -c /home/dvander/projects/ambuild/ambuild2/main.cpp -o main.o
[15565] c++ main.o helpers.o -o hello
[15565] Child process terminating normally.
[15564] Child process terminating normally.
[15563] Child process terminating normally.
Build succeeded.