aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md92
-rw-r--r--default.bld60
-rw-r--r--docs/build-manual.tex134
-rw-r--r--pkg.bld6
-rw-r--r--src/build.l4
5 files changed, 293 insertions, 3 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..3b055fb
--- /dev/null
+++ b/README.md
@@ -0,0 +1,92 @@
1# Build
2
3Xagasoft Build is a comprehensive build tool for nearly any multi-step
4automation process, but is intended primarily for compiling source code.
5
6Features:
7
8 * Does _NOT_ rely on make of any sort.
9 * Can auto-generate targets based on builtin and user proided rules.
10 * Contains it's own turing complete scripting language.
11 * Provides a variety of output modes to make errors easier to see.
12 * Supports plugins.
13 * Write much, much less and do more.
14 * Builtin understanding of dependancy tracking.
15
16## Requirements
17
18There are different requirements depending on how you got your source code and
19what you intend to do with it. If you just want to use build, then I recommend
20getting one of the release tarballs. They include most of the dependancies and
21are the easiest to use.
22
23### Tarball Releases
24
25To compile a tarball release you need:
26
27 * bash (or similar)
28 * C++ compiler (gcc is the primary development target)
29 * libc with pthreads and libdl support (glibc and most compatibles)
30
31### SCM Checkouts
32
33If you're getting the code from source control or want to do more there are
34these additional requirements:
35
36 * flex
37 * bison
38
39The flex and bison source code are pre-processed into C source code for the
40tarballs, so you do not need these programs in order to compile.
41
42Build also relies on libbu++, but the shell script 'build.sh' will check out
43the files it needs from libbu++ SVN. These files are also included in the
44tarball release.
45
46Build also builds the easiest when using build. Once you have a working
47version of build it's very easy to keep working on build.
48
49# Example Build Scripts
50
51Just to give you a taste, here are some real, simple build scripts.
52
53 target "filescan"
54 {
55 rule "exe";
56 input files("src/*.cpp");
57 CXXFLAGS += "-ggdb";
58 LDFLAGS += "-lbu++";
59 }
60
61Build has sensible defaults for many things, this creates an explicit target
62named filescan that relies on the source code in the directory src. It adds
63debugging flags, and it links libbu++.
64
65The build system uses a variation on a standard boolean transitive closure
66algorithm to provide "path-finding" between the .cpp files and the inputs the
67"exe" rule needs to create output. In this case it will automatically create
68targets needed to produce all of the object code.
69
70 CXXFLAGS += "-ggdb -I. -Ilibgats";
71 LDFLAGS += "-ggdb";
72
73 target "libjove.a"
74 {
75 rule "lib";
76 input files("src/libjove/*.cpp");
77 }
78
79 target "joved"
80 {
81 rule "exe";
82 input files("src/joved/*.cpp");
83 requires "libjove.a";
84
85 LDFLAGS += "-L. -ljove -lbu++ -Llibgats -lgats -lcryptopp -lpthread";
86 }
87
88This example is slightly more complex. It sets some flags that all targets will
89use, then creates two explicit targets. The second target, joved, also
90requires that libjove.a is up to date, but it is not treated as an input. This
91is enough to determine order of building, all source files, targets, and even
92provides full dependancy tracking.
diff --git a/default.bld b/default.bld
index d88f3cd..467274b 100644
--- a/default.bld
+++ b/default.bld
@@ -9,6 +9,11 @@ CXXFLAGS += "-ggdb -W -Wall";
9 9
10CC = CXX; // We actually want to use c++ to compile our c files. 10CC = CXX; // We actually want to use c++ to compile our c files.
11 11
12if PREFIX == null then
13{
14 PREFIX = "/usr/local";
15}
16
12action "default" 17action "default"
13{ 18{
14 build: ["build", targets("plugins")]; 19 build: ["build", targets("plugins")];
@@ -24,6 +29,11 @@ action "clean"
24 clean: "build"; 29 clean: "build";
25} 30}
26 31
32action "docs"
33{
34 build: targets("docs");
35}
36
27action "devinstall" 37action "devinstall"
28{ 38{
29 if "$(id -u)" != "0" then 39 if "$(id -u)" != "0" then
@@ -106,3 +116,53 @@ for vimdir in dirs("/usr/share/vim/vim*") do
106 } 116 }
107} 117}
108 118
119target "docs/build-manual.pdf"
120{
121 display "pdflatex";
122 tag "docs";
123 profile "build"
124 {
125 condition always;
126 execute("mkdir -p docs/pdf");
127 // You have to do this multiple times to get the TOC right.
128 for j in range(1,3) do
129 {
130 notice "Pass ${j}...";
131 execute("cd docs/pdf; pdflatex ../build-manual.tex > /dev/null");
132 }
133 execute("mv docs/pdf/build-manual.pdf docs");
134 execute("rm -Rf docs/pdf");
135 }
136}
137
138target "docs/html-single/build-manual.html"
139{
140 display "htlatex";
141 tag "docs";
142 profile "build"
143 {
144 condition always;
145 execute("mkdir -p docs/html-single");
146 execute("cd docs/html-single; htlatex ../build-manual.tex > /dev/null");
147 }
148 profile "clean"
149 {
150 execute("rm -Rf docs/html-single");
151 }
152}
153
154target "docs/html-multi"
155{
156 display "htlatex";
157 tag "docs";
158 profile "build"
159 {
160 condition always;
161 execute("mkdir -p docs/html-multi");
162 execute("cd docs/html-multi; htlatex ../build-manual.tex \"html,3\" > /dev/null");
163 }
164 profile "clean"
165 {
166 execute("rm -Rf docs/html-multi");
167 }
168}
diff --git a/docs/build-manual.tex b/docs/build-manual.tex
new file mode 100644
index 0000000..a85c20e
--- /dev/null
+++ b/docs/build-manual.tex
@@ -0,0 +1,134 @@
1\documentclass[letterpaper]{book}
2\usepackage{listings}
3\begin{document}
4
5\title{Xagasoft Build Manual}
6\author{Mike Buland}
7\date{November 2012}
8\maketitle
9
10\tableofcontents
11
12\chapter{Introduction}
13Build is a self-contained, sophisticated tool for performing multi-step
14processes. The primary goal is to be able to replace the standard
15configure/make or cmake/make systems that have become quite popular.
16
17By default Build will work much as one would expect for compiling software, it
18uses file exisistance and timestamps to determine what to build, and every file
19has a list of dependant files and input files.
20
21However, this is only the default configuration, you can use anything as the
22condition for determining what to build or rebuild, and targets do not have to
23be files.
24
25Build boasts a sophisticated system for chaining rules together to take files
26through as many steps as necesarry to get them in the desirable foramt for input
27to the final step. This may sound a little vague and confusing, but what it
28means in the end is that you can list, say, a bison file as on input to an
29executable target that requires object (.o) files. In this case build will
30automatically figure out that it can get a .c file from the .y input file, and
31a .o file from the .c file. It will autogenerate these targets for you and
32save a lot of time and effort on your part.
33
34\chapter{Structure of a Build File}
35Build files contain build script along with four major types of declerations.
36These are the major types that can be decared:
37
38\begin{description}
39 \item[Targets] \hfill \\
40 Explicit targets can be defined that represent units of work with a definate
41 goal and possibly inputs that can be other targets.
42 \item[Actions] \hfill \\
43 Actions are triggered from the command line and determine what targets to
44 build and how.
45 \item[Rules] \hfill \\
46 Rules determine both how to build explicit targets to make life easier as
47 well as how to auto-generate implicit targets. An explicitly defined target
48 does not need to use a rule, but it can make everything easier.
49 \item[Functions] \hfill \\
50 Functions can be defined like in most programming languages, and called
51 anywhere in the script. Functions can also be used in several key places in
52 targets to extend the functionality of build.
53\end{description}
54
55Build script also allows you to declare and use variables like many other
56scripting languages, which can be integers, floats, booleans, strings, lists,
57the special value null, and file handles.
58
59\section{A Quick Example}
60Let's start with a very basic example. This example is capable of building an
61executable from any number of cpp source files:
62
63\begin{lstlisting}
64target "myprogram"
65{
66 rule "exe";
67 input files("src/*.cpp");
68}
69\end{lstlisting}
70
71This example doesn't set any special compliation or linking flags, but it is a
72complete and valid build file. It will find all cpp files in src, generate an
73implicit target for each file to compile it into an object (.o) file, and then
74use those files as the input to the myprogram target in the end.
75
76\section{Targets}
77A target represents a unit of work. This is usually a file in a compilation
78process, e.g. an object file, an executable, a library, et cetera. Targets
79come in two major flavors: explicit and implicit. Explicit targets are any
80targets that you define in a build script with the "target" keyword. Targets
81can also be auto-generated by rules when needed, these are known as implicit
82targets.
83
84If a target is declared more than once the two targets are merged. You can
85think of this as a newer target overriding \emph{parts} of an older target. It
86does not replace the previous target.
87
88Targets can be declared inside of any linguistic construct, including if blocks
89and loops, this gives you a lot of flexibility, but in addition, you can
90specify a list of strings instead of a single string for the name of a target,
91this creates a target with the same specs for each name in the list.
92
93Targets can contain the following special keywords:
94
95\begin{description}
96 \item[input] \hfill \\
97 You can specify any expression that results in a string or list of strings.
98 These strings will be added to the list of inputs to this target, and if
99 they are targets they will be added as dependancies. If you have a rule
100 specified then the list of inputs will be used to generate implicit targets
101 to satisfy dependancies.
102 \item[requires] \hfill \\
103 \item[profile] \hfill \\
104 \item[rule] \hfill \\
105 \item[tag] \hfill \\
106 \item[display] \hfill \\
107\end{description}
108
109
110\section{Actions}
111Actions are the primary interface to build scripts from the command line, when
112calling build you specify an action to run. If no action is specified on the
113command line the action "default" is run. If the build script doesn't specify
114a default action, one is generated for it that will attempt to build all
115explicit targets.
116
117Actions can contain almost any build script, plus an extra syntax that allows
118you to process a list of targets in a given profile (see the targets section
119for details). Basically this means that you have a lot of flexibility
120controlling how your targets are processed.
121
122Let's start with an example:
123
124\begin{lstlisting}
125action "default"
126{
127 build: "myprogram";
128}
129\end{lstlisting}
130
131This is as basic as it gets, this example will cause build to process the
132target "myprogram" using the profile "build".
133
134\end{document}
diff --git a/pkg.bld b/pkg.bld
index 1f0e8f3..30c9668 100644
--- a/pkg.bld
+++ b/pkg.bld
@@ -22,6 +22,9 @@ target PKG_BASE
22 files("*.bld"), 22 files("*.bld"),
23 "docs/build.1", 23 "docs/build.1",
24 "docs/build.7", 24 "docs/build.7",
25 files("docs/build-manual.*"),
26 files("docs/html-multi/*"),
27 files("docs/html-single/*"),
25 "build.sh", 28 "build.sh",
26 "version", 29 "version",
27 "support/vim/syntax/build.vim", 30 "support/vim/syntax/build.vim",
@@ -79,7 +82,8 @@ target PKG_BASE + ".xz"
79rule "tarball" 82rule "tarball"
80{ 83{
81 input matches("*.cpp", "*.h", "*.c", "*.y", "*.l", "*.bld", "Doxyfile", 84 input matches("*.cpp", "*.h", "*.c", "*.y", "*.l", "*.bld", "Doxyfile",
82 "*.1", "*.7", "*.vim", "*.sh", "version"); 85 "*.1", "*.7", "*.vim", "*.sh", "version", "*.tex", "*.pdf", "*.html",
86 "*.css");
83 profile "build" 87 profile "build"
84 { 88 {
85 OUTDIR = OUTPUT.replace(".tar",""); 89 OUTDIR = OUTPUT.replace(".tar","");
diff --git a/src/build.l b/src/build.l
index 30c79a6..7a77bfc 100644
--- a/src/build.l
+++ b/src/build.l
@@ -140,12 +140,12 @@ int iStrDepth = 0;
140 return LTR_UNDEF; 140 return LTR_UNDEF;
141} 141}
142 142
143-?([1-9][0-9]*)|(0) { 143([1-9][0-9]*)|(0) {
144 yylval->iVal = strtol( yytext, NULL, 10 ); 144 yylval->iVal = strtol( yytext, NULL, 10 );
145 return LTR_INT; 145 return LTR_INT;
146} 146}
147 147
148(0\.0+)|(-?(([1-9][0-9]*)|(0))\.[0-9]*) { 148(0\.0+)|((([1-9][0-9]*)|(0))\.[0-9]*) {
149 yylval->fVal = strtof( yytext, NULL ); 149 yylval->fVal = strtof( yytext, NULL );
150 return LTR_FLOAT; 150 return LTR_FLOAT;
151} 151}