files.jam   [plain text]


# Copyright (c) 1999-2003 Apple Computer, Inc.
# All rights reserved.

# Define reasonable base locations, to be overridden by default

# Build intermediates go into TEMP_ROOT which defaults to
# build/intermediates in current directory, or OBJROOT if defined
TEMP_ROOT default = $(OBJROOT) ;

# Builds go into the BUILD_ROOT which defaults to
# build/products in current directory, or SYMROOT if defined
BUILD_ROOT default = $(SYMROOT) ;

# Installation root defaults to root, or DSTROOT if defined
INSTALL_ROOT default = $(DSTROOT) ;

# Set initial values for installation information and framework version
_BUILD_PHASING default = YES ;
export INSTALL_OWNER default = $(USER) ;
export INSTALL_GROUP default = $(GROUP) ;
export FRAMEWORK_VERSION default = "A" ;
REMOVE_CVS_FROM_RESOURCES default = YES ;
REMOVE_SVN_FROM_RESOURCES default = YES ;
COPY_PHASE_STRIP default = NO ;
PREBINDING default = YES ;
SET_DIR_MODE_OWNER_GROUP default = YES ;
SET_FILE_MODE_OWNER_GROUP default = NO ;

# Set initial optimization level, debug, and profile settings
export OPTIMIZATION_LEVEL default = 0 ;
export DEBUGGING_SYMBOLS default = YES ;
export PROFILING_CODE default = NO ;

# Default linker warnings
WARNING_LDFLAGS default = -Wl,-no_arch_warnings ;

# Default settings for Java builds
JAVA_ARCHIVE_CLASSES default = YES ;
JAVA_ARCHIVE_TYPE default = JAR ;
JAVA_APP_STUB default = /System/Library/Frameworks/JavaVM.framework/Resources/MacOS/JavaApplicationStub ;
JAVA_JAR_FLAGS default = cv ;
JAVA_SOURCE_SUBDIR default = . ;
JAVA_FRAMEWORK_RESOURCES_DIRS default = Resources ;
export JAVA_FRAMEWORK_JARS default = ;
JAVA_USE_DEPENDENCIES default = YES ;
JAVA_FORCE_FILE_LIST default = NO ;
JAVA_ZIP_FLAGS default = -urg ;

JAVA_COMPILER_DEBUGGING_SYMBOLS default = YES ;
JAVA_COMPILER_DISABLE_WARNINGS default = NO ;
JAVA_COMPILER_DEPRECATED_WARNINGS default = NO ;

# These default flags probably shouldn't be overridden by users.
JAVAC_DEFAULT_FLAGS default = -J-Xms64m -J-XX:NewSize=4M -J-Dfile.encoding=UTF8 ;
JIKES_DEFAULT_FLAGS default = +E +OLDCSO ;

# Default variants and flags
BUILD_VARIANTS default = normal ;
_BUILD_PHASES = ;

