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