1 /* 2 * DSFML - The Simple and Fast Multimedia Library for D 3 * 4 * Copyright (c) 2013 - 2017 Jeremy DeHaan (dehaan.jeremiah@gmail.com) 5 * 6 * This software is provided 'as-is', without any express or implied warranty. 7 * In no event will the authors be held liable for any damages arising from the 8 * use of this software. 9 * 10 * Permission is granted to anyone to use this software for any purpose, 11 * including commercial applications, and to alter it and redistribute it 12 * freely, subject to the following restrictions: 13 * 14 * 1. The origin of this software must not be misrepresented; you must not claim 15 * that you wrote the original software. If you use this software in a product, 16 * an acknowledgment in the product documentation would be appreciated but is 17 * not required. 18 * 19 * 2. Altered source versions must be plainly marked as such, and must not be 20 * misrepresented as being the original software. 21 * 22 * 3. This notice may not be removed or altered from any source distribution 23 */ 24 25 module build; 26 27 import std.stdio; 28 import std.file; 29 import std.process; 30 import std.algorithm; 31 import std.array; 32 import std.getopt; 33 34 static if (__VERSION__ < 2068L) 35 { 36 static assert(0, "Please upgrade your compiler to v2.068 or later"); 37 } 38 39 version(DigitalMars) 40 { 41 string compiler = "dmd "; 42 } 43 else version(GNU) 44 { 45 string compiler = "gdc "; 46 } 47 else version(LDC) 48 { 49 string compiler = "ldc2 "; 50 } 51 else 52 { 53 static assert(false, "Unknown or unsupported compiler."); 54 } 55 56 //build settings 57 string prefix; 58 string extension; 59 string libCompilerSwitches; 60 string docCompilerSwitches; 61 string interfaceCompilerSwitches; 62 string unittestCompilerSwitches; 63 bool buildStop; 64 65 66 //switch settings 67 bool buildingLibs; 68 bool buildingInterfaceFiles; 69 bool buildingDoc; 70 bool buildingWebsiteDocs; 71 bool showingHelp; 72 bool force32Build; 73 bool force64Build; 74 75 bool buildingUnittests; 76 string unittestLibraryLocation; 77 78 bool buildingAll; 79 80 bool hasUnrecognizedSwitch; 81 string unrecognizedSwitch; 82 83 string makefileType; 84 string makefileProgram; 85 string objExt; 86 string singleFileSwitches; 87 string archSwitch; 88 89 90 //Possibly use this to completely automate the process for dmd/ldc users on windows 91 //environment.get("VCINSTALLDIR"); 92 //will need to find an alternative for gdc users on windows in regards to mingw 93 94 version(Windows) 95 { 96 } 97 else version(linux) 98 { 99 } 100 else version(OSX) 101 { 102 } 103 //FreeBSD Support coming soon! 104 else 105 { 106 static assert(false, "DSFML is only supported on OSX, Windows, and Linux."); 107 } 108 109 110 string[5] modules = ["system", "audio", "network", "window", "graphics"]; 111 string selectedModule; 112 113 //lists of d files and c++ object files 114 string[][string] fileList; 115 string[][string] objectList; 116 117 118 //checks for any inconsistencies with the passed switchs. 119 //Returns true if everything is ok and false if an error was found. 120 bool checkSwitchErrors() 121 { 122 //can't force both 123 if(force32Build && force64Build) 124 { 125 writeln("Can't use -m32 and -m64 together"); 126 return false; 127 } 128 129 //if other Switchs are used with -all 130 if(buildingAll) 131 { 132 if(buildingLibs || buildingDoc || 133 buildingInterfaceFiles || buildingUnittests) 134 { 135 writeln("Can't use -all with any other build switches ", 136 "(-lib, -doc, -import, -unittest)"); 137 138 return false; 139 } 140 } 141 142 return true; 143 } 144 145 //initialize all build settings 146 void initialize() 147 { 148 //populate file lists 149 fileList["system"] = ["clock", "config", "err", "inputstream", "lock", 150 "mutex", "package", "sleep", "string", "thread", 151 "vector2", "vector3"]; 152 153 fileList["audio"] = ["listener", "music", "package", "sound", 154 "soundbuffer", "soundbufferrecorder", 155 "inputsoundfile", "outputsoundfile", 156 "soundrecorder", "soundsource", "soundstream"]; 157 158 fileList["network"] = ["ftp", "http", "ipaddress", "package", 159 "packet", "socket", "socketselector", 160 "tcplistener", "tcpsocket", "udpsocket"]; 161 162 fileList["window"] = ["context", "contextsettings", "event", "joystick", 163 "keyboard", "mouse", "sensor", "touch", "package", 164 "videomode", "window", "windowhandle"]; 165 166 fileList["graphics"] = ["blendmode", "circleshape", "color", "convexshape", 167 "drawable", "font", "glsl", "glyph", "image", 168 "package", "primitivetype", "rect", 169 "rectangleshape", "renderstates", "rendertarget", 170 "rendertexture", "renderwindow", "shader", "shape", 171 "sprite", "text", "texture", "transform", 172 "transformable", "vertex", "vertexarray", "view"]; 173 174 archSwitch = ""; 175 176 177 version(DigitalMars) 178 { 179 initializeDMD(); 180 } 181 else version(GNU) 182 { 183 initializeGDC(); 184 } 185 else 186 { 187 initializeLDC(); 188 } 189 190 if(force32Build) 191 { 192 version(Windows) 193 { 194 version(DigitalMars) 195 { 196 archSwitch = "-m32mscoff"; 197 } 198 } 199 else 200 { 201 archSwitch = "-m32"; 202 } 203 } 204 205 if(force64Build) 206 { 207 archSwitch = "-m64"; 208 } 209 210 writeln(); 211 } 212 213 void initializeDMD() 214 { 215 216 string linkToSFMLLibs = ""; 217 218 version (Windows) 219 { 220 writeln("Building for Windows with dmd"); 221 prefix = ""; 222 extension = ".lib"; 223 objExt = ".obj"; 224 225 //Default to 64 bit on windows because why wouldn't we? 226 if(!force64Build || !force32Build) 227 { 228 archSwitch = " -m64"; 229 } 230 231 makefileProgram = "nmake"; 232 makefileType = `"NMake Makefiles"`; 233 234 linkToSFMLLibs = "-L/LIBPATH:lib -L/LIBPATH:SFML\\lib "~ 235 "-L/LIBPATH:SFML\\extlibs\\libs-msvc-universal\\x64 "; 236 237 linkToSFMLLibs ~= 238 "dsfmlc-graphics.lib dsfmlc-window.lib dsfmlc-audio.lib " ~ 239 "dsfmlc-network.lib dsfmlc-system.lib "; 240 241 linkToSFMLLibs~= 242 "sfml-graphics.lib sfml-window.lib sfml-audio.lib "~ 243 "sfml-network.lib sfml-system.lib "; 244 245 /*linkToSFMLLibs~= 246 "opengl32.lib gdi32.lib flac.lib freetype.lib jpeg.lib ogg.lib "~ 247 "openal32.lib vorbis.lib vorbisenc.lib vorbisfile.lib ws2_32.lib "~ 248 "winmm.lib user32.lib "; 249 */ 250 } 251 else version(linux) 252 { 253 writeln("Building for Linux with dmd"); 254 prefix = "lib"; 255 extension = ".a"; 256 objExt = ".o"; 257 258 makefileProgram = "make"; 259 makefileType = `"Unix Makefiles"`; 260 261 262 linkToSFMLLibs = "-L-Llib -L-LSFML/lib "; 263 264 linkToSFMLLibs ~= 265 "-L-ldsfmlc-graphics -L-ldsfmlc-window -L-ldsfmlc-audio " ~ 266 "-L-ldsfmlc-network -L-ldsfmlc-system "; 267 268 linkToSFMLLibs ~= 269 "-L-lsfml-graphics -L-lsfml-window -L-lsfml-audio "~ 270 "-L-lsfml-network -L-lsfml-system "; 271 272 linkToSFMLLibs ~= "-L-lstdc++ "; 273 274 //linkToSFMLLibs ~= 275 //"-L-lstdc++ -L-lFLAC -L-logg -L-lvorbisfile -L-lvorbisenc -L-lvorbis "~ 276 //"-L-lopenal -L-lX11 -L-ludev -L-lGL -L-lXrandr -L-ljpeg -L-lfreetype"; 277 } 278 else 279 { 280 writeln("Building for OSX with dmd"); 281 prefix = "lib"; 282 extension = ".a"; 283 objExt = ".o"; 284 285 makefileProgram = "make"; 286 makefileType = `"Unix Makefiles"`; 287 288 289 linkToSFMLLibs = "-L-Llib -L-LSFML/lib "; 290 291 linkToSFMLLibs ~= 292 "-L-ldsfmlc-graphics -L-ldsfmlc-window -L-ldsfmlc-audio " ~ 293 "-L-ldsfmlc-network -L-ldsfmlc-system "; 294 295 linkToSFMLLibs ~= 296 "-L-lsfml-graphics -L-lsfml-window -L-lsfml-audio "~ 297 "-L-lsfml-network -L-lsfml-system "; 298 299 linkToSFMLLibs ~= "-L-lstdc++ -L-rpath -L. "; 300 301 //linkToSFMLLibs ~= 302 //"-L-lstdc++ -L-lFLAC -L-logg -L-lvorbisfile -L-lvorbisenc -L-lvorbis "~ 303 //"-L-lopenal -L-lX11 -L-ludev -L-lGL -L-lXrandr -L-ljpeg -L-lfreetype"; 304 } 305 306 singleFileSwitches = archSwitch ~ " -c -O -release -inline -Isrc"; 307 libCompilerSwitches = archSwitch ~ " -lib -Isrc"; 308 docCompilerSwitches = " -c -o- -op -D -Dd../../doc -I../../src"; 309 //interfaceCompilerSwitches = " -c -o- -op -H -Hd"~quoteString(interfaceDirectory); 310 311 unittestCompilerSwitches = 312 "-main -unittest -version=DSFML_Unittest_System " ~ 313 "-version=DSFML_Unittest_Window -version=DSFML_Unittest_Graphics " ~ 314 "-version=DSFML_Unittest_Audio -version=DSFML_Unittest_Network "~ 315 linkToSFMLLibs; 316 //unittestCompilerSwitches ="-main -unittest -version=DSFML_Unittest_Network "~linkToSFMLLibs; 317 //libCompilerSwitches = "-lib -O -release -inline -I"~quoteString(impDirectory); 318 //interfaceCompilerSwitches = " -c -o- -op -H -Hd"~quoteString(interfaceDirectory); 319 } 320 321 void initializeGDC() 322 { 323 //need to set up for windows and macOS later 324 325 string linkToSFMLLibs = ""; 326 327 version(linux) 328 { 329 writeln("Building for Linux with gdc"); 330 prefix = "lib"; 331 extension = ".a"; 332 objExt = ".o"; 333 334 makefileProgram = "make"; 335 makefileType = `"Unix Makefiles"`; 336 337 linkToSFMLLibs = "-Llib -LSFML/lib "; 338 339 linkToSFMLLibs ~= 340 "-ldsfmlc-graphics -ldsfmlc-window -ldsfmlc-audio " ~ 341 "-ldsfmlc-network -ldsfmlc-system "; 342 343 linkToSFMLLibs ~= 344 "-lsfml-graphics -lsfml-window -lsfml-audio "~ 345 "-lsfml-network -lsfml-system "; 346 347 linkToSFMLLibs ~= "-lstdc++ "; 348 349 //linkToSFMLLibs ~= 350 //"-lstdc++ -lFLAC -logg -lvorbisfile -lvorbisenc -lvorbis "~ 351 //"-lopenal -lX11 -ludev -lGL -lXrandr -ljpeg -lfreetype"; 352 } 353 354 355 singleFileSwitches = archSwitch ~ " -c -O3 -frelease -Isrc"; 356 libCompilerSwitches = archSwitch ~ " -Isrc"; 357 docCompilerSwitches = " -c -fdoc -I../../src"; 358 359 unittestCompilerSwitches = 360 "-funittest -fversion=DSFML_Unittest_System " ~ 361 "-fversion=DSFML_Unittest_Window -fversion=DSFML_Unittest_Graphics " ~ 362 "-fversion=DSFML_Unittest_Audio -fversion=DSFML_Unittest_Network "~ 363 linkToSFMLLibs; 364 365 } 366 367 void initializeLDC() 368 { 369 string linkToSFMLLibs = ""; 370 371 //fix this before testing on windows 372 version(Windows) 373 { 374 writeln("Building for Windows with ldc"); 375 prefix = ""; 376 extension = ".lib"; 377 objExt = ".obj"; 378 379 //Default to 64 bit on windows because why wouldn't we? 380 if(!force64Build || !force32Build) 381 { 382 archSwitch = " -m64"; 383 } 384 385 makefileProgram = "nmake"; 386 makefileType = `"NMake Makefiles"`; 387 388 linkToSFMLLibs = "-L=/LIBPATH:lib -L=/LIBPATH:SFML\\lib "~ 389 "-L=/LIBPATH:SFML\\extlibs\\libs-msvc-universal\\x64 "; 390 391 linkToSFMLLibs ~= 392 "dsfmlc-graphics.lib dsfmlc-window.lib dsfmlc-audio.lib " ~ 393 "dsfmlc-network.lib dsfmlc-system.lib "; 394 395 linkToSFMLLibs~= 396 "sfml-graphics.lib sfml-window.lib sfml-audio.lib "~ 397 "sfml-network.lib sfml-system.lib "; 398 399 /*linkToSFMLLibs~= 400 "opengl32.lib gdi32.lib flac.lib freetype.lib jpeg.lib ogg.lib "~ 401 "openal32.lib vorbis.lib vorbisenc.lib vorbisfile.lib ws2_32.lib "~ 402 "winmm.lib user32.lib "; 403 */ 404 } 405 else version(linux) 406 { 407 writeln("Building for Linux with ldc"); 408 prefix = "lib"; 409 extension = ".a"; 410 objExt = ".o"; 411 412 makefileProgram = "make"; 413 makefileType = `"Unix Makefiles"`; 414 415 416 linkToSFMLLibs = "-L=-Llib -L=-LSFML/lib "; 417 418 linkToSFMLLibs ~= 419 "-L=-ldsfmlc-graphics -L=-ldsfmlc-window -L=-ldsfmlc-audio " ~ 420 "-L=-ldsfmlc-network -L=-ldsfmlc-system "; 421 422 linkToSFMLLibs ~= 423 "-L=-lsfml-graphics -L=-lsfml-window -L=-lsfml-audio "~ 424 "-L=-lsfml-network -L=-lsfml-system "; 425 426 linkToSFMLLibs ~= "-L=-lstdc++ "; 427 428 //linkToSFMLLibs ~= 429 //"-L=-lstdc++ -L=-lFLAC -L=-logg -L=-lvorbisfile -L=-lvorbisenc "~ 430 //"-L=-lvorbis -L=-lopenal -L=-lX11 -L=-ludev -L=-lGL -L=-lXrandr "~ 431 //"-L=-ljpeg -L=-lfreetype"; 432 } 433 else 434 { 435 writeln("Building for OSX with ldc"); 436 prefix = "lib"; 437 extension = ".a"; 438 objExt = ".o"; 439 440 makefileProgram = "make"; 441 makefileType = `"Unix Makefiles"`; 442 443 linkToSFMLLibs = "-L=-Llib -L=-LSFML/lib "; 444 445 linkToSFMLLibs ~= 446 "-L=-ldsfmlc-graphics -L=-ldsfmlc-window -L=-ldsfmlc-audio " ~ 447 "-L=-ldsfmlc-network -L=-ldsfmlc-system "; 448 449 linkToSFMLLibs ~= 450 "-L=-lsfml-graphics -L=-lsfml-window -L=-lsfml-audio "~ 451 "-L=-lsfml-network -L=-lsfml-system "; 452 453 linkToSFMLLibs ~= "-L=-lstdc++ -L=-rpath -L=. "; 454 } 455 456 singleFileSwitches = archSwitch ~ " -c -O -release -oq -I=src"; 457 libCompilerSwitches = archSwitch ~ " -lib -I=src"; 458 docCompilerSwitches = " -c -o- -op -D -Dd=../../doc -I=../../src"; 459 460 unittestCompilerSwitches = 461 "-main -unittest -d-version=DSFML_Unittest_System " ~ 462 "-d-version=DSFML_Unittest_Window -d-version=DSFML_Unittest_Graphics " ~ 463 "-d-version=DSFML_Unittest_Audio -d-version=DSFML_Unittest_Network "~ 464 linkToSFMLLibs; 465 } 466 467 //build the static libraries. Returns true on successful build, false on unsuccessful build 468 bool buildLibs() 469 { 470 import std.ascii; //toUpper 471 472 if(!exists("lib/")) 473 { 474 mkdir("lib/"); 475 } 476 477 478 479 if(!exists("CMakeCache.txt")) 480 { 481 auto pid = spawnShell("cmake -G"~makefileType~" ."); 482 if(wait(pid) != 0) 483 { 484 //oh shit, what up? 485 return false; 486 } 487 } 488 489 //always try to rebuild c++ files. They will be skipped if nothing to do. 490 auto pid = spawnProcess([makefileProgram]); 491 if(wait(pid) != 0) 492 { 493 //oh shit, what up? 494 return false; 495 } 496 497 writeln(); 498 499 //go trhough each module directory, build d source files if need be, 500 //populate a list of all object files (both d and cpp), 501 //and build a static lib. 502 foreach(theModule;modules) 503 { 504 if(selectedModule != "" && theModule != selectedModule) 505 { 506 continue; 507 } 508 509 //+1 for lib file 510 size_t numberOfFiles = fileList[theModule].length + 1; 511 int currentFile = 1; 512 string files = ""; 513 foreach (string name; fileList[theModule]) 514 { 515 string objectFile = "src/dsfml/" ~theModule~"/"~name~objExt; 516 string dFile = "src/dsfml/" ~theModule~"/"~name~".d"; 517 518 version(DigitalMars) 519 { 520 string buildCommand = compiler~dFile~singleFileSwitches~ 521 " -of" ~objectFile; 522 } 523 else version(GNU) 524 { 525 string buildCommand = compiler~dFile~singleFileSwitches~ 526 " -o" ~objectFile; 527 } 528 else version(LDC) 529 { 530 string buildCommand = compiler~dFile~singleFileSwitches~ 531 " -of=" ~objectFile; 532 } 533 534 535 if(needToBuild(objectFile, dFile)) 536 { 537 progressOutput(currentFile, numberOfFiles, dFile); 538 539 auto status = executeShell(buildCommand); 540 if(status.status !=0) 541 { 542 writeln(status.output); 543 return false; 544 } 545 } 546 547 files~= objectFile ~ " "; 548 currentFile++; 549 } 550 551 552 string buildCommand = compiler ~ files; 553 554 version(DigitalMars) 555 { 556 //adding the library to dmd doesn't work on OSX 557 version(OSX) 558 { 559 buildCommand = "cd "~"src/dsfml/"~theModule~"/ && "~ 560 "ar -x ../../../lib/"~prefix~"dsfmlc-"~theModule~extension ~ " && "~ 561 " ar rcs ../../../lib/libdsfml-"~theModule~extension~" *"~objExt~"&& "~ 562 "cd ../../../"; 563 } 564 else 565 { 566 //build the static libs directly 567 buildCommand ~= " -lib -L-Llib/ -L-l"~"dsfmlc-"~theModule~extension ~ 568 " -oflib/"~prefix~"dsfml-"~theModule~extension~archSwitch; 569 } 570 } 571 else version(GNU) 572 { 573 writeln("building the library"); 574 575 //we want to use ar here, so we'll completely reset the build command 576 577 buildCommand = "cd "~"src/dsfml/"~theModule~"/ && "~ 578 "ar -x ../../../lib/"~prefix~"dsfmlc-"~theModule~extension ~ " && "~ 579 " ar rcs ../../../lib/libdsfml-"~theModule~extension~" *"~objExt~"&& "~ 580 "cd ../../../"; 581 582 } 583 else 584 { 585 version(OSX) 586 { 587 buildCommand = "cd "~"src/dsfml/"~theModule~"/ && "~ 588 "ar -x ../../../lib/"~prefix~"dsfmlc-"~theModule~extension ~ " && "~ 589 " ar rcs ../../../lib/libdsfml-"~theModule~extension~" *"~objExt~"&& "~ 590 "cd ../../../"; 591 } 592 else 593 { 594 buildCommand ~= " -lib lib/"~prefix~"dsfmlc-"~theModule~extension ~ 595 " -of=lib/"~prefix~"dsfml-"~theModule~extension~archSwitch; 596 } 597 //buildCommand ~= " -of="~quoteString(libDirectory~prefix~"dsfml-"~theModule~extension); 598 } 599 600 601 //always rebuilds the lib in case the cpp files were re-built 602 auto status = executeShell(buildCommand); 603 604 //writeln(buildCommand); 605 606 if(status.status !=0) 607 { 608 writeln("Something happened!"); 609 writeln(status.output); 610 return false; 611 } 612 613 writeln("[100%] Built "~prefix~"dsfml-" ~ theModule~extension); 614 } 615 616 return true; 617 } 618 619 bool buildUnittests() 620 { 621 622 version(Windows) 623 { 624 //technically, we also need .lib files because Windows is stupid, but 625 //the build script will only look for the .dll's. 626 string dynamicExtension = "-2.dll"; 627 } 628 else version(linux) 629 { 630 string dynamicExtension = ".so"; 631 } 632 else 633 { 634 string dynamicExtension = ".dylib"; 635 } 636 637 import std.ascii; //toUpper 638 //string[2] testModules = ["system", "network"]; 639 //check to make sure ALL SFML libs were built 640 foreach(theModule; modules) 641 { 642 if(!exists("SFML/lib/"~prefix~"sfml-"~theModule~dynamicExtension)) 643 { 644 writeln("SFML/lib/"~prefix~"sfml-"~theModule~dynamicExtension, 645 " not found."); 646 writeln("Building unit tests requires SFML libs in ", 647 "dsfml/SFML/lib/ directory."); 648 return false; 649 } 650 } 651 652 if(!exists("CMakeCache.txt")) 653 { 654 auto pid = spawnShell("cmake -G"~makefileType~" ."); 655 if(wait(pid) != 0) 656 { 657 //oh shit, what up? 658 return false; 659 } 660 } 661 662 //always try to rebuild c++ files. They will be skipped if nothing to do. 663 auto pid = spawnProcess([makefileProgram]); 664 if(wait(pid) != 0) 665 { 666 //oh shit, what up? 667 return false; 668 } 669 670 string files = ""; 671 672 foreach(theModule;modules) 673 { 674 foreach(string name; fileList[theModule]) 675 { 676 files~= "src/dsfml/" ~theModule~"/"~name~".d "; 677 } 678 } 679 680 string buildCommand = compiler; 681 682 version(DigitalMars) 683 { 684 buildCommand ~= files~" "~unittestCompilerSwitches~archSwitch; 685 buildCommand ~= " -ofunittest/unittest"; 686 } 687 else version(GNU) 688 { 689 std.file.write("main.d", "void main(){}"); 690 691 buildCommand ~= "main.d "~files~unittestCompilerSwitches~archSwitch~ 692 " -ounittest/unittest -Wl,--verbose"; 693 } 694 else 695 { 696 buildCommand ~= unittestCompilerSwitches~archSwitch~" -oq "~files; 697 buildCommand ~= "-of=unittest/unittest"; 698 //buildCommand ~= " -of="~quoteString(libDirectory~prefix~"dsfml-"~theModule~extension); 699 } 700 701 version(Windows) 702 { 703 buildCommand ~= ".exe"; 704 } 705 706 writeln(buildCommand); 707 708 709 //std.file.write("cmdFile") 710 //remove(deleteme); 711 712 713 714 auto status = executeShell(buildCommand); 715 716 version(GNU) 717 { 718 std.file.remove("main.d"); 719 } 720 721 if(status.status !=0) 722 { 723 writeln(status.output); 724 return false; 725 } 726 727 return true; 728 } 729 730 bool buildDocumentation() 731 { 732 if(!exists("doc/")) 733 { 734 mkdir("doc/"); 735 } 736 737 chdir("src/dsfml/"); 738 739 string docExtension; 740 string ddoc; 741 if(buildingWebsiteDocs) 742 { 743 docExtension = ".php"; 744 745 version(GNU) 746 ddoc = "../../doc/website_documentation.ddoc"; 747 else 748 ddoc = " ../../doc/website_documentation.ddoc"; 749 } 750 else 751 { 752 docExtension = ".html"; 753 version(GNU) 754 ddoc = "../../doc/default_ddoc_theme.ddoc"; 755 else 756 ddoc = " ../../doc/local_documentation.ddoc"; 757 } 758 759 foreach(theModule;modules) 760 { 761 if(selectedModule != "" && theModule != selectedModule) 762 { 763 continue; 764 } 765 766 // skipping package.d 767 size_t numberOfFiles = fileList[theModule].length -1 ; 768 int currentFile = 1; 769 foreach (string name; fileList[theModule]) 770 { 771 if (name == "package") 772 continue; 773 string docFile = "../../doc/"~theModule~"/"~name~docExtension; 774 string outputFile = name~docExtension; 775 string dFile = theModule~"/"~name~".d"; 776 777 778 string buildCommand; 779 780 version(GNU) 781 { 782 buildCommand = compiler~dFile~" -fdoc-inc="~ddoc~ 783 " -fdoc-dir=../../doc/dsfml/"~theModule~ 784 docCompilerSwitches~" -o obj.o"; 785 } 786 else 787 buildCommand = compiler~dFile~ddoc~docCompilerSwitches; 788 789 if(needToBuild(docFile, dFile)) 790 { 791 progressOutput(currentFile, numberOfFiles, outputFile); 792 793 auto status = executeShell(buildCommand); 794 if(status.status !=0) 795 { 796 writeln(status.output); 797 return false; 798 } 799 800 if(docExtension!=".html") 801 rename("../../doc/"~theModule~"/"~name~".html", 802 "../../doc/"~theModule~"/"~name~docExtension); 803 } 804 805 currentFile++; 806 } 807 } 808 809 version(GNU) 810 core.stdc.stdio.remove("obj.o"); 811 812 chdir("../.."); 813 814 return true; 815 } 816 817 /** 818 * Display the progress as a percentage given the current file is next. 819 * 820 * Display example: 821 * [ 20%] Building dsfml/src/system/clock.d 822 */ 823 void progressOutput(int current, size_t total, string file) 824 { 825 size_t percentage = (current*100)/total; 826 827 writefln("[%3u%%] Building %s", percentage, file); 828 } 829 830 /** 831 * Checks the timestamps on the object file and its associated source file. 832 * 833 * If the source file has been more recently updated than the object file was 834 * built, or if the object file doesn't yet exist, this will return true. 835 */ 836 bool needToBuild(string objLocation, string srcLocation) 837 { 838 import std.file: exists, timeStamp = timeLastModified; 839 840 return exists(objLocation)?timeStamp(objLocation) < timeStamp(srcLocation): 841 true; 842 } 843 844 string singleSplitter(string haystack, char needle, ref int startPos) 845 { 846 int i; 847 for(i = startPos; i < haystack.length; i++) 848 { 849 if(haystack[i] == needle) 850 break; 851 } 852 853 if(i >= haystack.length) 854 return null; 855 auto ret = haystack[startPos .. i]; 856 startPos = i+1; 857 return ret; 858 } 859 860 string pathToMSVCToolChain() 861 { 862 string dmdPath; 863 auto paths = environment.get("PATH"); 864 int start = 0; 865 auto path = singleSplitter(paths, ';', start); 866 867 while(path !is null) 868 { 869 870 if(canFind(path, "dmd2")) 871 { 872 dmdPath = path; 873 } 874 path = singleSplitter(paths, ';', start); 875 } 876 877 File scFile = File(dmdPath~"\\sc.ini", "r"); 878 char[] buf; 879 880 while(!canFind(buf, "VCINSTALLDIR=")) 881 { 882 scFile.readln(buf); 883 //writeln(buf); 884 } 885 886 //$-1 because the buffer ends with \n 887 return buf[13 ..$-1].idup; 888 889 } 890 891 int main(string[] args) 892 { 893 894 GetoptResult optInfo; 895 try 896 { 897 optInfo = getopt(args, 898 "lib", "Build static libraries.", &buildingLibs, 899 "m32", "Force 32 bit building.", &force32Build, 900 "m64", "Force 64 bit building.", &force64Build, 901 "unittest", "Build DSFML unit test executable.", &buildingUnittests, 902 "doc", "Build DSFML documentation.", &buildingDoc, 903 "webdoc", "Build the DSFML website documentation.", &buildingWebsiteDocs 904 ); 905 } 906 catch(GetOptException e) 907 { 908 writeln(e.msg); 909 return -1; 910 } 911 912 if(optInfo.helpWanted) 913 { 914 defaultGetoptPrinter("Switch Information\n" 915 ~"Default (no switches passed) will be to build static libraries with the compiler that built this.", 916 optInfo.options); 917 return 0; 918 } 919 920 //default to building libs 921 if(!buildingLibs && !buildingDoc && !buildingInterfaceFiles && 922 !buildingWebsiteDocs && !buildingUnittests && !buildingAll) 923 { 924 buildingLibs = true; 925 } 926 927 /* 928 writeln("lib ", buildingLibs); 929 writeln("doc ", buildingDoc); 930 writeln("import ",buildingInterfaceFiles); 931 writeln("unittest ", buildingUnittests); 932 writeln("all ", buildingAll); 933 writeln("sharedDir ", unittestLibraryLocation); 934 writeln("m32 ", force32Build); 935 writeln("m64 ", force64Build); 936 writeln("dmd ", forceDMD); 937 writeln("gdc ", forceGDC); 938 writeln("ldc ", foorceLDC); 939 */ 940 941 if(!checkSwitchErrors()) 942 { 943 return -1; 944 } 945 946 writeln(); 947 initialize(); 948 if(buildingLibs) 949 { 950 if(!buildLibs()) 951 return -1; 952 } 953 if(buildingUnittests) 954 { 955 if(!buildUnittests()) 956 return -1; 957 } 958 if(buildingDoc || buildingWebsiteDocs) 959 { 960 if(!buildDocumentation()) 961 return -1; 962 } 963 964 return 0; 965 }