diff options
author | Mike Buland <eichlan@xagasoft.com> | 2012-11-08 20:38:56 +0000 |
---|---|---|
committer | Mike Buland <eichlan@xagasoft.com> | 2012-11-08 20:38:56 +0000 |
commit | c5d1304f04273b579e00f967ec564a8de3ea0e69 (patch) | |
tree | be6bacefb60a64aef0017f94cd4913d89c6032fe | |
parent | 21cf5c846c1d004da98b4c93715ca44036f7ecd5 (diff) | |
download | build-c5d1304f04273b579e00f967ec564a8de3ea0e69.tar.gz build-c5d1304f04273b579e00f967ec564a8de3ea0e69.tar.bz2 build-c5d1304f04273b579e00f967ec564a8de3ea0e69.tar.xz build-c5d1304f04273b579e00f967ec564a8de3ea0e69.zip |
Packaging updates, started on the manual, too.
-rw-r--r-- | README.md | 92 | ||||
-rw-r--r-- | default.bld | 60 | ||||
-rw-r--r-- | docs/build-manual.tex | 134 | ||||
-rw-r--r-- | pkg.bld | 6 | ||||
-rw-r--r-- | src/build.l | 4 |
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 | |||
3 | Xagasoft Build is a comprehensive build tool for nearly any multi-step | ||
4 | automation process, but is intended primarily for compiling source code. | ||
5 | |||
6 | Features: | ||
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 | |||
18 | There are different requirements depending on how you got your source code and | ||
19 | what you intend to do with it. If you just want to use build, then I recommend | ||
20 | getting one of the release tarballs. They include most of the dependancies and | ||
21 | are the easiest to use. | ||
22 | |||
23 | ### Tarball Releases | ||
24 | |||
25 | To 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 | |||
33 | If you're getting the code from source control or want to do more there are | ||
34 | these additional requirements: | ||
35 | |||
36 | * flex | ||
37 | * bison | ||
38 | |||
39 | The flex and bison source code are pre-processed into C source code for the | ||
40 | tarballs, so you do not need these programs in order to compile. | ||
41 | |||
42 | Build also relies on libbu++, but the shell script 'build.sh' will check out | ||
43 | the files it needs from libbu++ SVN. These files are also included in the | ||
44 | tarball release. | ||
45 | |||
46 | Build also builds the easiest when using build. Once you have a working | ||
47 | version of build it's very easy to keep working on build. | ||
48 | |||
49 | # Example Build Scripts | ||
50 | |||
51 | Just 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 | |||
61 | Build has sensible defaults for many things, this creates an explicit target | ||
62 | named filescan that relies on the source code in the directory src. It adds | ||
63 | debugging flags, and it links libbu++. | ||
64 | |||
65 | The build system uses a variation on a standard boolean transitive closure | ||
66 | algorithm 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 | ||
68 | targets 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 | |||
88 | This example is slightly more complex. It sets some flags that all targets will | ||
89 | use, then creates two explicit targets. The second target, joved, also | ||
90 | requires that libjove.a is up to date, but it is not treated as an input. This | ||
91 | is enough to determine order of building, all source files, targets, and even | ||
92 | provides 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 | ||
10 | CC = CXX; // We actually want to use c++ to compile our c files. | 10 | CC = CXX; // We actually want to use c++ to compile our c files. |
11 | 11 | ||
12 | if PREFIX == null then | ||
13 | { | ||
14 | PREFIX = "/usr/local"; | ||
15 | } | ||
16 | |||
12 | action "default" | 17 | action "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 | ||
32 | action "docs" | ||
33 | { | ||
34 | build: targets("docs"); | ||
35 | } | ||
36 | |||
27 | action "devinstall" | 37 | action "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 | ||
119 | target "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 | |||
138 | target "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 | |||
154 | target "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} | ||
13 | Build is a self-contained, sophisticated tool for performing multi-step | ||
14 | processes. The primary goal is to be able to replace the standard | ||
15 | configure/make or cmake/make systems that have become quite popular. | ||
16 | |||
17 | By default Build will work much as one would expect for compiling software, it | ||
18 | uses file exisistance and timestamps to determine what to build, and every file | ||
19 | has a list of dependant files and input files. | ||
20 | |||
21 | However, this is only the default configuration, you can use anything as the | ||
22 | condition for determining what to build or rebuild, and targets do not have to | ||
23 | be files. | ||
24 | |||
25 | Build boasts a sophisticated system for chaining rules together to take files | ||
26 | through as many steps as necesarry to get them in the desirable foramt for input | ||
27 | to the final step. This may sound a little vague and confusing, but what it | ||
28 | means in the end is that you can list, say, a bison file as on input to an | ||
29 | executable target that requires object (.o) files. In this case build will | ||
30 | automatically figure out that it can get a .c file from the .y input file, and | ||
31 | a .o file from the .c file. It will autogenerate these targets for you and | ||
32 | save a lot of time and effort on your part. | ||
33 | |||
34 | \chapter{Structure of a Build File} | ||
35 | Build files contain build script along with four major types of declerations. | ||
36 | These 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 | |||
55 | Build script also allows you to declare and use variables like many other | ||
56 | scripting languages, which can be integers, floats, booleans, strings, lists, | ||
57 | the special value null, and file handles. | ||
58 | |||
59 | \section{A Quick Example} | ||
60 | Let's start with a very basic example. This example is capable of building an | ||
61 | executable from any number of cpp source files: | ||
62 | |||
63 | \begin{lstlisting} | ||
64 | target "myprogram" | ||
65 | { | ||
66 | rule "exe"; | ||
67 | input files("src/*.cpp"); | ||
68 | } | ||
69 | \end{lstlisting} | ||
70 | |||
71 | This example doesn't set any special compliation or linking flags, but it is a | ||
72 | complete and valid build file. It will find all cpp files in src, generate an | ||
73 | implicit target for each file to compile it into an object (.o) file, and then | ||
74 | use those files as the input to the myprogram target in the end. | ||
75 | |||
76 | \section{Targets} | ||
77 | A target represents a unit of work. This is usually a file in a compilation | ||
78 | process, e.g. an object file, an executable, a library, et cetera. Targets | ||
79 | come in two major flavors: explicit and implicit. Explicit targets are any | ||
80 | targets that you define in a build script with the "target" keyword. Targets | ||
81 | can also be auto-generated by rules when needed, these are known as implicit | ||
82 | targets. | ||
83 | |||
84 | If a target is declared more than once the two targets are merged. You can | ||
85 | think of this as a newer target overriding \emph{parts} of an older target. It | ||
86 | does not replace the previous target. | ||
87 | |||
88 | Targets can be declared inside of any linguistic construct, including if blocks | ||
89 | and loops, this gives you a lot of flexibility, but in addition, you can | ||
90 | specify a list of strings instead of a single string for the name of a target, | ||
91 | this creates a target with the same specs for each name in the list. | ||
92 | |||
93 | Targets 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} | ||
111 | Actions are the primary interface to build scripts from the command line, when | ||
112 | calling build you specify an action to run. If no action is specified on the | ||
113 | command line the action "default" is run. If the build script doesn't specify | ||
114 | a default action, one is generated for it that will attempt to build all | ||
115 | explicit targets. | ||
116 | |||
117 | Actions can contain almost any build script, plus an extra syntax that allows | ||
118 | you to process a list of targets in a given profile (see the targets section | ||
119 | for details). Basically this means that you have a lot of flexibility | ||
120 | controlling how your targets are processed. | ||
121 | |||
122 | Let's start with an example: | ||
123 | |||
124 | \begin{lstlisting} | ||
125 | action "default" | ||
126 | { | ||
127 | build: "myprogram"; | ||
128 | } | ||
129 | \end{lstlisting} | ||
130 | |||
131 | This is as basic as it gets, this example will cause build to process the | ||
132 | target "myprogram" using the profile "build". | ||
133 | |||
134 | \end{document} | ||
@@ -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" | |||
79 | rule "tarball" | 82 | rule "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 | } |