-
Notifications
You must be signed in to change notification settings - Fork 0
/
rusty_cs.1
310 lines (266 loc) · 14.2 KB
/
rusty_cs.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
.TH RUSTY 1
.SH NAME
rusty \- malý a rychlý systém pro automatizaci překladu kódu jazyků C, C++ a pravděpodobně mnoha dalších
.SH SYNOPSIS
.B rusty
[\fB\-h\fR] [\fB\-\-help\fR] [\fB\-\-ast\fR] [\fB\-\-info\fR] [\fB\-\-about\fR] [\fB\-viratwn\fR] [\fB\-o\fR \fIDIR\fR] [\fB\-\-output\fR \fIDIR\fR] [\fB\-d\fR \fIDIR\fR] [\fB\-\-dir\fR \fIDIR\fR] [\fB\-c\fR \fICOMPILER\fR] [\fB\-\-compiler\fR \fICOMPILER\fR] [\fB\-o\fR \fIDIR\fR] [\fITARGETS\fR] [\fBclean\fR] [\fBinstall\fR] [\fBuninstall\fR]
.SH DESCRIPTION
.B rusty
je jednoduchý systém pro automatizaci překladu, který si původně zapůjčil syntaxi a koncepty ze zabudovaného systému pro jazyk C2. Syntaxe a schopnosti projektu se ovšem postupně rozrostly, a nyní Rusty podporuje nejen jednoduchou kompilaci, ale také inkrementální kompilaci, načítání zdrojových souborů z jedné složky, změnu kořenového adresáře projektu, podmíněné sestavování (podle operačního systému) linkování mezi cíli, příkazy pro instalaci a odinstalaci, spouštění příkazů před kompilací, přidávání přepínačů překladači a kontrolu, na jakých souborech je který zdrojový soubor závislý a na kterých souborech je závislý celý projekt.
Rusty používá parsovací knihovnu mpc Daniela Holdena k načítání informací o jednotlivých cílech. Momentálně rozpoznává Rusty čtyři typy cílů: spustitelné soubory, statické knihovny, sdílené/dynamické knihovny a cíle objektového kódu, kdy nedojde k finálnímu sestavování do binárního souboru, ale pouze tvorbě objektového kódu. Rusty vyžaduje rustyfile (soubor rusty.txt). Rusty tento soubor hledá iterativně, takže není problém jej spouštět z pod-adresářů projektu.
Filozofie projektu Rusty je inspirována filozofií skupiny suckless.org. Rusty se snaží být co nejmenší (rusty.c je jen něco málo přes tisíc řádků), co nejpoužitelnější a hojně využívat možnosti programovacího jazyka C.
.SH OPTIONS
.TP
.BR \-h ", " \-\-help\fR
Zobrazí základní text pomoci
.TP
.BR \-\-about\fR
Zobrazí text popisující Rusty a příklad použití.
.TP
.BR \-c ", " \-\-compiler " " \fIname\fR
Změní překladač použitý ke zpracování souborů.
.TP
.BR \-i ", " \-\-info\fR
Zobrazí informace o každém z cílů nalezeném v rustyfilu.
.TP
.BR \-d ", " \-\-dir " " \fIpath\fR
Změní pracovní adressář před startem hledání rustyfilu.
.TP
.BR \-r ", " \-\-fullrebuild\fR
Znovu postaví všechny soubory bez ohledu na to, jestli byly modifikovány. Užitečné, pokud se nepodaří kompilace a řešením problému byla změna, která nezasahovala do zdrojových souborů.
.TP
.BR \-t ", " \-\-time\fR
Změří a vypíše CPU čas, jaký spuštění Rusty trvalo. Poznámka: CPU čas bývá výrazně kratší, než by byl reálný čas.
.TP
.BR \-n ", " \-\-check\fR
Pouze zkontroluje rustyfile a nic nepřekládá/nesetavuje. Ostatní přepínače jsou stále zpracovávány. Nevztahuje se na 'run' tagy, které běží tak jako tak.
.TP
.BR \-w ", " \-\-wanted\-only\fR
Zobrazí informace a abstraktní syntaxní strom pouze pro specifikované cíle, ne celý rustyfile. Neimplikuje přepínače -i a -a, je nutné je použít v konjukci s -w, aby se informace zobrazily.
.SH MODUS OPERANDI
.nr step 1 1
.IP \fB\n[step] 6\fR
Rusty přečte parametry z příkazového řádku a začne hledat rustyfile.
.IP \fB\n+[step] \fR
Po nalezení rustyfilu dojde k jeho přečtení, vymazání komentářů a následnému parsování.
.IP \fB\n+[step] \fR
Na základě informací přečtených ze syntaxního stromu vytvoří Rusty cíle. 'run' tagy jsou okamžitě po přečtení spuštěny.
.IP \fB\n+[step] \fR
Rusty zkontroluje, jestli pro všechny požadované cíle existují jejich soubory a vypíše chybu, není-li tomu tak.
.IP \fB\n+[step] \fR
U každého souboru dojde ke kontrole, zda-li byl modifikován od předchozí kompilace. Má-li soubor @depends() atribut, jsou i zkontrolovány všechny soubory zde specifikované. Dojde-li ke změně globálního závislotního souboru, je modifikovanost ignorována a všechny soubory jsou přeloženy znovu. Za tímto účelem vytváří Rusty komicky minimální metadata ve složce .rusty v kořenovém adresáři projektu.
.IP \fB\n+[step] \fR
Po kompilaci všech souborů, pokud je úspěšná, dochází k linkovací části programu. Pro binární soubory se využije překladače bez nějakých přídavných přepínačů. Pro sdílené knihovny se používá přepínač -shared, očekává se že, ke kompilaci dodá uživatel přepínač -fPIC sám, uzná-li to za vhodné. Statické knihovny jsou vytvořené pomocí utility ar.
.IP \fB\n+[step] \fR
Pokud byl na začátku specifikován cíl 'install' nebo 'uninstall', provede Rusty patřičnou operaci. Rusty povoluje jak instalaci tak odinstalaci najednou, i když se zeptá uživatele, zda-li je to úmyslné.
.SH LIMITACE
Rusty občas nedokáže vždy určit, zda-li se překlad povedl. Problémy také dělá, když se v rustyfilech vyskytuje nekonsistentní ukončení řádků. Při (od)instalaci cílů neví, jestli má dostatečná práva.
.SH MAPA KÓDU
.TP
.BR \fBarg.h\fR
Modifikovaný headr pro zpracování přepínačů z příkazové řádky. Původně napsáno Christopherem Lohmannem. Změny zahrnují možnost dát přepínače kamkoliv do příkazu, přepínače ve formě celých slov (např. \fB\-\-version\fR), makra pro jednoduché přepínače a integrace s Rusty. Verze 'arg.h' obsažená v Rusty je nepoužitelná mimo něj.
.TP
.BR \fBdirent.h\fR
Implementace rozhraní 'dirent' pro platformu Win32 napsaná Toni Ronkkem. Nutná, protože Rusty využívá rozhraní dirent ke čtení složek.
.TP
.BR \fBmpc.c/h\fR
Parsovací knihovna mpc od Daniela Holdena. Modifikovaná verze je identická s tou vloženou do projektu c2tc
.TP
.BR \fBrusty.c\fR
Hlavní soubor, který obsahuje drtivou většinu kódu, který není součástí vložených knihoven mpc, dirent.h a arg.h.
.TP
.BR \fButil.h\fR
Soubor, který definuje aliasy pro číselné typy a implementaci funkce strdup() pro systémy, na kterých není přítomna.
.SH PŘÍKLADY
Samotný Rusty má vlastní rustyfile v kořenovém adresáři, kterým jej jde postavit a instalovat. Standardní postup při instalaci je použití skriptu 'compile.sh', zkompilování Rusty pomocí této verze sebe sama, a následná instalace pomocí nové verze. To znamená zhruba tento postup:
$ ./compile.sh
#rustyfile projektu obsahuje dva cíle: rusty a rusty_debug. Bez specifikace by se postavily všechny cíle najednou.
$ ./rusty rusty
$ sudo rusty install #v tomto případě zkopíruje binární soubor do /usr/bin a nainstaluje manuálovou stránku
Další příklad(y) lze najít ve složce test. Soubor rusty.txt.concept obsahuje i budoucí plánované funkce, které ještě nejsou implementovány. Pro pohodlí prohlížení rustyfilů je v kořenovém adresáři soubor rusty.nanorc, který obsahuje zvýrazňování syntaxe pro rustyfily.
.SH SYNTAXE
Přesnou gramatiku rustyfilů lze najít v souboru rusty.c ve funkci parse(), ale tato sekce se pokusí alespoň částečně popsat tvorbu rustyfilu.
Rustyfile se zkládá z definice překladače a jednoho nebo více cílů. Definice překladače se vytvoří klíčovým slovem 'compiler', dvojtečky, jména překladače ve formě textového řetězce a středníku. Cíl je deklarován pomocí klíčového slova 'target', identifikátoru pro cíl a dvojtečky. Identifikátor vůbec nesouvisí s finálním názvem binárního souboru. Příklad:
compiler: "gcc";
\fBtarget jablko:
target malina:
target brambora:\fR
Tyto cíle ovšem nejsou validní, protože Rusty vyžaduje alespoň tag "name", a k tomu jeden funkční tag. Tag name specifikuje název binárního souboru, který bude vytvořen. Z hlediska formy patří mezi řetězcové tagy (tzn. vyžaduje jeden a pouze jeden textový řetězec). Každý řetězcový tag musí být ukončen středníkem.
compiler: "gcc";
\fBtarget jablko:\fR
name: "meloun";
\fBtarget malina:\fR
name: "jahoda";
\fBtarget brambora:\fR
name: "lilek";
V minulém příkladu jsou všechny tagy odsazeny, ale to je jen otázka stylu/čitelnosti. Rusty kompletně ignoruje bílé znaky mezi tokeny. Speciální tag je tag 'type'. Může být použit k určení typu cíle. Není vyžadován, Rusty předpokládá spustitelný soubor. Tento předpoklad ovšem závisí na tom, že funkce calloc() bude vynulovávat přidělenou paměť, proto je lepší vždy typ specifikovat ručně.
compiler: "gcc";
\fBtarget jablko:\fR
name: "meloun";
type: executable;
\fBtarget malina:\fR
name: "jahoda";
type: object;
\fBtarget brambora:\fR
name: "lilek";
type: libstatic;
Další tagem je tag 'flags', který přidává přepínače k překladači jak během kompilace tak i sestavování cíle. Tag flags zneužívá toho, že většina překladačů jazyka C a C++ ignoruje značky, které se nehodí pro danou fázi sestavování. Tag flags je seznamový tag, což znamená, že místo jednoho řetězce jich bere celý seznam uzavřený ve složených závorkách. Seznam musí obsahovat jeden a více řetězců, prázdné seznamy nejsou povoleny. Stejně jako ostatní tagy jsou uzavřeny středníkem
compiler: "gcc";
\fBtarget jablko:\fR
name: "meloun";
type: executable;
flags: { "-Wall", "-std=c89" };
\fBtarget malina:\fR
name: "jahoda";
type: object;
flags: { "-Wall", "-std=c89" };
\fBtarget brambora:\fR
name: "lilek";
type: libstatic;
flags: { "-Wall", "-std=c89" };
Tag output je posledním nefunkčním tagem. Mění, do jaké složky se uloží výsledné binární soubory. Výchozí chování je složka output/nazev_projektu v kořenovém adresáři projektu. Nutno podotknout, že Rusty nevytváří tyto složky automaticky, je nutno je vytvořit předem, například pomocí run tagu, který je popsán níže.
compiler: "gcc";
\fBtarget jablko:\fR
name: "meloun";
type: executable;
flags: { "-Wall", "-std=c89" };
output: ".";
\fBtarget malina:\fR
name: "jahoda";
type: object;
flags: { "-Wall", "-std=c89" };
output: ".";
\fBtarget brambora:\fR
name: "lilek";
type: libstatic;
flags: { "-Wall", "-std=c89" };
output: ".";
Řetězcové funkční tagy jsou: 'sourcedir', 'file', 'dir', 'depends' a 'link'.
Tag sourcedir určuje, v jaké složce začíná Rusty hledat soubory specifikované pomocí tagu file. Sourcedir nemění pracovní adresář, nýbrž přidává specifikovanou cestu jako předponu k souborům.
Tag file může mít u sebe atribut @depends(), který určuje na jakých jiných souborech daný zdrojový soubor závisí ve formě odčárkovaného seznamu řetězců.
Depends určuje soubor, na kterém závisí celý cíl a který při změně způsobí překlad a sestavení celého cíle. Tag depends se zejména hodí, když má projekt headery, které jsou vloženy do většiny zdrojových souborů.
Tag dir najde všechny zdrojové soubory v dané složce podle přípon souborů. Seznam souborových přípon, které Rusty rozpoznává, je vypsán ve funkci read_dir().
Tag link přidá do sestavování i objektový kód jiného cíle. Pokud cíl, jehož objektový kód je přidáván, není ještě sestavený, rusty jej nejdříve sestaví.
compiler: "gcc";
\fBtarget jablko:\fR
name: "meloun";
type: executable;
flags: { "-Wall", "-std=c89" };
output: ".";
sourcedir: "src";
depends: "soubor.h";
file: "potato.c";
file: "potato2.c" @depends("potato.h", "util.h");
dir: "brambory";
link: mpc;
\fBtarget malina:\fR
name: "jahoda";
type: object;
flags: { "-Wall", "-std=c89" };
output: ".";
sourcedir: "src";
depends: "soubor.h";
file: "potato.c";
file: "potato2.c" @depends("potato.h", "util.h");
dir: "brambory";
link: mpc;
\fBtarget brambora:\fR
name: "lilek";
type: libstatic;
flags: { "-Wall", "-std=c89" };
output: ".";
sourcedir: "src";
depends: "soubor.h";
file: "potato.c";
file: "potato2.c" @depends("potato.h", "util.h");
dir: "brambory";
link: mpc;
Seznamové tagy jsou 'run', 'install' a 'uninstall'. Tag run spouští příkazy v okamžiku, kdy jsou přečteny, bez ohledu na to, jestli je cíl vybrán pro kompilaci. Pokud se dostane Rusty mezi argumenty i slova install a uninstall, spustí patřičné příkazy.
compiler: "gcc";
\fBtarget jablko:\fR
name: "meloun";
type: executable;
flags: { "-Wall", "-std=c89" };
output: ".";
sourcedir: "src";
depends: "soubor.h";
file: "potato.c";
file: "potato2.c" @depends("potato.h", "util.h");
dir: "brambory";
link: mpc;
run:
{
"echo jablko",
"cowsay 123"
};
install:
{
"echo instalace jablka",
"cowsay 321"
};
uninstall:
{
"echo odinstalace jablka",
"cowsay 231"
};
\fBtarget malina:\fR
name: "jahoda";
type: object;
flags: { "-Wall", "-std=c89" };
output: ".";
sourcedir: "src";
depends: "soubor.h";
file: "potato.c";
file: "potato2.c" @depends("potato.h", "util.h");
dir: "brambory";
link: mpc;
run:
{
"echo jablko",
"cowsay 123"
};
install:
{
"echo instalace jablka",
"cowsay 321"
};
uninstall:
{
"echo odinstalace jablka",
"cowsay 231"
};
\fBtarget brambora:\fR
name: "lilek";
type: libstatic;
flags: { "-Wall", "-std=c89" };
output: ".";
sourcedir: "src";
depends: "soubor.h";
file: "potato.c";
file: "potato2.c" @depends("potato.h", "util.h");
dir: "brambory";
link: mpc;
run:
{
"echo jablko",
"cowsay 123"
};
install:
{
"echo instalace jablka",
"cowsay 321"
};
uninstall:
{
"echo odinstalace jablka",
"cowsay 231"
};
Poznámka: Na pořadí funkčních tagů nezáleží, ale na pořadí hlavičkových tagů (name, type, flags, output) ano. V tomto návodu jsou specifikovány v patřičném pořadí.
.SH LICENCE
Rusty je licencován licencí 'Fair License'. Jedná se o absolutně minimální licenci, což jde v duchu s filozofií projektu Rusty (co nejvíce funkčnosti s co nejméně řádky kódu). Plné znění je v souboru LICENSE a zde:
Fair License
Lukáš Hozda(c), 2015-2017
Usage of the works is permitted provided that this
instrument is retained with the works, so that any
entity that uses the works is notified of this instrument.
DISCLAIMER: THE WORKS ARE WITHOUT WARRANTY.