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