# BeginProduct <product>
#
# Initializes the directory and file list variables
#
# Variable references:
# BUILD_ROOT			Base directory for builds
# TARGET_NAME			Name of the target that builds this product
# PRODUCT_NAME			Name of the product that's built
# TEMP_ROOT			Base directory for intermediates
# BASE_PROJECT_HEADER_DIR	Base directory for project headers
# HEADER_SUBDIRECTORY		Path prefix in header #include lines
# INSTALL_ROOT			Base directory for installations
# INSTALL_PATH			Subdirectory where product is installed
# PUBLIC_HEADER_DIR		Location for public headers
#
# Variables set:
# HEADER_SUBDIRECTORY		Base product name
# BUILD_COMPONENTS		List may include: headers, build, source
# OPTIMIZATION_CFLAGS		Optimization flags for C compiles
# OTHER_CPLUSPLUSFLAGS		C++ flags default to C values
# WARNING_CPLUSPLUSFLAGS
# INCLUDED_ARCHS		Architectures intended for this build
# NATIVE_ARCH			Architecture of the build machine
# ARCHS				Architectures used for this build
# ARCH_FLAGS			Architecture flags used for most tools
# SOURCE_DIR			
# BUILD_DIR			Target-specific directory for builds
# TEMP_DIR			For target-specific intermediates
# PROJECT_HEADER_DIR		Project header file directory in $(TEMP_DIR)
# OBJECT_FILE_DIR		Object file directory in $(TEMP_DIR)
# CLASS_FILE_DIR		Class file directory in $(TEMP_DIR)
# FILE_LIST			Base name for lists of files generated
# DERIVED_FILE_DIR		Derived source directory in $(TEMP_DIR)
# INSTALL_DIR			Directory in $(INSTALL_ROOT) for installations
# HEADER_SEARCH_PATHS		Project header directories prepended
# FRAMEWORK_SEARCH_PATHS	Product build root appended
# DERIVED_FILES			Initialized empty
# OBJECT_FILES			Initialized empty
# LINKED_FILES			Initialized empty
# PRODUCT_FILES			Initialized empty
# PRECOMP_TRUSTFILE		List of trusted precompiled headers
#
rule BeginProduct
{
    # target representing the build must be a nonfile pseudotarget
    NOTFILE $(1) ;

    # define the header subdirectory early since we'll use it to
    # compute the project header directory
    HEADER_SUBDIRECTORY = $(1:B) ;

    # the following sequence of tests sets up CC, CPLUSPLUS, LD, and LDPLUSPLUS appropriately,
    # depending on whether we're using GCC 2.95.2, 3.1, 3.3, 3.5 or 4.0 (either explicitly or implicitly)

    # a hack to detect attempt to use GCC 3, and to set the 'GCC_VERSION' build setting accordingly
    if $(USE_GCC3) = YES  ||  $(USE_GCC2) = NO  ||  $(CC) = "/usr/bin/gcc3" {
        # use either the default gcc version if available or default to 3.1
        if $(_DEFAULT_GCC_VERSION) = 3.1 || $(_DEFAULT_GCC_VERSION) = 3.3 || $(_DEFAULT_GCC_VERSION) = 3.5 || $(_DEFAULT_GCC_VERSION) = 4.0 {
            GCC_VERSION default = $(_DEFAULT_GCC_VERSION) ;
        }
        else {
            GCC_VERSION default = 3.1 ;
        }
    }
    else if $(USE_GCC2) = YES  ||  $(USE_GCC3) = NO  ||  $(CC) = "/usr/bin/gcc2" {
        GCC_VERSION default = 2.x ;
    }
    else {
        if $(_DEFAULT_GCC_VERSION) = 3.1 || $(_DEFAULT_GCC_VERSION) = 3.3 || $(_DEFAULT_GCC_VERSION) = 3.5 || $(_DEFAULT_GCC_VERSION) = 4.0 {
            GCC_VERSION default = $(_DEFAULT_GCC_VERSION) ;
        }
        else if $(_DEFAULT_GCC_VERSION) = 2.95.2 {
            GCC_VERSION default = 2.x ;
        }
        else {
            GCC_VERSION default = unknown ;
        }
    }

    # set up CC, CPLUSPLUS, LD, and LDPLUSPLUS appropriately (this logic is temporary, and is
    # expected to be phased out once we have per-build-phase compiler choices)
    if $(GCC_VERSION) = 4.0 {
        CC default = "$(DEVELOPER_BIN_DIR)/gcc-4.0" ;
        CPLUSPLUS default = "$(DEVELOPER_BIN_DIR)/g++-4.0" ;
    }
    else if $(GCC_VERSION) = 3.5 {
        CC default = /usr/bin/gcc-3.5 ;
        CPLUSPLUS default = /usr/bin/g++-3.5 ;
    }
    else if $(GCC_VERSION) = 3.3 {
        CC default = /usr/bin/gcc-3.3 ;
        CPLUSPLUS default = /usr/bin/g++-3.3 ;
    }
    else if $(GCC_VERSION) = 3.1 {
        CC default = /usr/bin/gcc3 ;
        CPLUSPLUS default = /usr/bin/g++3 ;
    }
    else if $(GCC_VERSION) = 2.x {
        CC default = /usr/bin/gcc2 ;
        CPLUSPLUS default = /usr/bin/g++2 ;
    }
    else {
        CC default = "$(DEVELOPER_BIN_DIR)/cc" ;
        CPLUSPLUS default = "$(DEVELOPER_BIN_DIR)/c++" ;
    }
    LD default = $(CC) ;
    LDPLUSPLUS default = $(CPLUSPLUS) ;
    _LD_FOR_LINKING = $(LD) ;   # this might get reset to $(LDPLUSPLUS) in the CompileCplusplus rule

    # Set reasonable optimization flags for installs if not already set
    OPTIMIZATION_CFLAGS default = -Os ;
    # precompiled header, C++, Assembly, and Fortran options match C options by default
    OTHER_PRECOMP_CPLUSPLUSFLAGS default = $(OTHER_PRECOMP_CFLAGS) ;
    OTHER_CPLUSPLUSFLAGS default = $(OTHER_CFLAGS) ;
    WARNING_CPLUSPLUSFLAGS default = $(WARNING_CFLAGS) ;
    OTHER_ASFLAGS default = $(OTHER_CFLAGS) ;
    WARNING_ASFLAGS default = $(WARNING_CFLAGS) ;
    OTHER_FFLAGS default = $(OTHER_CFLAGS) ;
    WARNING_FFLAGS default = $(WARNING_CFLAGS) ;
    # Variant flags and suffixes
    for VARIANT in $(BUILD_VARIANTS) {
        if $(VARIANT) = profile {
            OTHER_CFLAGS_$(VARIANT) default = $(OTHER_CFLAGS) -pg ;
            OTHER_ASFLAGS_$(VARIANT) default = $(OTHER_CFLAGS) -pg ;
            OTHER_CPLUSPLUSFLAGS_$(VARIANT) default = $(OTHER_CPLUSPLUSFLAGS) -pg ;
            OTHER_LDFLAGS_$(VARIANT) default = $(OTHER_LDFLAGS) -pg ;
        }
        else {
            OTHER_CFLAGS_$(VARIANT) default = $(OTHER_CFLAGS) ;
            OTHER_ASFLAGS_$(VARIANT) default = $(OTHER_CFLAGS) ;
            OTHER_CPLUSPLUSFLAGS_$(VARIANT) default = $(OTHER_CPLUSPLUSFLAGS) ;
            OTHER_LDFLAGS_$(VARIANT) default = $(OTHER_LDFLAGS) ;
        }
        if $(VARIANT) = normal {
            VARIANT_SUFFIX_$(VARIANT) = "" ;
        }
        else {
            VARIANT_SUFFIX_$(VARIANT) = _$(VARIANT) ;
        }
    }
    # Set up architecture options for product
    INCLUDED_ARCHS default = $(SUPPORTED_ARCHITECTURES) ;
    SUPPORTED_ARCHITECTURE_FLAGS = ;
    ARCHS = ;
    for SUPPORTED_ARCHITECTURE in $(SUPPORTED_ARCHITECTURES) {
        if $($(SUPPORTED_ARCHITECTURE)) = YES
         && ( $(SUPPORTED_ARCHITECTURE) in $(INCLUDED_ARCHS) )
         && ( $(SUPPORTED_ARCHITECTURE) in $(VALID_ARCHS) ) {
            SUPPORTED_ARCHITECTURE_FLAGS += -arch $(SUPPORTED_ARCHITECTURE) ;
            ARCHS += $(SUPPORTED_ARCHITECTURE) ;
        }
    }
    # if somehow no architecture was found, then use the native architecture
    if ! $(ARCHS) {
        $(NATIVE_ARCH) = YES ;
        RC_$(NATIVE_ARCH) = YES ;
        SUPPORTED_ARCHITECTURE_FLAGS += -arch $(NATIVE_ARCH) ;
        ARCHS += $(NATIVE_ARCH) ;
    }

    ARCH_FLAGS default = $(SUPPORTED_ARCHITECTURE_FLAGS) ;
    # Initialize the directory variables
    # SOURCE_DIR is the location of installed sources
    SOURCE_DIR default = $(INSTALL_ROOT) ;
    BUILD_DIR default = $(BUILD_ROOT) ;
    # create base build dir
    Mkdir $(BUILD_DIR) ;
    ProductFile $(BUILD_DIR) ;
    # create active build dir
    if $(TARGET_BUILD_DIR) && ($(TARGET_BUILD_DIR) != $(BUILD_DIR)) {
        Mkdir $(TARGET_BUILD_DIR) ;
    }
    # asides
    if $(INSTALLED_PRODUCT_ASIDES) = YES && $(DEPLOYMENT_LOCATION) = YES {
        SEPARATE_STRIP = YES ;
        ASIDE_DIR default = $(BUILD_ROOT) ;
        Mkdir $(ASIDE_DIR) ;
        ProductFile $(ASIDE_DIR) ;
    }
    # define other important locations
    TEMP_DIR default = $(TEMP_ROOT)$(/)$(PROJECT_NAME).build$(/)$(TARGET_NAME).build ;
    OBJECT_FILE_DIR default = $(TEMP_DIR)$(/)Objects ;
    export CLASS_FILE_DIR default = $(TEMP_DIR)$(/)JavaClasses ;
    for VARIANT in $(BUILD_VARIANTS) {
        OBJECT_FILE_DIR_$(VARIANT) default = $(OBJECT_FILE_DIR)-$(VARIANT) ;
        FILE_LIST_$(VARIANT) default = $(OBJECT_FILE_DIR_$(VARIANT))$(/)LinkFileList ;
        # initialize file lists
        OBJECT_FILES_$(VARIANT) = ;
        LINKED_FILES_$(VARIANT) = ;
    }
    if $(JAVA_ARCHIVE_CLASSES) != YES && ( $(PRODUCT_TYPE) = Tool || $(PRODUCT_TYPE) = Library ) {
        export PRODUCT_CLASS_FILE_DIR default = $(TARGET_BUILD_DIR)$(/)$(PRODUCT_NAME) ;
    }
    DERIVED_FILE_DIR default = $(TEMP_DIR)$(/)DerivedSources ;
    if $(INSTALL_PATH) {
        INSTALL_DIR default = $(INSTALL_ROOT)$(/)$(INSTALL_PATH) ;
    }
    else {
        INSTALL_DIR default = $(INSTALL_ROOT) ;
    }
    # Initialize the search paths
    if $(TARGET_BUILD_DIR) != $(BUILT_PRODUCTS_DIR) {
        HEADER_SEARCH_PATHS = $(TARGET_BUILD_DIR)$(/)include $(BUILT_PRODUCTS_DIR)$(/)include $(HEADER_SEARCH_PATHS) ;
    }
    else {
        HEADER_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR)$(/)include $(HEADER_SEARCH_PATHS) ;
    }
    FRAMEWORK_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR) $(FRAMEWORK_SEARCH_PATHS) ;
    REZ_SEARCH_PATHS default = $(BUILT_PRODUCTS_DIR) $(HEADER_SEARCH_PATHS) ;
    LIBRARY_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR) $(LIBRARY_SEARCH_PATHS) ;
    if $(DEPLOYMENT_LOCATION) = YES && $(BUILT_PRODUCTS_DIR) {
        HEADER_SEARCH_PATHS = $(BUILT_PRODUCTS_DIR)$(/)include $(HEADER_SEARCH_PATHS) ;
    }
    # Initialize the file lists
    DERIVED_FILES = ;
    DERIVED_FILE_SOURCES = ;
    PRODUCT_FILES = ;
    PRECOMP_TRUSTFILE default = $(TEMP_DIR)$(/)TrustedPrecomps.txt ;
    # Make symlink to product in products dir,
    # and also set product mode and ownership
    # unless there is no nonempty product name.
    if $(DEPLOYMENT_LOCATION) = YES {
        if $(WRAPPER)
         && $(PRODUCT_TYPE) != Tool
         && $(PRODUCT_TYPE) != Library {
            # Use WRAPPER when defined for bundle product
            _INSTALLED_PRODUCT = $(TARGET_BUILD_DIR)$(/)$(WRAPPER) ;
            _PRODUCT_REFERENCE default = $(BUILT_PRODUCTS_DIR:G=ProductRef)$(/)$(WRAPPER) ;
            #!!!:cmolick:20020517:this may be bad for non-deployment location
            if $(DEPLOYMENT_POSTPROCESSING) = YES {
                SetModeOwnerAndGroup $(_INSTALLED_PRODUCT:G=ModeOwnerGroup) : $(_INSTALLED_PRODUCT) ;
            }
            SymLink $(_PRODUCT_REFERENCE) : $(_INSTALLED_PRODUCT) ;
            DEPENDS $(_PRODUCT_REFERENCE) : $(BUILT_PRODUCTS_DIR) ;
            DEPENDS $(1) : $(_PRODUCT_REFERENCE) ;
        }
        else {
            if $(1:G=) {
                # Use nonempty, ungristed primary target for tool or library product
                _INSTALLED_PRODUCT = $(TARGET_BUILD_DIR)$(/)$(1:G=) ;
                _PRODUCT_REFERENCE default = $(BUILT_PRODUCTS_DIR:G=ProductRef)$(/)$(1:G=) ;
                SymLink $(_PRODUCT_REFERENCE) : $(_INSTALLED_PRODUCT) ;
                DEPENDS $(_PRODUCT_REFERENCE) : $(BUILT_PRODUCTS_DIR) ;
                DEPENDS $(1) : $(_PRODUCT_REFERENCE) ;
            }
        }
    }
    # Set default locations for headers and resources of simple (tool or library) products
    if $(PRODUCT_TYPE) = Tool || $(PRODUCT_TYPE) = Library {
        PUBLIC_HEADER_DIR default = $(TARGET_BUILD_DIR) ;
        PRIVATE_HEADER_DIR default = $(TARGET_BUILD_DIR) ;
        RESOURCE_DIR default = $(TARGET_BUILD_DIR) ;
    }
    # Run the hack script to build debug and profile variants, if appropriate.
    if $(INTERNAL_BUILD_VARIANTS)
     && ( $(RC_JASPER) || $(INTERNAL_BUILD_VARIANTS_ONLY_IN_JASPER) != YES )
     && ( $(ACTION) = build || $(ACTION) = install ) {
        # build variants list should be used only by this call in this case
        _INTERNAL_BUILD_VARIANTS = $(INTERNAL_BUILD_VARIANTS) ;
        INTERNAL_BUILD_VARIANTS = ;
        INTERNAL_BUILD_VARIANTS on $(1) = $(_INTERNAL_BUILD_VARIANTS) ;
        RunVariantHackScript $(1) ;
    }
}

