1 2rule SetupObjectsDir 3{ 4 # SetupObjectsDir 5 # 6 # Internal rule used to set up the *{LOCATE,SEARCH}*_{TARGET,SOURCE} 7 # variables for the current directory. 8 9 local relPath = [ FDirName $(SUBDIR_TOKENS[2-]) ] ; 10 if $(relPath) = . { 11 relPath = ; 12 } 13 COMMON_PLATFORM_LOCATE_TARGET = 14 [ FDirName $(HAIKU_COMMON_PLATFORM_OBJECT_DIR) $(relPath) ] ; 15 16 local var ; 17 for var in COMMON_ARCH COMMON_DEBUG DEBUG_$(HAIKU_DEBUG_LEVELS) { 18 HOST_$(var)_LOCATE_TARGET 19 = [ FDirName $(HOST_$(var)_OBJECT_DIR) $(relPath) ] ; 20 TARGET_$(var)_LOCATE_TARGET 21 = [ FDirName $(TARGET_$(var)_OBJECT_DIR) $(relPath) ] ; 22 } 23 24 LOCATE_TARGET = $(COMMON_PLATFORM_LOCATE_TARGET) ; 25 LOCATE_SOURCE = $(LOCATE_TARGET) ; 26 SEARCH_SOURCE = $(SUBDIR) $(LOCATE_SOURCE) 27 $(HOST_COMMON_DEBUG_LOCATE_TARGET) # Also add the standard output 28 $(TARGET_COMMON_DEBUG_LOCATE_TARGET) # dirs for generated sources. 29 ; 30} 31 32rule SetupFeatureObjectsDir feature 33{ 34 # SetupFeatureObjectsDir <feature> 35 # 36 # Updates the *{LOCATE,SEARCH}*_{TARGET,SOURCE} variables for the current 37 # directory appending a <feature> to each of them. Note that it resets 38 # the LOCATE_TARGET, LOCATE_SOURCE, SEARCH_SOURCE (!) variables. I.e. it 39 # should be invoked before customizing these variables further (e.g. like 40 # adding additional source directories to SEARCH_SOURCE). 41 42 COMMON_PLATFORM_LOCATE_TARGET 43 = [ FDirName $(COMMON_PLATFORM_LOCATE_TARGET) $(feature) ] ; 44 45 local var ; 46 for var in COMMON_ARCH COMMON_DEBUG DEBUG_$(HAIKU_DEBUG_LEVELS) { 47 HOST_$(var)_LOCATE_TARGET 48 = [ FDirName $(HOST_$(var)_LOCATE_TARGET) $(feature) ] ; 49 TARGET_$(var)_LOCATE_TARGET 50 = [ FDirName $(TARGET_$(var)_LOCATE_TARGET) $(feature) ] ; 51 } 52 53 LOCATE_TARGET = [ FDirName $(LOCATE_TARGET) $(feature) ] ; 54 LOCATE_SOURCE = $(LOCATE_TARGET) ; 55 SEARCH_SOURCE = $(SUBDIR) $(LOCATE_SOURCE) 56 $(HOST_COMMON_DEBUG_LOCATE_TARGET) # Also add the standard output 57 $(TARGET_COMMON_DEBUG_LOCATE_TARGET) # dirs for generated sources. 58 ; 59} 60 61rule SubIncludeGPL 62{ 63 # SubInclude rule that can be used to conditionally include GPL licensed 64 # add-ons 65 if $(INCLUDE_GPL_ADDONS) = 1 { 66 SubInclude $(1) ; 67 } 68} 69 70 71# pragma mark - MakeLocate variants 72 73 74rule MakeLocateCommonPlatform 75{ 76 MakeLocate $(1) : $(COMMON_PLATFORM_LOCATE_TARGET) ; 77} 78 79rule MakeLocatePlatform 80{ 81 local files = $(1) ; 82 local file ; 83 for file in $(files) { 84 if [ on $(file) return $(PLATFORM) ] = host { 85 MakeLocate $(file) : $(HOST_COMMON_ARCH_LOCATE_TARGET) ; 86 } else { 87 MakeLocate $(file) : $(TARGET_COMMON_ARCH_LOCATE_TARGET) ; 88 } 89 } 90} 91 92rule MakeLocateArch 93{ 94 local files = $(1) ; 95 local file ; 96 for file in $(files) { 97 if [ on $(file) return $(PLATFORM) ] = host { 98 MakeLocate $(file) : $(HOST_COMMON_DEBUG_LOCATE_TARGET) ; 99 } else { 100 MakeLocate $(file) : $(TARGET_COMMON_DEBUG_LOCATE_TARGET) ; 101 } 102 } 103} 104 105rule MakeLocateDebug 106{ 107 local files = $(1) ; 108 local file ; 109 for file in $(files) { 110 on $(file) { 111 if $(PLATFORM) = host { 112 MakeLocate $(file) : $(HOST_DEBUG_$(DEBUG)_LOCATE_TARGET) ; 113 } else { 114 MakeLocate $(file) : $(TARGET_DEBUG_$(DEBUG)_LOCATE_TARGET) ; 115 } 116 } 117 } 118} 119 120 121# pragma mark - Deferred SubIncludes 122 123 124# The variable used to collect the deferred SubIncludes. 125HAIKU_DEFERRED_SUB_INCLUDES = ; 126 127rule DeferredSubInclude params : jamfile : scope 128{ 129 # DeferredSubInclude <subdir tokens> [ : <jamfile name> [ : <scope> ] ] ; 130 # 131 # Takes the same directory tokens parameter as SubInclude plus an optional 132 # alternative Jamfile name. The the subdirectory referred to by 133 # <subdir tokens> will be included when ExecuteDeferredSubIncludes is 134 # invoked, i.e. at the end of the root Jamfile. The <jamfile name> parameter 135 # specifies the name of the Jamfile to include. By default it is "Jamfile". 136 # The <scope> parameter can be "global" (default) or "local", specifying 137 # whether the alternative Jamfile name shall also be used for subdirectories. 138 139 HAIKU_DEFERRED_SUB_INCLUDES += "/" $(params) ; 140 if $(jamfile) { 141 SetConfigVar JAMFILE : $(params) : $(jamfile) : $(scope) ; 142 } 143} 144 145rule ExecuteDeferredSubIncludes 146{ 147 # ExecuteDeferredSubIncludes ; 148 # 149 # Performs the deferred SubIncludes scheduled by DeferredSubInclude. 150 151 local tokensList = $(HAIKU_DEFERRED_SUB_INCLUDES) ; 152 while $(tokensList) { 153 # chop off leading "/" 154 tokensList = $(tokensList[2-]) ; 155 156 # get the tokens for the next include 157 local tokens ; 158 while $(tokensList) && $(tokensList[1]) != "/" { 159 tokens += $(tokensList[1]) ; 160 tokensList = $(tokensList[2-]) ; 161 } 162 163 # perform the include 164 if $(tokens) { 165 SubInclude $(tokens) ; 166 } 167 } 168} 169 170rule HaikuSubInclude tokens 171{ 172 # HaikuSubInclude <tokens> ; 173 # 174 # Current subdir relative SubInclude. 175 # <tokens> - subdir tokens specifying the subdirectory to be include 176 # (relative to the current subdir) 177 178 if $(tokens) { 179 SubInclude HAIKU_TOP $(SUBDIR_TOKENS) $(tokens) ; 180 } 181} 182 183 184# pragma mark - Unique IDs/targets 185 186 187# private to NextID; incremented with each NextID invocation 188HAIKU_NEXT_ID = 0 ; 189 190rule NextID 191{ 192 # NextID ; 193 194 local result = $(HAIKU_NEXT_ID:J=) ; 195 HAIKU_NEXT_ID = [ AddNumAbs $(HAIKU_NEXT_ID) : 1 ] ; 196 return $(result) ; 197} 198 199rule NewUniqueTarget basename 200{ 201 # NewUniqueTarget [ basename ] ; 202 203 local id = [ NextID ] ; 204 return $(basename[1]:E=_target:G=unique!target)_$(id) ; 205} 206 207 208# pragma mark - RunCommandLine 209 210 211rule RunCommandLine commandLine 212{ 213 # RunCommandLine <commandLine> 214 # 215 # Creates a pseudo target that, when made by jam, causes the supplied shell 216 # command line to be executed. Elements of <commandLine> with the prefix ":" 217 # are replaced by the rule. After stripping the prefix such a string specifies 218 # a build system target and the finally executed command line will contain 219 # a path to the target instead. 220 # The pseudo target will depend on all targets thus identified. Each 221 # invocation of this rule creates a different pseudo target, which is 222 # returned to the caller. 223 224 # collect the targets in the command line and replace them by $targetX* 225 # variables 226 local substitutedCommandLine ; 227 local targets ; 228 229 local targetVarName = target ; 230 local i ; 231 for i in $(commandLine) { 232 # targets are marked by the ":" prefix 233 local target = [ Match ^:(.*) : $(i) ] ; 234 if $(target) { 235 targets += $(target) ; 236 targetVarName = $(targetVarName)X ; 237 i = "$"$(targetVarName) ; 238 } 239 240 substitutedCommandLine += $(i) ; 241 } 242 243 # define the "run" target 244 local run = [ NewUniqueTarget run ] ; 245 COMMAND_LINE on $(run) = $(substitutedCommandLine) ; 246 NotFile $(run) ; 247 Always $(run) ; 248 Depends $(run) : $(targets) ; 249 RunCommandLine1 $(run) : $(targets) ; 250 251 return $(run) ; 252} 253 254actions RunCommandLine1 { 255 target=target; 256 for t in $(2) ; do 257 target=${target}X 258 eval "${target}=${t}" 259 done 260 $(HOST_ADD_BUILD_COMPATIBILITY_LIB_DIR) 261 "$(COMMAND_LINE)" 262} 263 264 265#pragma mark - DefineBuildProfile 266 267 268rule DefineBuildProfile name : type : path { 269 # DefineBuildProfile <name> : <type> [ : <path> ] 270 # 271 # Makes a build profile known. Build profiles can be used to define 272 # different sets of settings for Haiku images/installations. For each 273 # profile the default actions "build", "update", and "mount" (the latter 274 # only for disks or image types) will be available (i.e. can be specified 275 # as second parameter on the jam command line). They will build an image 276 # or installation, update only given targets, respectively just mount the 277 # image or disk using the bfs_shell. 278 # 279 # <name> - The name of the build profile. 280 # <type> - The type of the build profile. Must be one of "image" (plain 281 # disk image), "vmware-image" (VMware disk image), "disk" 282 # (actual partition or hard disk device), "cd-image" (ISO CD 283 # image), "install" (installation in a directory), or "custom" 284 # (user-defined). 285 # <path> - The path associated with the profile. Depending on the profile 286 # type, this is the path to the disk image/VMware image, hard 287 # disk/partition device, or the installation directory. If the 288 # parameter is omitted, the value of the HAIKU[_VMWARE]_IMAGE_NAME, 289 # HAIKU_IMAGE_DIR, respectively HAIKU_INSTALL_DIR or their default 290 # values will be used instead. 291 292 if [ on $(name) return $(HAIKU_BUILD_PROFILE_SPECIFIED) ] { 293 Exit "ERROR: Build profile \"$(name)\" defined twice!" ; 294 } 295 HAIKU_BUILD_PROFILE_SPECIFIED on $(name) = 1 ; 296 297 if ! $(HAIKU_BUILD_PROFILE) || $(HAIKU_BUILD_PROFILE) != $(name) { 298 return ; 299 } 300 301 HAIKU_BUILD_PROFILE_DEFINED = 1 ; 302 303 # split path into directory path and name 304 local targetDir = $(path:D) ; 305 local targetName = $(path:BS) ; 306 307 # Jam's path splitting produces an empty string, if a component doesn't 308 # exist. That's a little unhandy for checks. 309 if $(targetDir) = "" { 310 targetDir = ; 311 } 312 if $(targetName) = "" { 313 targetName = ; 314 } 315 316 targetDir ?= $(HAIKU_IMAGE_DIR) ; 317 targetDir ?= $(HAIKU_DEFAULT_IMAGE_DIR) ; 318 319 # "disk" is "image" with HAIKU_DONT_CLEAR_IMAGE 320 if $(type) = "disk" { 321 type = "image" ; 322 HAIKU_DONT_CLEAR_IMAGE = 1 ; 323 } 324 325 local buildTarget ; 326 local startOffset ; 327 328 switch $(type) { 329 case "cd-image" : { 330 targetName ?= $(HAIKU_CD_NAME) ; 331 targetName ?= $(HAIKU_DEFAULT_CD_NAME) ; 332 HAIKU_CD_DIR = $(targetDir) ; 333 HAIKU_CD_NAME = $(targetName) ; 334 buildTarget = haiku-cd ; 335 } 336 337 case "image" : { 338 targetName ?= $(HAIKU_IMAGE_NAME) ; 339 targetName ?= $(HAIKU_DEFAULT_IMAGE_NAME) ; 340 HAIKU_IMAGE_DIR = $(targetDir) ; 341 HAIKU_IMAGE_NAME = $(targetName) ; 342 buildTarget = haiku-image ; 343 } 344 345 case "vmware-image" : { 346 targetName ?= $(HAIKU_VMWARE_IMAGE_NAME) ; 347 targetName ?= $(HAIKU_DEFAULT_VMWARE_IMAGE_NAME) ; 348 HAIKU_IMAGE_DIR = $(targetDir) ; 349 HAIKU_VMWARE_IMAGE_NAME = $(targetName) ; 350 buildTarget = haiku-vmware-image ; 351 startOffset = --start-offset 65536 ; 352 } 353 354 case "install" : { 355 path ?= $(HAIKU_INSTALL_DIR) ; 356 path ?= $(HAIKU_DEFAULT_INSTALL_DIR) ; 357 HAIKU_INSTALL_DIR = $(path) ; 358 buildTarget = install-haiku ; 359 } 360 361 case "custom" : { 362 # user-defined -- don't do anything 363 return 1 ; 364 } 365 366 case * : { 367 Exit "Unsupported build profile type: " $(type) ; 368 } 369 } 370 371 switch $(HAIKU_BUILD_PROFILE_ACTION) { 372 case "build" : { 373 JAM_TARGETS = $(buildTarget) ; 374 } 375 376 case "update" : { 377 JAM_TARGETS = $(buildTarget) ; 378 SetUpdateHaikuImageOnly 1 ; 379 HAIKU_INCLUDE_IN_IMAGE on $(HAIKU_BUILD_PROFILE_PARAMETERS) = 1 ; 380 } 381 382 case "update-all" : { 383 JAM_TARGETS = $(buildTarget) ; 384 SetUpdateHaikuImageOnly 1 ; 385 HAIKU_INCLUDE_IN_IMAGE = 1 ; 386 } 387 388 case "mount" : { 389 if $(type) in "install" "cd-image" { 390 Exit "Build action \"mount\" not supported for profile type" 391 "\"$(type)\"." ; 392 } 393 394 local commandLine = :<build>bfs_shell $(startOffset) 395 \"$(targetName:D=$(targetDir))\" ; 396 JAM_TARGETS = [ RunCommandLine $(commandLine) ] ; 397 } 398 } 399 400 return 1 ; 401} 402