1# Include BuildConfig 2{ 3 local buildConfig = [ GLOB $(OBOS_TOP) : BuildConfig ] ; 4 if ! $(buildConfig) 5 { 6 EXIT "No BuildConfig!" 7 "Run ./configure in the source tree's root directory first!" ; 8 } 9 include $(buildConfig) ; 10} 11 12# Determine if we're building on PPC or x86 13# Determine mimetype of executable 14# Cross compiling can come later 15 16if $(METROWERKS) { 17 OBOS_TARGET ?= "ppc.R1" ; 18 OBOS_TARGET_TYPE ?= "application/x-be-executable" ; 19 OBOS_ARCH ?= "ppc" ; 20 OBOS_TARGET_DEFINE ?= "ARCH_ppc" ; 21} else { 22 OBOS_TARGET ?= "x86.R1" ; 23 OBOS_TARGET_TYPE ?= "application/x-vnd.Be-elfexecutable" ; 24 OBOS_ARCH ?= "x86" ; 25 OBOS_TARGET_DEFINE ?= "ARCH_x86" ; 26 OBOS_TARGET_DIR ?= "x86" ; 27} 28 29# Enable warnings only if WARNINGS is defined 30# Should be enabled by default later 31 32if $(WARNINGS) { 33 # For an explanation of the different warning options, see: 34 # http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_2.html 35 # to get even more warnings, add: 36 # -Wwrite-strings (doesn't work well with some Be headers) 37 # -Wundef (dito) 38 # -Wconversion (gets you many warnings about implicit conversions) 39 # -W (gets you even more warnigs) 40 CCFLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes" ; 41 CCFLAGS += "-Wpointer-arith -Wcast-align -Wsign-compare" ; 42 C++FLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes -Wno-ctor-dtor-privacy -Woverloaded-virtual" ; 43 C++FLAGS += "-Wpointer-arith -Wcast-align -Wsign-compare" ; 44} 45 46KERNEL_CCFLAGS ?= "-Wall -Wno-multichar -Wmissing-prototypes -finline -nostdinc" ; 47KERNEL_CCFLAGS += "-fno-builtin -D$(OBOS_TARGET_DEFINE) " ; 48 49AR = ar r ; 50OPTIM = -O2 ; 51 52# If no OBOS_OBJECT_TARGET is not defined yet, use our default directory and 53# include our "OBOS_TARGET" as subdirectory in there (to prevent different 54# builds mixing objects from different targets). 55if ! $(OBOS_OBJECT_TARGET) { 56 OBOS_OBJECT_TARGET ?= [ FDirName $(OBOS_TOP) objects $(OBOS_TARGET) ] ; 57} 58 59# If no OBOS_DISTRO_TARGET is not defined yet, use our default directory and 60# include our "OBOS_TARGET" as subdirectory in there (to prevent different 61# builds mixing executables from different targets). 62if ! $(OBOS_DISTRO_TARGET) { 63 OBOS_DISTRO_TARGET ?= [ FDirName $(OBOS_TOP) distro $(OBOS_TARGET) ] ; 64} 65 66# Set our version number if not already set and mark it as a developer build 67if ! $(OBOS_BUILD_VERSION) { 68 OBOS_BUILD_VERSION ?= "1 0 0 a 1" ; 69 OBOS_BUILD_DESCRIPTION ?= "Developer Build" ; 70} 71 72# If OBOS_BUILD_VERSION is set, but OBOS_BUILD_DESCRIPTION isn't, mark it as 73# an unknown build. 74if ! $(OBOS_BUILD_DESCRIPTION) { 75 OBOS_BUILD_DESCRIPTION ?= "Unknown Build" ; 76} 77 78# Relative subdirs for distro dir (these are for *INTERNAL* use by the following rules only!) 79OBOS_APPS_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos apps ] ; 80OBOS_BIN_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos bin ] ; 81OBOS_PREFS_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos preferences ] ; 82OBOS_SERVER_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system servers ] ; 83OBOS_ADDON_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system add-ons ] ; 84OBOS_SHLIB_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system lib ] ; 85OBOS_STLIB_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system lib ] ; 86OBOS_KERNEL_DIR ?= [ FDirName $(OBOS_DISTRO_TARGET) beos system ] ; 87OBOS_TEST_DIR ?= [ FDirName $(OBOS_TOP) tests ] ; 88 89OBOS_KERNEL_CONFIG = config.$(OBOS_ARCH).ini ; 90OBOS_KERNEL = kernel.$(OBOS_ARCH) ; 91OBOS_FLOPPY = floppy.$(OBOS_ARCH) ; 92 93rule SetupIncludes 94{ 95 OBOS_INCLUDES ?= . add-ons app be_apps device drivers game interface kernel mail media midi midi2 net opengl storage support translation ; 96 UsePublicHeaders $(OBOS_INCLUDES) ; 97 UsePosixHeaders ; 98} 99 100#------------------------------------------------------------------------------- 101# Things Jam needs in order to work :) 102#------------------------------------------------------------------------------- 103 104rule UserObject 105{ 106 switch $(2) 107 { 108 case *.S : assemble $(1) : $(2) ; 109 case *.o : return ; 110 case * : ECHO "unknown suffix on" $(2) ; 111 } 112} 113 114# Override the default to give "prettier" command lines. 115actions Cc 116{ 117 $(CC) -c "$(2)" $(CCFLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ; 118} 119 120actions C++ 121{ 122 $(C++) -c "$(2)" $(C++FLAGS) $(CCDEFS) $(CCHDRS) -o "$(1)" ; 123} 124 125 126#------------------------------------------------------------------------------- 127# General High-level OBOS target rules 128#------------------------------------------------------------------------------- 129 130rule App 131{ 132 # App <name> : <sources> ; 133 SetupObjectsDir ; 134 Main $(<) : $(>) ; 135 MakeLocate $(<) : $(OBOS_APPS_DIR) ; 136} 137 138rule BinCommand 139{ 140 # BinCommand <name> : <sources> : <libraries> ; 141 SetupObjectsDir ; 142 Main $(1) : $(2) ; 143 MakeLocate $(1) : $(OBOS_BIN_DIR) ; 144 LinkSharedOSLibs $(1) : $(3) ; 145} 146 147rule StdBinCommands 148{ 149 # StdBinCommands <sources> : <libs> ; 150 local libs = $(2) ; 151 for source in $(1) 152 { 153 local target = $(source:S=) ; 154 target = [ FGristFiles $(target) ] ; 155 BinCommand $(target) : $(source) : $(libs) ; 156 } 157} 158 159rule Preference 160{ 161 # Preference <name> : <sources> ; 162# SetupIncludes ; 163 SetupObjectsDir ; 164 Main $(<) : $(>) ; 165 MakeLocate $(<) : $(OBOS_PREFS_DIR) ; 166} 167 168rule Server 169{ 170 # Server <name> : <sources> ; 171 172# SetupIncludes ; 173 SetupObjectsDir ; 174 Main $(<) : $(>) ; 175 MakeLocate $(<) : $(OBOS_SERVER_DIR) ; 176} 177 178# test pseudo targets 179NOTFILE obostests ; 180NOTFILE r5tests ; 181 182rule CommonUnitTest 183{ 184 # CommonUnitTest <target> : <sources> : <dest> : <obos libraries> 185 # : <r5 libraries> : <public headers>; 186 # Builds a unit test for both OBOS and R5 modules. 187 # <target> The name of the target. 188 # <sources> The list of sources. 189 # <dest> The directory for the target (as passed to FDirName). 190 # <obos libraries> A list of link libraries for the OBOS tests (as passed 191 # to LinkSharedOSLibs). 192 # <r5 libraries> A list of link libraries for the R5 tests (as passed 193 # to LinkSharedOSLibs). 194 # <public headers> A list of public header dirs (as passed to 195 # UsePublicHeaders). 196 197 UnitTest $(1) : $(2) : $(3) : $(4) : $(6) ; 198 R5UnitTest $(1) : $(2) : $(3) : $(5) ; 199} 200 201rule UnitTest 202{ 203 # UnitTest <target> : <sources> : <dest> : <libraries> : <public headers> 204 # Builds a unit test for an OBOS module. 205 # <target> The name of the target. 206 # <sources> The list of sources. 207 # <dest> The directory for the target (as passed to FDirName). 208 # <libraries> A list of link libraries (as passed to LinkSharedOSLibs). 209 # <public headers> A list of public header dirs (as passed to 210 # UsePublicHeaders). 211 212 local target = $(1) ; 213 local sources = $(2) ; 214 local dest = $(3) ; 215 local libraries = $(4) ; 216 local headerDirs = $(5) ; 217 218 # Turn optimization off. 219 local optim = $(OPTIM) ; 220 OPTIM = ; 221 222# SetupIncludes ; 223 UseCppUnitHeaders ; 224 SetupObjectsDir ; 225 MakeLocateObjects $(sources) ; 226 Main $(target) : $(sources) ; 227 MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(dest) ] ; 228 DEPENDS $(target) : libcppunit.so ; 229 DEPENDS obostests : $(target) ; 230 LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ; 231 UsePublicObjectHeaders $(sources) : $(headerDirs) ; 232 ObjectDefines $(sources) : TEST_OBOS ; 233 234 # Turn debugging on. That is usually desired for test code. 235 ObjectCcFlags $(sources) : "-g" ; 236 ObjectC++Flags $(sources) : "-g" ; 237 238 # Turn optimization on again. 239 OPTIM = $(optim) ; 240} 241 242rule R5UnitTest 243{ 244 # R5UnitTest <target> : <sources> : <dest> : <libraries> 245 # Builds a unit test for an R5 module. "_r5" is appended to the object 246 # and the target name. 247 # <target> The name of the target. 248 # <sources> The list of sources. 249 # <dest> The directory for the target (as passed to FDirName). 250 # <libraries> A list of link libraries (as passed to LinkSharedOSLibs). 251 252 local target = $(1)_r5 ; 253 local sources = $(2) ; 254 local dest = $(3) ; 255 local libraries = $(4) ; 256 local objects = [ R5ObjectNames $(sources) ] ; 257 258 # Turn optimization off. 259 local optim = $(OPTIM) ; 260 OPTIM = ; 261 262 UseCppUnitHeaders ; 263 SetupObjectsDir ; 264 MakeLocateObjects $(objects) ; 265 266 # Our Main replacement. 267 MainFromObjects $(target) : $(objects) ; 268 local source ; 269 for source in [ FGristFiles $(sources) ] 270 { 271 local object = [ R5ObjectNames $(source) ] ; 272 Object $(object) : $(source) ; 273 Depends obj : $(object) ; 274 } 275 276 MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(dest) ] ; 277 DEPENDS $(target) : libcppunit.so ; 278 DEPENDS r5tests : $(target) ; 279 LinkSharedOSLibs $(target) : libcppunit.so $(libraries) ; 280 ObjectDefines $(objects) : TEST_R5 ; 281 282 # Turn debugging on. That is usually desired for test code. 283 ObjectCcFlags $(objects) : "-g" ; 284 ObjectC++Flags $(objects) : "-g" ; 285 286 # Turn optimization on again. 287 OPTIM = $(optim) ; 288} 289 290rule R5ObjectNames 291{ 292 # R5ObjectNames <sources> ; 293 # Returns a list of gristed object names given a list of source file names. 294 # Moreover each object names gets "_r5" inserted before the object suffix. 295 local objects = $(1:S=)_r5 ; 296 return [ FGristFiles $(objects:S=$(SUFOBJ)) ] ; 297} 298 299rule SimpleTest 300{ 301 # UnitTest <target> : <sources> : <libraries> 302 # Builds a unit test for an OBOS module. 303 # <target> The name of the target. 304 # <sources> The list of sources. 305 # <dest> The directory for the target (as passed to FDirName). 306 # <libraries> A list of link libraries (as passed to LinkSharedOSLibs). 307 # <public headers> A list of public header dirs (as passed to 308 # UsePublicHeaders). 309 310 local target = $(1) ; 311 local sources = $(2) ; 312 local libraries = $(3) ; 313 local relPath = [ FRelPath src tests : $(SUBDIR_TOKENS) ] ; 314 315 # Turn optimization off. 316 local optim = $(OPTIM) ; 317 OPTIM = ; 318 319# SetupIncludes ; 320 SetupObjectsDir ; 321 MakeLocateObjects $(sources) ; 322 Main $(target) : $(sources) ; 323 MakeLocate $(target) : [ FDirName $(OBOS_TEST_DIR) $(relPath) ] ; 324 DEPENDS obostests : $(target) ; 325 LinkSharedOSLibs $(target) : $(libraries) ; 326 ObjectDefines $(sources) : TEST_OBOS ; 327 328 # Turn debugging on. That is usually desired for test code. 329 ObjectCcFlags $(sources) : "-g" ; 330 ObjectC++Flags $(sources) : "-g" ; 331 332 # Turn optimization on again. 333 OPTIM = $(optim) ; 334} 335 336rule Addon 337{ 338 # Addon <name> : <relpath> : <sources> ; 339 340# SetupIncludes ; 341 SetupObjectsDir ; 342 Main $(1) : $(3) ; 343 344 # Create output dir path for addon 345 local targetdir; 346 targetdir = [ FDirName $(OBOS_ADDON_DIR) $(2) ] ; 347 348 MakeLocate $(1) : $(targetdir) ; 349 LINKFLAGS on $(1) = $(LINKFLAGS) -nostart -Xlinker -soname=\"$(1)\" ; 350} 351 352rule MakeLocateObjects 353{ 354 # MakeLocateObjects <gristed_sources_or_objects> ; 355 356 local _objs = $(1:S=$(SUFOBJ)) ; 357 358 for o in $(_objs) 359 { 360 local dir = $(o:D) ; 361 if $(dir) { 362 MakeLocate $(o) : [ FDirName $(LOCATE_TARGET) $(dir) ] ; 363 } else { 364 MakeLocate $(o) : $(LOCATE_TARGET) ; 365 } 366 } 367} 368 369rule StaticLibrary 370{ 371 # StaticLibrary <name> : <sources> ; 372 373# SetupIncludes ; 374 SetupObjectsDir ; 375 MakeLocateObjects $(2) ; 376 Library lib$(<).a : $(>) ; 377 MakeLocate lib$(<).a : $(OBOS_STLIB_DIR) ; 378} 379 380rule SharedLibrary 381{ 382 # SharedLibrary <name> : <sources> ; 383 local _lib = lib$(1).so ; 384 385# SetupIncludes ; 386 SetupObjectsDir ; 387 MakeLocateObjects $(2) ; 388 Main $(_lib) : $(2) ; 389 MakeLocate $(_lib) : $(OBOS_SHLIB_DIR) ; 390 LINKFLAGS on $(_lib) = $(LINKFLAGS) -nostart -Xlinker -soname=\"$(_lib)\" ; 391} 392 393rule LinkSharedOSLibs 394{ 395 # LinkSharedOSLibs <name> : <libs> ; 396 # Valid elements for <libs> are e.g. "be" or "libopenbeos.so" or 397 # "/boot/.../libfoo.so". If the basename starts with "lib" or the thingy 398 # has a dirname or grist, it is added to the NEEDLIBS variable (i.e. the 399 # file will be bound!), otherwise it is prefixed "-l" and added to 400 # LINKLIBS. 401 402 for i in $(>) 403 { 404 local isfile = ; 405 if $(i:D) || $(i:G) { 406 isfile = true ; 407 } else { 408 switch $(i:B) 409 { 410 case lib* : isfile = true ; 411 case * : isfile = ; 412 } 413 } 414 if $(isfile) { 415 NEEDLIBS on $(1) += $(i) ; 416 DEPENDS $(1) : $(i) ; 417 } else { 418 LINKLIBS on $(1) += -l$(i) ; 419 } 420 } 421} 422 423rule LinkStaticOSLibs 424{ 425 # LinkStaticOSLibs <name> : <libs> ; 426 427 for i in $(>) 428 { 429 LINKLIBS on $(<) = $(LINKLIBS) -l $(i) ; 430 } 431} 432 433rule AddResources 434{ 435 # AddResources <name> : <resourcefiles> ; 436 437 SEARCH on $(2) += $(SEARCH_SOURCE) ; 438 RESFILES on $(1) += $(2) ; 439} 440 441rule PublicHeaders 442{ 443 # PublicHeaders <group list> 444 # 445 # Returns the directory names for the public header dirs identified by 446 # <group list>. 447 448 local list = $(1) ; 449 local dirs ; 450 for i in $(list) { 451 dirs += [ FDirName $(OBOS_TOP) headers os $(i) ] ; 452 } 453 return $(dirs) ; 454} 455 456rule PrivateHeaders 457{ 458 # PrivateHeaders <group list> 459 # 460 # Returns the directory names for the private header dirs identified by 461 # <group list>. 462 463 local list = $(1) ; 464 local dirs ; 465 for i in $(list) { 466 dirs += [ FDirName $(OBOS_TOP) headers private $(i) ] ; 467 } 468 return $(dirs) ; 469} 470 471rule ArchHeaders 472{ 473 # usage: ArchHeaders <arch> ; 474 # 475 # <arch> specifies the architecture (e.g. x86). 476 477 return [ FDirName $(OBOS_TOP) headers private kernel arch $(1) ] ; 478} 479 480rule UsePublicHeaders 481{ 482 # UsePublicHeaders <group list> ; 483 # 484 # Adds the public C header dirs given by <group list> to the header search 485 # dirs of the subdirectory. 486 # NOTE: This rule must be invoked *before* the rule that builds the objects. 487 488 UseHeaders [ PublicHeaders $(1) ] ; 489} 490 491rule UsePublicObjectHeaders 492{ 493 # UsePublicObjectHeaders <sources_or_objects> : <group list> ; 494 # 495 # Adds the public C header dirs given by <group list> to the header search 496 # dirs of <sources_or_objects>. 497 # NOTE: This rule must be invoked *after* the rule that builds the objects. 498 499 ObjectHdrs $(1) : [ PublicHeaders $(2) ] ; 500} 501 502rule UsePrivateHeaders 503{ 504 # UsePrivateHeaders <group list> ; 505 # 506 # Adds the private C header dirs given by <group list> to the header search 507 # dirs of the subdirectory. 508 # NOTE: This rule must be invoked *before* the rule that builds the objects. 509 510 UseHeaders [ PrivateHeaders $(1) ] ; 511} 512 513rule UsePrivateObjectHeaders 514{ 515 # UsePrivateObjectHeaders <sources_or_objects> : <group list> ; 516 # 517 # Adds the private C header dirs given by <group list> to the header search 518 # dirs of <sources_or_objects>. 519 # NOTE: This rule must be invoked *after* the rule that builds the objects. 520 521 ObjectHdrs $(1) : [ PrivateHeaders $(2) ] ; 522} 523 524rule UseHeaders 525{ 526 # UseHeaders <headers> ; 527 # 528 # Adds the C header dirs <headers> to the header search 529 # dirs of the subdirectory. 530 # NOTE: This rule must be invoked *before* the rule that builds the objects. 531 532 local header ; 533 for header in $(1) { 534 SubDirHdrs $(header) ; 535 } 536} 537 538rule UseCppUnitHeaders 539{ 540 SubDirHdrs [ FDirName $(OBOS_TOP) headers tools cppunit ] ; 541} 542 543rule UseArchHeaders 544{ 545 # usage: UseArchHeaders <arch> ; 546 # 547 # <arch> specifies the architecture (e.g. x86). 548 # NOTE: This rule must be invoked *before* the rule that builds the objects. 549 550 local headers = [ ArchHeaders $(1) ] ; 551 local opt = -D$(OBOS_TARGET_DEFINE) ; 552 553 SubDirCcFlags $(opt) ; 554 SubDirC++Flags $(opt) ; 555 SubDirHdrs $(headers) ; 556} 557 558rule UseArchObjectHeaders 559{ 560 # usage: UseArchObjectHeaders <sources_or_objects> : <arch> ; 561 # 562 # <arch> specifies the architecture (e.g. x86). 563 # <sources_or_objects> Source or object files. 564 # NOTE: This rule must be invoked *after* the rule that builds the objects. 565 566 local targets = $(1) ; 567 local headers = [ ArchHeaders $(2) ] ; 568 local opt = -D$(OBOS_TARGET_DEFINE) ; 569 570 ObjectCcFlags $(targets) : $(opt) ; 571 ObjectC++Flags $(targets) : $(opt) ; 572 ObjectHdrs $(targets) : $(headers) ; 573} 574 575rule UsePosixHeaders 576{ 577 # UsePrivateHeaders <group list> ; 578 # 579 # Adds the POSIX header dir to the header search 580 # dirs of the subdirectory. 581 # NOTE: This rule must be invoked *before* the rule that builds the objects. 582 583 SubDirHdrs [ FDirName $(OBOS_TOP) headers posix ] ; 584} 585 586rule UsePosixObjectHeaders 587{ 588 # UsePosixObjectHeaders <sources_or_objects> ; 589 # 590 # Adds the POSIX header dir to the header search 591 # dirs of <sources_or_objects>. 592 # NOTE: This rule must be invoked *after* the rule that builds the objects. 593 594 ObjectHdrs $(1) : [ FDirName $(OBOS_TOP) headers posix ] ; 595} 596 597rule SplitPath 598{ 599 # SplitPath <path> ; 600 # Decomposes a path into its components. 601 local path = $(1:G=) ; 602 local components ; 603 while $(path:D) 604 { 605 # Note: $(path:B) returns "." for "..", but $(path:D=) is fine. 606 components = $(path:D=) $(components) ; 607 path = $(path:D) ; 608 } 609 components = $(path) $(components) ; 610 return $(components) ; 611} 612 613rule PrependObjectHdrs 614{ 615 # PrependObjectHdrs <objects_or_sources> : <dirs> ; 616 # Prepends <dirs> to the list of header search dirs of the objects 617 # specified by <objects_or_sources>. The HDRS variable will not be 618 # changed, only CCHDRS. 619 # Note: A subsequent ObjectHdrs invocation will therefore undo the 620 # effect of this rule. 621 # NOTE: This is a hack. 622 623 local objects = [ FGristFiles $(1:S=$(SUFOBJ)) ] ; 624 local dirs = $(2) ; 625 for object in $(objects) { 626 # Don't change HDRS to avoid screwing up the header scanning. 627 PREPENDED_HDRS on $(object) 628 = $(dirs) [ on $(object) return $(PREPENDED_HDRS) ] ; 629 CCHDRS on $(object) 630 = [ FIncludes [ on $(object) return $(PREPENDED_HDRS) $(HDRS) ] ] ; 631 } 632} 633 634rule SymLink 635{ 636 # SymLink <target> : <source> ; 637 # Links <target> to <source>. 638 # <source> is the exact link contents. No binding is done. 639 LINKCONTENTS on $(1) = $(2) ; 640 SymLink1 $(1) ; 641 DEPENDS all : $(target) ; 642} 643 644actions SymLink1 645{ 646 $(RM) "$(1)" && $(LN) -s "$(LINKCONTENTS)" "$(1)" 647} 648 649rule RelSymLink 650{ 651 # RelSymLink <link> : <link target> 652 # Creates a relative symbolic link from <link> to <link target>. 653 # <link> and <link target> can be usual targets. They may have a grist 654 # and don't need to have any dirname. Their LOCATE variables are used to 655 # find their locations. 656 657 local target = $(1) ; 658 local source = $(2) ; 659 local targetDir = [ on $(target) FDirName $(LOCATE[1]) $(target:D) ] ; 660 local sourceDir = [ on $(source) FDirName $(LOCATE[1]) $(source:D) ] ; 661 local sourcePath = $(source:G=) ; 662 sourcePath = $(sourcePath:D=$(sourceDir)) ; 663 local targetDirComponents = [ SplitPath $(targetDir) ] ; 664 local sourceComponents = [ SplitPath $(sourcePath) ] ; 665 666 SymLink $(target) 667 : [ FRelPath $(targetDirComponents) : $(sourceComponents) ] ; 668 NOUPDATE $(target); 669 DEPENDS $(target) : $(source) ; 670} 671 672#------------------------------------------------------------------------------- 673# Low-level OBOS utility rules 674#------------------------------------------------------------------------------- 675rule SetupObjectsDir 676{ 677 local rel_objectsdir; 678 679 # Copy subdir tokens except the first, as that will be "sources", and we 680 # do not want to include that :) 681 rel_objectsdir = [ FDirName $(SUBDIR_TOKENS[2-]) ] ; 682 LOCATE_TARGET = [ FDirName $(OBOS_OBJECT_TARGET) $(rel_objectsdir) ] ; 683} 684 685#------------------------------------------------------------------------------- 686# Link rule/action are overwritten as they don't handle linking files who's name 687# contain spaces very well. Also adds resources and version to executable. 688#------------------------------------------------------------------------------- 689rule Link 690{ 691 # Note: RESFILES must be set before invocation. 692 MODE on $(<) = $(EXEMODE) ; 693 on $(1) XRes $(1) : $(RESFILES) ; 694 SetVersion $(1) ; 695 Chmod $(<) ; 696 SetType $(1) ; 697 MimeSet $(1) ; 698} 699 700actions Link bind NEEDLIBS 701{ 702 $(LINK) $(LINKFLAGS) -o "$(1)" $(UNDEFS) "$(2)" "$(NEEDLIBS)" $(LINKLIBS) ; 703} 704 705# BeOS specific rules 706 707rule XRes 708{ 709 # XRes <target> : <resource files> 710 if $(2) 711 { 712 DEPENDS $(1) : $(2) ; 713 XRes1 $(1) : $(2) ; 714 } 715} 716 717rule XRes1 { } 718 719rule SetVersion 720{ 721 # SetVersion <target> 722} 723 724rule SetType 725{ 726 # SetType <target> 727} 728 729rule MimeSet 730{ 731 # SetType <target> 732} 733 734 735if $(OS) = BEOS 736{ 737 738actions XRes1 739{ 740 xres -o "$(1)" "$(2)" ; 741} 742 743actions SetVersion 744{ 745 setversion "$(1)" -system $(OBOS_BUILD_VERSION) -short "$(OBOS_BUILD_DESCRIPTION)" ; 746} 747 748actions SetType 749{ 750 settype -t $(OBOS_TARGET_TYPE) "$(1)" ; 751} 752 753actions MimeSet 754{ 755 mimeset -f "$(1)" ; 756} 757 758} # if BEOS 759 760 761rule assemble 762{ 763 DEPENDS $(1) : $(2) ; 764 Clean clean : $(1) ; 765} 766 767actions assemble 768{ 769 $(CC) -c "$(2)" -O2 $(KERNEL_CCFLAGS) -o "$(1)" ; 770} 771 772# Overridden to allow spaces in file names. 773actions Chmod1 774{ 775 $(CHMOD) "$(MODE)" "$(1)" 776} 777 778rule ObjectReference 779{ 780 # ObjectReference <reference object> : <source object> 781 # Makes <reference object> refer to the same file as <source object>. 782 # The filenames must of course be identical. 783 # <source object> must have already been LOCATEd. 784 785 local ref = $(1) ; 786 local source = $(2) ; 787 if $(ref) != $(source) { 788 DEPENDS $(ref) : $(source) ; 789 on $(ref) LOCATE = [ on $(source) return $(LOCATE) ] ; 790 } 791} 792 793rule ObjectReferences 794{ 795 # ObjectReferences <source objects> 796 # Creates local references to <source objects>, i.e. identifiers with the 797 # current grist referring to the same files. <source objects> must have 798 # already been LOCATEd. 799 800 local source ; 801 for source in $(1) { 802 ObjectReference [ FGristFiles $(source) ] : $(source) ; 803 } 804} 805 806rule Filter 807{ 808 # Filter <list> : <excludes> ; 809 # Removes all occurrences of <excludes> in <list>. 810 811 local list = $(1) ; 812 local excludes = $(2) ; 813 local newList ; 814 local item ; 815 for item in $(list) { 816 local skip ; 817 local exclude ; 818 for exclude in $(excludes) { 819 if $(item) = $(exclude) { 820 skip = true ; 821 } 822 } 823 if ! $(skip) { 824 newList += item ; 825 } 826 } 827 return $(newList) ; 828} 829 830 831## Kernel stuff! 832 833rule SetupKernel 834{ 835 # Usage SetupKernel <sources_or_objects> : <extra_cc_flags>; 836 837 local _objs = $(1:S=$(SUFOBJ)) ; 838 839 UsePublicHeaders kernel support drivers ; 840 UsePublicHeaders [ FDirName os kernel ] ; 841 UsePrivateHeaders kernel ; 842 UsePosixHeaders ; 843 UseArchHeaders $(OBOS_ARCH) ; 844 845 SetupObjectsDir ; 846 847 CCFLAGS on $(_objs) = $(KERNEL_CCFLAGS) $(2) ; 848 C++FLAGS on $(_objs) = $(KERNEL_CCFLAGS) $(2) ; 849} 850 851rule KernelObjects 852{ 853 SetupKernel $(1) : $(2) ; 854 855 Objects $(1) ; 856} 857 858rule KernelLd 859{ 860 # KernelLd <name> : <objs> : <linkerscript> : <args> : <gcc_off> ; 861 862 SetupKernel $(2) ; 863 LINK on $(1) = ld ; 864 865 LINKFLAGS on $(1) = $(4) ; 866 if $(3) { LINKFLAGS on $(1) += --script=$(3) ; } 867 868 # Remove any preset LINKLIBS 869 LINKLIBS on $(1) = ; 870 871 # Show that we depend on the libraries we need 872 Clean clean : $(1) ; 873 Depends all : $(1) ; 874 Depends $(1) : $(2) ; 875 876 if $(6) { 877 for i in $(6) { 878 KernelConfigSection $(i) : elf32 : $(1) ; 879 } 880 } 881 882 MakeLocate $(1) : $(LOCATE_TARGET) ; 883 884 # Add libgcc.a - NB this should be detected not hard coded! 885 if ! $(5) { 886 LINKLIBS on $(1) += -L $(GCC_PATH) -lgcc ; 887 } 888} 889 890actions KernelLd 891{ 892 $(LINK) $(LINKFLAGS) -o "$(1)" "$(2)" $(LINKLIBS) ; 893} 894 895rule KernelStaticLibrary 896{ 897 # Usage KernelStaticLibrary <name> : <sources> : <extra cc flags> ; 898 # This is designed to take a set of sources and libraries and create 899 # a file called lib<name>.a 900 901 SetupKernel $(2) : $(3) ; 902 903 MakeLocateObjects $(2) ; 904 Library $(1) : $(2) ; 905} 906 907rule KernelStaticLibraryObjects 908{ 909 # Usage KernelStaticLibrary <name> : <sources> ; 910 # This is designed to take a set of sources and libraries and create 911 # a file called <name> 912 913 SetupKernel $(2) ; 914 915 # Show that we depend on the libraries we need 916 Clean clean : $(1) ; 917 Depends all : $(1) ; 918 Depends $(1) : $(2) ; 919 920 MakeLocate $(1) : $(LOCATE_TARGET) ; 921} 922 923actions KernelStaticLibraryObjects 924{ 925 ar -r "$(1)" "$(2)" ; 926} 927 928rule SystemMain 929{ 930 # Usage SystemMain <target> : <sources> : <rqd_by> ; 931 SetupObjectsDir ; 932 933 LINKLIBS = ; 934 935 # This allows us to preset certain commands we use 936 # for building. 937 if $(3) { 938 for obj in $(3) { 939 BUILD_CMD on $(obj) = [ FDirName $(LOCATE_TARGET) $(1) ] ; 940 } 941 } 942 943 Main $(1) : $(2) ; 944} 945 946rule KernelConfigSection 947{ 948 # KernelConfigSection <section> : <type> : <file> ; 949 950 SECTION_NAMES on $(OBOS_KERNEL_CONFIG) += $(1) ; 951 SECTION_TYPES on $(OBOS_KERNEL_CONFIG) += $(2) ; 952 SECTION_FILES on $(OBOS_KERNEL_CONFIG) += $(3) ; 953 954 Depends $(OBOS_KERNEL_CONFIG) : $(3) ; 955} 956 957rule WriteKernelConfig 958{ 959 # usage: WriteKernelConfig <target> ; 960 961 Depends files : $(1) ; 962 963 MakeLocate $(1) : $(OBOS_OBJECT_TARGET) ; 964 965 Clean clean : $(1) ; 966} 967 968actions WriteKernelConfig bind SECTION_FILES 969{ 970 target="$(1)" 971 echo "# OpenBeOS Kernel Config File" > "$target" 972 echo "# Automatically generated - do not edit!" >> "$target" 973 count=0 974 for section in "$(SECTION_NAMES)" ; do 975 count=`expr $count + 1` 976 eval section$count="$section" 977 done 978 i=1 979 for type in "$(SECTION_TYPES)" ; do 980 eval type$i="$type" 981 i=`expr $i + 1` 982 done 983 i=1 984 for file in "$(SECTION_FILES)" ; do 985 eval file$i="$file" 986 i=`expr $i + 1` 987 done 988 for i in `seq $count` ; do 989 eval section="\$section$i" 990 eval type="\$type$i" 991 eval file="\$file$i" 992 echo "" >> "$target" 993 echo "["$section"]" >> "$target" 994 echo "type="$type >> "$target" 995 case "$file" in 996 /*) ;; 997 *) file=`pwd`/"$file";; 998 esac 999 echo "file="$file >> "$target" 1000 done 1001} 1002 1003rule BuildKernel 1004{ 1005 # Usage BuildKernel <target> : <config_file> ; 1006 1007 Depends all : $(1) ; 1008 Depends $(1) : $(2) ; 1009 Clean clean : $(1) ; 1010 1011 MakeLocate $(1) : $(LOCATE_TARGET) ; 1012} 1013 1014actions BuildKernel 1015{ 1016 "$(BUILD_CMD)" --strip-debug --strip-binary strip "$(2)" -o "$(1)" ; 1017 echo "" 1018 echo "Kernel linked!" 1019 echo "" 1020} 1021 1022# At present I don't bother moving the final location for 1023# the floppy image as it makes copying it onto a floppy easier if it's 1024# where you did the build. This is easy enough changed. 1025rule KernelFloppyImage 1026{ 1027 # Usage KernelFloppyImage <target> : <kernel> : <bootblock> ; 1028 1029 Depends all : $(1) ; 1030 Depends $(1) : $(2) ; 1031 Clean clean : $(1) ; 1032 1033 BOOT_BLOCK on $(1) = $(3) ; 1034} 1035 1036# This may be a bit verbose, but I think it's useful to show what's 1037# going on, at least in this early stage of development. 1038actions KernelFloppyImage 1039{ 1040 "$(BUILD_CMD)" "$(BOOT_BLOCK)" "$(2)" "$(1)" ; 1041 echo "" 1042 echo "*************************************************" 1043 echo "* Kernel build completed! *" 1044 echo "* Boot image for a 1.44M floppy created *" 1045 echo "*************************************************" 1046 echo "" 1047 echo "Floppy image is $(OBOS_FLOPPY)" 1048 echo "The following command will write it to a floppy on BeOS" 1049 echo " dd if=$(OBOS_FLOPPY) of=/dev/disk/floppy/raw bs=18k" 1050 echo "" 1051} 1052 1053 1054