# EndProduct <product>
#
# Creates BUILD_DIR, OBJECT_FILE_DIR, CLASS_FILE_DIR, DERIVED_FILE_DIR,
# and the PROJECT_HEADER_DIR if necessary, then sets up the build action.
rule EndProduct
{
    # Create required directories.  This is done here to allow
    # variables to be overridden before this rule is evaluated.
    for VARIANT in $(BUILD_VARIANTS) {
        Mkdir $(OBJECT_FILE_DIR_$(VARIANT)) ;
        PRODUCT_FILES += $(OBJECT_FILE_DIR_$(VARIANT)) ;
        DEPENDS $(1) : $(OBJECT_FILE_DIR_$(VARIANT)) ;
    }
    if $(DEPLOYMENT_LOCATION) {
        Mkdir $(BUILT_PRODUCTS_DIR) ;
        PRODUCT_FILES += $(BUILT_PRODUCTS_DIR) ;
        DEPENDS $(1) : $(BUILT_PRODUCTS_DIR) ;
    }
    Mkdir $(CLASS_FILE_DIR) ;
    PRODUCT_FILES += $(CLASS_FILE_DIR) ;
    DEPENDS $(1) : $(CLASS_FILE_DIR) ;
    Mkdir $(DERIVED_FILE_DIR) ;
    PRODUCT_FILES += $(DERIVED_FILE_DIR) ;
    DEPENDS $(1) : $(DERIVED_FILE_DIR) ;
    # Set up post-phase processing
    if $(POST_PHASE_PRODUCTS) {
        DEPENDS $(1) : $(POST_PHASE_PRODUCTS) ;
        DEPENDS $(POST_PHASE_PRODUCTS) : $(_BUILD_PHASES) ;
    }
    # Alternative catch-all mechanism to set mode and ownership of files
    # that for some reason require this post build processing.
    # !!!:cmolick:20021025 skip this if action is installhdrs since
    #  it is not relevant in that case and might even be impossible
    if ( $(DEPLOYMENT_POSTPROCESSING) = YES && $(_INSTALLED_PRODUCT) ) {
        DEPENDS $(_INSTALLED_PRODUCT:G=ModeOwnerGroup) : $(PRODUCT_FILES) ;
    }
    if $(DEPLOYMENT_POSTPROCESSING) = YES && $(ACTION) != installhdrs {
    PREVIOUS_PERMISSIONS_TARGET = ;
    for ALTERNATE_PERMISSIONS_FILE in $(ALTERNATE_PERMISSIONS_FILES) {
        ALTERNATE_PERMISSIONS_FILE_PATH = $(INSTALL_DIR)$(/)$(ALTERNATE_PERMISSIONS_FILE) ;
        ALTERNATE_PERMISSIONS_TARGET = $(ALTERNATE_PERMISSIONS_FILE:G=AlternatePermissions) ;
        if $(PREVIOUS_PERMISSIONS_TARGET) {
            DEPENDS $(ALTERNATE_PERMISSIONS_TARGET) : $(PREVIOUS_PERMISSIONS_TARGET) ;
        }
        else {
            if ( $(DEPLOYMENT_POSTPROCESSING) = YES && $(_INSTALLED_PRODUCT) ) {
                DEPENDS $(ALTERNATE_PERMISSIONS_TARGET) : $(_INSTALLED_PRODUCT:G=ModeOwnerGroup) ;
            }
        }
        NOTFILE $(ALTERNATE_PERMISSIONS_TARGET) ;
        DEPENDS $(1) : $(ALTERNATE_PERMISSIONS_TARGET) ;
        DEPENDS $(ALTERNATE_PERMISSIONS_TARGET) : $(_BUILD_PHASES) ;
        if $(ALTERNATE_MODE) {
            INSTALL_MODE_FLAG on $(ALTERNATE_PERMISSIONS_TARGET) = $(ALTERNATE_MODE) ;
        }
        if $(ALTERNATE_OWNER) {
            INSTALL_OWNER on $(ALTERNATE_PERMISSIONS_TARGET) = $(ALTERNATE_OWNER) ;
        }
        if $(ALTERNATE_GROUP) {
            INSTALL_GROUP on $(ALTERNATE_PERMISSIONS_TARGET) = $(ALTERNATE_GROUP) ;
        }
        SetModeOwnerAndGroup $(ALTERNATE_PERMISSIONS_TARGET) : $(ALTERNATE_PERMISSIONS_FILE_PATH) ;
        PREVIOUS_PERMISSIONS_TARGET = $(ALTERNATE_PERMISSIONS_TARGET) ;
    }
    }
    # Define actions for this target
    Actions $(1) ;
}

