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