root/trunk/sss/main.d

Revision 933, 14.2 kB (checked in by Gregor, 3 months ago)

RELEASE: 0.78

Line 
1 /**
2  * Main DSSS entry location
3  *
4  * Authors:
5  *  Gregor Richards
6  *
7  * License:
8  *  Copyright (c) 2006, 2007  Gregor Richards
9  * 
10  *  Permission is hereby granted, free of charge, to any person obtaining a
11  *  copy of this software and associated documentation files (the "Software"),
12  *  to deal in the Software without restriction, including without limitation
13  *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  *  and/or sell copies of the Software, and to permit persons to whom the
15  *  Software is furnished to do so, subject to the following conditions:
16  * 
17  *  The above copyright notice and this permission notice shall be included in
18  *  all copies or substantial portions of the Software.
19  * 
20  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  *  DEALINGS IN THE SOFTWARE.
27  */
28
29 module sss.main;
30
31 import std.file;
32 import std.path;
33 import std.stdio;
34 import std.string;
35
36 import std.c.stdlib;
37
38 import sss.build;
39 import sss.clean;
40 import sss.conf;
41 import sss.genconfig;
42 import sss.install;
43 version (DSSS_Light) {} else {
44     import sss.net;
45 }
46 import sss.uninstall;
47
48 const char[] DSSS_VERSION = "0.78";
49
50 private {
51     /** Possible commands */
52     enum cmd_t {
53         NONE,
54             BUILD,
55             CLEAN,
56             DISTCLEAN,
57             INSTALL,
58             BINSTALL,
59             UNINSTALL,
60             INSTALLED,
61             NET,
62             GENCONFIG
63     }
64    
65     /** The command in use */
66     cmd_t command;
67 }
68
69 int main(char[][] args)
70 {
71     bool commandSet = false;
72    
73     /** Elements to build/install/something */
74     char[][] buildElems;
75
76     /** Overridden dsss.conf to use */
77     char[] useDSSSConf = null;
78
79     char[] val;
80
81     // Now load in dsssrc
82     args ~= readDSSSRC();
83    
84     for (int i = 1; i < args.length; i++) {
85         char[] arg = args[i];
86        
87         /** A simple function to check for any help-type option */
88         bool argIsHelp() {
89             return (arg == "--help" ||
90                     arg == "-help" ||
91                     arg == "-h" ||
92                     arg == "-?");
93         }
94        
95         /** Parse an argument */
96         bool parseArg(char[] arg, char[] expect, bool takesVal, char[]* val = null) {
97             if (takesVal) {
98                 if (arg.length > expect.length + 2 &&
99                     arg[0 .. (expect.length + 3)] == "--" ~ expect ~ "=") {
100                     *val = arg[(expect.length + 3) .. $];
101                     return true;
102                 } else if (arg.length > expect.length + 1 &&
103                            arg[0 .. (expect.length + 2)] == "-" ~ expect ~ "=") {
104                     *val = arg[(expect.length + 2) .. $];
105                     return true;
106                 }
107                 return false;
108             } else {
109                 if (arg == "--" ~ expect ||
110                     arg == "-" ~ expect) return true;
111                 return false;
112             }
113         }
114        
115         if (!commandSet) {
116             // no command set yet, DSSS options
117             if (argIsHelp()) {
118                 usage();
119                 return 0;
120
121             } else if (parseArg(arg, "config", true, &val)) {
122                 useDSSSConf = val.dup;
123                
124             } else if (arg == "build") {
125                 commandSet = true;
126                 command = cmd_t.BUILD;
127                
128             } else if (arg == "clean") {
129                 commandSet = true;
130                 command = cmd_t.CLEAN;
131                
132             } else if (arg == "distclean") {
133                 commandSet = true;
134                 command = cmd_t.DISTCLEAN;
135                
136             } else if (arg == "install") {
137                 commandSet = true;
138                 command = cmd_t.INSTALL;
139
140             } else if (arg == "binstall") {
141                 commandSet = true;
142                 command = cmd_t.BINSTALL;
143                
144             } else if (arg == "uninstall") {
145                 commandSet = true;
146                 command = cmd_t.UNINSTALL;
147                
148             } else if (arg == "installed") {
149                 commandSet = true;
150                 command = cmd_t.INSTALLED;
151                
152             } else if (arg == "net") {
153                 version (DSSS_Light) {
154                     writefln("The 'net' command is not supported in DSSS Light");
155                     exit(1);
156                 } else {
157                     commandSet = true;
158                     command = cmd_t.NET;
159                 }
160                
161             } else if (arg == "genconfig") {
162                 commandSet = true;
163                 command = cmd_t.GENCONFIG;
164                
165             } else {
166                 writefln("Unrecognized argument: %s", arg);
167                 exit(1);
168             }
169            
170         } else {
171             /* generic options */
172             if (argIsHelp()) {
173                 usage();
174                 return 0;
175                
176             } else if (parseArg(arg, "use", true, &val)) {
177                 // force a use-dir
178                 useDirs ~= makeAbsolute(val);
179                
180             } else if (parseArg(arg, "doc", false)) {
181                 doDocs = true;
182                
183             } else if (parseArg(arg, "doc-binaries", false)) {
184                 doDocs = true;
185                 doDocBinaries = true;
186
187             } else if (parseArg(arg, "debug", false)) {
188                 buildDebug = true;
189
190             } else if (parseArg(arg, "v", false)) {
191                 verboseMode = true;
192
193             } else if (parseArg(arg, "vv", false)) {
194                 verboseMode = true;
195                 dsss_buildOptions ~= "-v ";
196
197             } else if (parseArg(arg, "prefix", true, &val)) {
198                 // force a prefix
199                 forcePrefix = makeAbsolute(val);
200                
201             } else if (parseArg(arg, "keep-response-files", false)) {
202                 deleteRFiles = false;
203                
204             } else if (parseArg(arg, "bindir", true, &val)) {
205                 binPrefix = makeAbsolute(val);
206                
207             } else if (parseArg(arg, "libdir", true, &val)) {
208                 libPrefix = makeAbsolute(val);
209                
210             } else if (parseArg(arg, "includedir", true, &val)) {
211                 includePrefix = makeAbsolute(val);
212                
213             } else if (parseArg(arg, "docdir", true, &val)) {
214                 docPrefix = makeAbsolute(val);
215                
216             } else if (parseArg(arg, "sysconfdir", true, &val)) {
217                 etcPrefix = makeAbsolute(val);
218                
219             } else if (parseArg(arg, "scratchdir", true, &val)) {
220                 scratchPrefix = makeAbsolute(val);
221                
222             } else if (arg == "-arch" ||
223                        arg == "-isysroot" ||
224                        arg == "-framework") {
225                 // special Mac OS X flags
226                 dsss_buildOptions ~= arg ~ " ";
227                 i++;
228                 if (i >= args.length) {
229                     writefln("Argument expected after %s", arg);
230                     return 1;
231                 }
232                 dsss_buildOptions ~= args[i] ~ " ";
233                
234             } else if (arg.length >= 1 &&
235                        arg[0] == '-') {
236                 // perhaps specific to a command
237                 if (command == cmd_t.BUILD) {
238                     if (parseArg(arg, "test", false)) {
239                         testLibs = true;
240                     } else {
241                         dsss_buildOptions ~= arg ~ " ";
242                     }
243
244                 } else if (command == cmd_t.NET) {
245                     version (DSSS_Light) {} else {
246                         if (parseArg(arg, "source", true, &val)) {
247                             forceMirror = val;
248                         } else {
249                             dsss_buildOptions ~= arg ~ " ";
250                         }
251                     }
252                    
253                 } else {
254                     // pass through to build
255                     dsss_buildOptions ~= arg ~ " ";
256                 }
257                
258             } else {
259                 // something to pass in
260                 buildElems ~= arg;
261             }
262            
263             /* there are presently no specific options */
264         }
265     }
266    
267     if (!commandSet) {
268         usage();
269         return 0;
270     }
271    
272     // Before running anything, get our prefix
273     getPrefix(args[0]);
274    
275     // add useDirs
276     foreach (dir; useDirs) {
277         dsss_build ~= "-I" ~ dir ~ std.path.sep ~
278             "include" ~ std.path.sep ~
279             "d -S" ~ dir ~ std.path.sep ~
280             "lib ";
281     }
282
283     // if a specific dsss.conf file was requested, use it
284     DSSSConf conf = null;
285     if (useDSSSConf != "") {
286         writefln("WARNING: The --config option is only recommended for testing, and should NOT be");
287         writefln("         a part of your general build routine.");
288         conf = readConfig(buildElems, false, useDSSSConf);
289     }
290    
291     switch (command) {
292         case cmd_t.BUILD:
293             return sss.build.build(buildElems, conf);
294             break;
295            
296         case cmd_t.CLEAN:
297             return sss.clean.clean(conf);
298             break;
299            
300         case cmd_t.DISTCLEAN:
301             return sss.clean.distclean(conf);
302             break;
303            
304         case cmd_t.INSTALL:
305             return sss.install.install(buildElems, conf);
306             break;
307
308         case cmd_t.BINSTALL:
309         {
310             int bret = sss.build.build(buildElems, conf);
311             if (bret) return bret;
312             return sss.install.install(buildElems, conf);
313             break;
314         }
315            
316         case cmd_t.UNINSTALL:
317             return sss.uninstall.uninstall(buildElems);
318             break;
319            
320         case cmd_t.INSTALLED:
321             return sss.uninstall.installed();
322             break;
323            
324         case cmd_t.NET:
325             version (DSSS_Light) {} else {
326                 return sss.net.net(buildElems);
327             }
328             break;
329            
330         case cmd_t.GENCONFIG:
331             return sss.genconfig.genconfig(buildElems);
332             break;
333     }
334    
335     return 0;
336 }
337
338 /** Make a dir absolute */
339 char[] makeAbsolute(char[] path)
340 {
341     if (!isabs(path)) {
342         return getcwd() ~ std.path.sep ~ path;
343     }
344     return path;
345 }
346
347 void usage()
348 {
349     if (command == cmd_t.NONE) {
350         writefln(
351 `DSSS version ` ~ DSSS_VERSION ~ `
352 Usage: dsss [dsss options] <command> [options]
353   DSSS Options:
354     --help|-h: Display this help.
355     --config=<alternative dsss.conf file>: Should be used for testing only.
356   Commands:
357     build:     build all or some binaries or libraries
358     clean:     clean up object files from all or some builds
359     distclean: clean up all files from all or some builds
360     install:   install all or some binaries or libraries
361     uninstall: uninstall a specified tool or library
362     installed: list installed software`);
363         version(DSSS_Light) {} else {
364             writefln(
365 `    net:       Internet-based installation and package management`);
366         }
367         writefln(
368 `    genconfig: generate a config file`);
369        
370     } else if (command == cmd_t.BUILD) {
371         writefln(
372 `Usage: dsss [dsss options] build [build options] [sources, binaries or packages]
373   Build options:
374     --test: test compiled libraries`
375             );
376        
377     } else if (command == cmd_t.CLEAN) {
378         writefln(
379 `Usage: dsss [dsss options] clean [clean options] [sources, binaries or packages]`
380             );
381        
382     } else if (command == cmd_t.DISTCLEAN) {
383         writefln(
384 `Usage: dsss [dsss options] distclean [distclean options] [sources, binaries or packages]`
385             );
386        
387     } else if (command == cmd_t.INSTALL) {
388         writefln(
389 `Usage: dsss [dsss options] install [install options] [sources, binaries or packages]`
390             );
391        
392    } else if (command == cmd_t.BINSTALL) {
393         writefln(
394 `Usage: dsss [dsss options] binstall [binstall options] [sources, binaries or packages]`
395             );
396
397    } else if (command == cmd_t.UNINSTALL) {
398         writefln(
399 `Usage: dsss [dsss options] uninstall [uninstall options] <tools or libraries>`
400             );
401        
402     } else if (command == cmd_t.INSTALLED) {
403         writefln(
404 `Usage: dsss [dsss options] installed`
405             );
406        
407     } else if (command == cmd_t.NET) {
408         writefln(
409 `Usage: dsss [dsss options] net <net command> [options] <package name>
410   Net commands:
411     deps:    install (from the network source) dependencies of the present
412              package
413     depslist:list dependencies, but do not install them
414     install: install a package via the network source
415     fetch:   fetch but do not compile or install a package
416     list:    list all installable packages
417     search:  find an installable package by name
418   Net options:
419     --source=<URL>: Use the given URL for the sources list, rather than asking
420             or using the last URL used.`
421             );
422
423        
424     } else if (command == cmd_t.GENCONFIG) {
425         writefln(
426 `Usage: dsss [dsss options] genconfig [install options] [sources, binaries or packages]`
427             );
428        
429     }
430    
431     writefln(
432 `  Generic options (must come after the command):
433     --help: display specific options and information
434     --prefix=<prefix>: set the install prefix
435     --doc: Generate/install documentation for libraries
436     --doc-binaries: Generate/install documentation for libraries and binaries.
437         This will generate a lot of needless documentation for prerequisite
438         libraries, and is therefore not recommended for general use.
439     --use=<directory containing import library includes and libs>
440     --keep-response-files: Do not delete temporary rebuild response files
441
442     --bindir=<dir> [default <prefix>/bin]
443     --libdir=<dir> [default <prefix>/lib]
444     --includedir=<dir> [default <prefix>/include/d]
445     --docdir=<dir> [default <prefix>/share/doc]
446     --sysconfdir=<dir> [default <prefix>/etc]
447     --scratchdir=<dir> [default /tmp]
448
449   All other options are passed through to rebuild and ultimately the compiler.`);
450        
451 }
Note: See TracBrowser for help on using the browser.