# BeginWrappedProduct <product>
#
# Sets additional variables required for wrapped products,
# primarily to assign locations within the product wrapper.
# WRAPPER			Local convenience variable
# WRAPPER_SUFFIX		Based on WRAPPER_EXTENSION by default
# RESOURCE_DIR			Base bundle resources location
# APPLESCRIPTS_DIR		Compiled AppleScript files folder
# [PUBLIC|PRIVATE]_HEADER_[DIR|LINK|LINK_PATH] Header folders
# CURRENT_VERSION_[DIR|LINK|LINK_PATH]
# HEADERDOC_DIR			Headerdoc output folder
# PRODUCT_CLASS_FILE_DIR	Defined if JAVA_ARCHIVE_CLASSES	is set
# 
rule BeginWrappedProduct
{
    # define wrapper using appropriate extension and suffix
    if $(WRAPPER_EXTENSION) {
        WRAPPER_SUFFIX = .$(WRAPPER_EXTENSION) ;
    }
    if $(WRAPPER_SUFFIX) {
        WRAPPER = $(1:G=:S=$(WRAPPER_SUFFIX)) ;
    }
    else {
        WRAPPER = $(1:G=) ;
    }
    # set up the basic product variables
    BeginProduct $(1) ;
    # define and create wrapper and make primary nonfile target depend on it
    LOCATE on $(WRAPPER) = $(TARGET_BUILD_DIR) ;
    Mkdir $(WRAPPER) ;
    PRODUCT_FILES += $(WRAPPER) ;
    DEPENDS $(1) : $(WRAPPER) ;
    if $(PRODUCT_TYPE) = Application {
        # Application wrappers
        if $(PURE_JAVA) = YES {
            RESOURCE_DIR default = $(WRAPPER) ;
        }
        else {
            RESOURCE_DIR default = $(WRAPPER)$(/)Contents$(/)Resources ;
        }
        LOCATE on $(RESOURCE_DIR) = $(TARGET_BUILD_DIR) ;
        RESOURCE_LINK = "" ;
        APPLESCRIPTS_DIR default = $(RESOURCE_DIR)$(/)Scripts ;
        LOCATE on $(APPLESCRIPTS_DIR) = $(TARGET_BUILD_DIR) ;
        PUBLIC_HEADER_DIR default = $(WRAPPER)$(/)"Contents"$(/)Headers ;
        LOCATE on $(PUBLIC_HEADER_DIR) = $(TARGET_BUILD_DIR) ;
        PUBLIC_HEADER_LINK default = "" ;
        PRIVATE_HEADER_DIR default = $(WRAPPER)$(/)"Contents"$(/)PrivateHeaders ;
        LOCATE on $(PRIVATE_HEADER_DIR) = $(TARGET_BUILD_DIR) ;
        PRIVATE_HEADER_LINK default = "" ;
        CURRENT_VERSION_DIR default = "" ;
        CURRENT_VERSION_LINK default = "" ;
    } # application wrappers
    else if $(PRODUCT_TYPE) = Framework {
        # Framework wrappers
        RESOURCE_DIR default = $(WRAPPER)$(/)Versions$(/)$(FRAMEWORK_VERSION)$(/)Resources ;
        LOCATE on $(RESOURCE_DIR) = $(TARGET_BUILD_DIR) ;
        RESOURCE_LINK default = $(WRAPPER)$(/)Resources ;
        LOCATE on $(RESOURCE_LINK) = $(TARGET_BUILD_DIR) ;
        RESOURCE_LINK_PATH default = Versions$(/)Current$(/)Resources ;
        APPLESCRIPTS_DIR default = $(RESOURCE_DIR)$(/)Scripts ;
        LOCATE on $(APPLESCRIPTS_DIR) = $(TARGET_BUILD_DIR) ;
        HAS_PUBLIC_HEADERS = "NO" ;
        PUBLIC_HEADER_DIR default = $(WRAPPER)$(/)Versions$(/)$(FRAMEWORK_VERSION)$(/)Headers ;
        LOCATE on $(PUBLIC_HEADER_DIR) = $(TARGET_BUILD_DIR) ;
        PUBLIC_HEADER_LINK default = $(WRAPPER)$(/)Headers ;
        LOCATE on $(PUBLIC_HEADER_LINK) = $(TARGET_BUILD_DIR) ;
        PUBLIC_HEADER_LINK_PATH default = Versions$(/)Current$(/)Headers ;
        PRIVATE_HEADER_DIR default = $(WRAPPER)$(/)Versions$(/)$(FRAMEWORK_VERSION)$(/)PrivateHeaders ;
        LOCATE on $(PRIVATE_HEADER_DIR) = $(TARGET_BUILD_DIR) ;
        PRIVATE_HEADER_LINK default = $(WRAPPER)$(/)PrivateHeaders ;
        LOCATE on $(PRIVATE_HEADER_LINK) = $(TARGET_BUILD_DIR) ;
        PRIVATE_HEADER_LINK_PATH default = Versions$(/)Current$(/)PrivateHeaders ;
        CURRENT_VERSION_DIR default = $(WRAPPER:G=)$(/)Versions$(/)$(FRAMEWORK_VERSION) ;
        LOCATE on $(CURRENT_VERSION_DIR) = $(TARGET_BUILD_DIR) ;
        CURRENT_VERSION_LINK default = $(WRAPPER:G=)$(/)Versions$(/)Current ;
        LOCATE on $(CURRENT_VERSION_LINK) = $(TARGET_BUILD_DIR) ;
        CURRENT_VERSION_LINK_PATH default = Versions$(/)Current ;
        if $(ASIDE_DIR) {
            ASIDE_CURRENT_VERSION_DIR default = $(WRAPPER:G=aside)$(/)Versions$(/)$(FRAMEWORK_VERSION) ;
            ASIDE_CURRENT_VERSION_LINK default = $(WRAPPER:G=aside)$(/)Versions$(/)Current ;
            ASIDE_CURRENT_VERSION_LINK_PATH default = Versions$(/)Current ;
            ASIDE_CURRENT_VERSION_LINK_PATH = $(ASIDE_CURRENT_VERSION_LINK_PATH:G=aside) ;
            Mkdir $(ASIDE_CURRENT_VERSION_DIR) ;
            ProductFileAside $(ASIDE_CURRENT_VERSION_DIR) ;
            DEPENDS $(1) : $(ASIDE_CURRENT_VERSION_DIR) ;
            NOUPDATE $(ASIDE_CURRENT_VERSION_DIR) ;
            SymLink $(ASIDE_CURRENT_VERSION_LINK) : $(FRAMEWORK_VERSION) ;
            ProductFileAside $(ASIDE_CURRENT_VERSION_LINK) ;
            DEPENDS $(1) : $(ASIDE_CURRENT_VERSION_LINK) ;
            DEPENDS $(ASIDE_CURRENT_VERSION_LINK) : $(ASIDE_CURRENT_VERSION_DIR) ;
            NOUPDATE $(ASIDE_CURRENT_VERSION_LINK) ;
        }
        # Create current version directory and link now because
        # they are implicit and needed by almost everything else:
        # Current version dir
        Mkdir $(CURRENT_VERSION_DIR) ;
        ProductFile $(CURRENT_VERSION_DIR) ;
        DEPENDS $(1) : $(CURRENT_VERSION_DIR) ;  # need this or build phase
        NOUPDATE $(CURRENT_VERSION_DIR) ;
        # Current version link
        SymLink $(CURRENT_VERSION_LINK) : $(FRAMEWORK_VERSION) ;
        ProductFile $(CURRENT_VERSION_LINK) ;
        DEPENDS $(1) : $(CURRENT_VERSION_LINK) ;  # need this or build phase
        DEPENDS $(CURRENT_VERSION_LINK) : $(CURRENT_VERSION_DIR) ;
        NOUPDATE $(CURRENT_VERSION_LINK) ;
    } # framework wrappers
    else {
        # Default bundle wrappers
        if $(BUNDLE_STYLE) = SHALLOW {
            # shallow bundles do not have the Contents/Resources folders
            RESOURCE_DIR default = $(WRAPPER) ;
            LOCATE on $(RESOURCE_DIR) = $(TARGET_BUILD_DIR) ;
            APPLESCRIPTS_DIR default = $(WRAPPER)$(/)Scripts ;
            LOCATE on $(APPLESCRIPTS_DIR) = $(TARGET_BUILD_DIR) ;
            PUBLIC_HEADER_DIR default = $(WRAPPER)$(/)Headers ;
            LOCATE on $(PUBLIC_HEADER_DIR) = $(TARGET_BUILD_DIR) ;
            PRIVATE_HEADER_DIR default = $(WRAPPER)$(/)PrivateHeaders ;
            LOCATE on $(PRIVATE_HEADER_DIR) = $(TARGET_BUILD_DIR) ;
        }
        else {
            # else, BUNDLE_STYLE=DEEP bundles do have Contents/Resources folders
            RESOURCE_DIR default = $(WRAPPER)$(/)Contents$(/)Resources ;
            LOCATE on $(RESOURCE_DIR) = $(TARGET_BUILD_DIR) ;
            APPLESCRIPTS_DIR default = $(RESOURCE_DIR)$(/)Scripts ;
            LOCATE on $(APPLESCRIPTS_DIR) = $(TARGET_BUILD_DIR) ;
            PUBLIC_HEADER_DIR default = $(WRAPPER)$(/)Contents$(/)Headers ;
            LOCATE on $(PUBLIC_HEADER_DIR) = $(TARGET_BUILD_DIR) ;
            PRIVATE_HEADER_DIR default = $(WRAPPER)$(/)Contents$(/)PrivateHeaders ;
            LOCATE on $(PRIVATE_HEADER_DIR) = $(TARGET_BUILD_DIR) ;
        }
        RESOURCE_LINK default = "" ;
        PUBLIC_HEADER_LINK default = "" ;
        PRIVATE_HEADER_LINK default = "" ;
        CURRENT_VERSION_DIR default = "" ;
        CURRENT_VERSION_LINK default = "" ;
    } # all bundle layouts
    # define location for optional header documentation generation
    if $(GENERATE_HEADERDOC) = YES && $(RESOURCE_DIR) {
        HEADERDOC_DIR default = $(TARGET_BUILD_DIR)$(/)$(RESOURCE_DIR)$(/)Documentation ;
        Mkdir $(HEADERDOC_DIR) ;
        ProductFile $(HEADERDOC_DIR) ;
    }

    # wrapped products may define a location for unarchived classes
    if $(JAVA_ARCHIVE_CLASSES) != YES {
        export PRODUCT_CLASS_FILE_DIR default = $(TARGET_BUILD_DIR)$(/)$(RESOURCE_DIR)$(/)Java ;
    }
}

# EndWrappedProduct <product>
#
# Sets up additional dependence related to object files.
# Files depended on by object files should be in compile rules,
# and dependence on object files should be in link rules.
rule EndWrappedProduct
{
    # Wrapper touch updates base container directory timestamp
    # This must be conditional on the "build" component,
    # otherwize installhdrs builds with no headers will fail.
    if build in $(BUILD_COMPONENTS) {
        WRAPPER_TOUCH = $(1:G=Touch) ;
        LOCATE on $(WRAPPER_TOUCH) = $(TARGET_BUILD_DIR) ;
        DEPENDS $(WRAPPER_TOUCH) : $(BUILD_PHASE) ;
        DEPENDS $(1) : $(WRAPPER_TOUCH) ;
        Touch $(WRAPPER_TOUCH) ;
    }
    # wrapper logic complete, now handle final build issues
    EndProduct $(1) ;
}