| 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 |
} |
|---|