⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 project.jam

📁 C++的一个好库。。。现在很流行
💻 JAM
📖 第 1 页 / 共 3 页
字号:
#  Copyright (C) Vladimir Prus and Rene Rivera 2002.
#  Permission to copy, use, modify, sell and
#  distribute this software is granted provided this copyright notice appears in
#  all copies. This software is provided "as is" without express or implied
#  warranty, and with no claim as to its suitability for any purpose.

#  Implements project representation and loading.
#   Each project is represented by 
#   - a module where all the Jamfile content live. 
#   - an instance of 'project-attributes' class.
#     (given module name, can be obtained by 'attributes' rule)
#   - an instance of 'project-target' class (from targets.jam)
#     (given a module name, can be obtained by 'target' rule)
#
#  Typically, projects are created as result of loading Jamfile, which is
#  do by rules 'load' and 'initialize', below. First, module for Jamfile
#  is loaded and new project-attributes instance is created. Some rules
#  necessary for project are added to the module (see 'project-rules' module)
#  at the bottom of this file.
#  Default project attributes are set (inheriting attributes of parent project, if
#  it exists). After that, Jamfile is read. It can declare its own attributes,
#  via 'project' rule, which will be combined with already set attributes.
#
#
#  The 'project' rule can also declare project id, which will be associated with 
#  the project module.
#
#  There can also be 'standalone' projects. They are created by calling 'initialize'
#  on arbitrary module, and not specifying location. After the call, the module can
#  call 'project' rule, declare main target and behave as regular projects. However,
#  since it's not associated with any location, it's better declare only prebuilt 
#  targets.
#
#  The list of all loaded Jamfile is stored in variable .project-locations. It's possible
#  to obtain module name for a location using 'module-name' rule. The standalone projects
#  are not recorded, the only way to use them is by project id.


import modules : peek poke ;
import numbers ;
import path ;
import sequence ;
import errors : error ;

import print ;
import "class" : new ;
import errors ;
import assert ;
import property-set ;

#
#   Loads jamfile at the given location. After loading, project global
#   file and jamfile needed by the loaded one will be loaded recursively.
#   If the jamfile at that location is loaded already, does nothing.
#   Returns the project module for the Jamfile.
#
rule load ( jamfile-location )
{   
    if --debug-loading in [ modules.peek : ARGV ]
    {
        ECHO "Loading Jamfile at" '$(jamfile-location)' ;
    }    
            
    local module-name = [ module-name $(jamfile-location) ] ;            
    # If Jamfile is already loaded, don't try again.
    if ! $(module-name) in $(.jamfile-modules)
    {      
        load-jamfile $(jamfile-location) ;
                
        # We want to make sure that child project are loaded only
        # after parent projects. In particular, because parent projects
        # define attributes whch are inherited by children, and we don't
        # want children to be loaded before parents has defined everything.
        # So, for "build-project" and "use-project" we only record relevant
        # information, and actually load the mentioned projects after
        # loading the current Jamfile.       
        for local p in [ attribute $(module-name) projects-to-build ]
        {
            load [ path.join $(jamfile-location) $(p) ] ;
        }

        local used = [ modules.peek $(module-name) : .used-projects ] ;
                import project ;
        while $(used)
        {
            local id = $(used[1]) ;
            local where = $(used[2]) ;
            
            project.use $(id) : [ path.root 
                [ path.make $(where) ] $(jamfile-location) ] ;
            used = $(used[3-]) ;
        }        
    }                
    return $(module-name) ;        
}

# Note the use of character groups, as opposed to listing
# 'Jamroot' and 'jamroot'. With the latter, we'd get duplicate
# matches on windows and would have to eliminate duplicates.
JAMROOT = project-root.jam [Jj]amroot [Jj]amroot.jam ;
# Loads parent of Jamfile at 'location'. Issues an error if nothing is found.
rule load-parent ( location )
{
    local found = [ path.glob-in-parents $(location) : 
      $(JAMROOT) $(JAMFILE) ] ;
    
    if ! $(found)
    {
        ECHO "error: Could not find parent for project at '$(location)'" ;
        ECHO "error: Did not find Jamfile or project-root.jam in any parent directory." ;
        EXIT ;
    }
    
    return [ load $(found[1]:D) ] ;    
}

# Makes the specified 'module' act as if it were a regularly loaded Jamfile 
# at 'location'. If Jamfile is already located for that location, it's an 
# error. 
rule act-as-jamfile ( module : location )
{
    if [ module-name $(location) ] in $(.jamfile-modules)
    {
        errors.error "Jamfile was already loaded for '$(location)'" ;
    }
    # Set up non-default mapping from location to module.
    .module.$(location) = $(module) ;    
    
    # Add the location to the list of project locations
    # so that we don't try to load Jamfile in future
    .jamfile-modules += [ module-name $(location) ] ;
    
    initialize $(module) : $(location) ;
}


# Given 'name' which can be project-id or plain directory name,
# return project module corresponding to that id or directory.
# Returns nothing of project is not found.
rule find ( name : current-location )
{
    local project-module ;
    
    # Try interpreting name as project id.
    if [ path.is-rooted $(name) ]
    {            
        project-module =  $($(name).jamfile-module) ;
    }            
                
    if ! $(project-module)
    {            
        local location = [ path.root 
            [ path.make $(name) ] $(current-location) ] ;
        # If no project is registered for the given location, try to
        # load it. First see if we have Jamfile. If not we might have project
        # root, willing to act as Jamfile. In that case, project-root
        # must be placed in the directory referred by id.
        
        project-module = [ module-name $(location) ] ;
        if ! $(project-module) in $(.jamfile-modules) 
        {
            if [ path.glob $(location) : $(JAMROOT) $(JAMFILE) ]
            {
                project-module = [ load $(location) ] ;            
            }        
            else
            {
                project-module = ;
            }
        }                    
    }
    
    return $(project-module) ;
}

#
# Returns the name of module corresponding to 'jamfile-location'.
# If no module corresponds to location yet, associates default
# module name with that location.
#
rule module-name ( jamfile-location )
{
    if ! $(.module.$(jamfile-location))
    {
        # Root the path, so that locations are always umbiguious.
        # Without this, we can't decide if '../../exe/program1' and '.'
        # are the same paths, or not.
        jamfile-location = [ path.root $(jamfile-location) [ path.pwd ] ] ;
        .module.$(jamfile-location) =  Jamfile<$(jamfile-location)> ;
    }
    return $(.module.$(jamfile-location)) ;
}

# Default patterns to search for the Jamfiles to use for build
# declarations.
#
JAMFILE = [ modules.peek : JAMFILE ] ;
JAMFILE ?= [Jj]amfile.v2 [Jj]amfile [Jj]amfile.jam ;

# Find the Jamfile at the given location. This returns the exact names of
# all the Jamfiles in the given directory. The optional parent-root argument
# causes this to search not the given directory but the ones above it up
# to the directory given in it.
#
local rule find-jamfile (
    dir # The directory(s) to look for a Jamfile.
    parent-root ? # Optional flag indicating to search for the parent Jamfile.
    : no-errors ?
    )
{
    # Glob for all the possible Jamfiles according to the match pattern.
    #
    local jamfile-glob = ;
    if $(parent-root)
    {
        if ! $(.parent-jamfile.$(dir))
        {     
            .parent-jamfile.$(dir) = 
              [ path.glob-in-parents $(dir) : $(JAMFILE)  ] ;            
        }        
        jamfile-glob = $(.parent-jamfile.$(dir)) ;                            
    }
    else
    {
        if ! $(.jamfile.$(dir))
        {            
            .jamfile.$(dir) = [ path.glob $(dir) : $(JAMFILE) ] ;         
        }   
        jamfile-glob = $(.jamfile.$(dir)) ;
        
    }
    
    local jamfile-to-load = $(jamfile-glob) ;
    # Multiple Jamfiles found in the same place. Warn about this.
    # And ensure we use only one of them.
    # As a temporary convenience measure, if there's Jamfile.v2 amount
    # found files, suppress the warning and use it.
    #
    if $(jamfile-to-load[2-])
    {
        local v2-jamfiles = [ MATCH (.*[Jj]amfile\\.v2) : $(jamfile-to-load) ] ;

        if $(v2-jamfiles) && ! $(v2-jamfiles[2])
        {
            jamfile-to-load = $(v2-jamfiles) ;
        }        
        else
        {                    
            ECHO
              "warning: Found multiple Jamfiles at '"$(dir)"'!"
                "Loading the first one: '" [ path.basename $(jamfile-to-load[1]) ]  "'." ;
        }
                    
        jamfile-to-load = $(jamfile-to-load[1]) ;
    }    
    
    # Could not find it, error.
    #
    if ! $(no-errors) && ! $(jamfile-to-load)
    {
        errors.error
            "Unable to load Jamfile." :
            "Could not find a Jamfile in directory '$(dir)'". : 
            "Attempted to find it with pattern '"$(JAMFILE:J=" ")"'." :
            "Please consult the documentation at 'http://www.boost.org'." ;
    }

    return $(jamfile-to-load) ;
}

# Load a Jamfile at the given directory. Returns nothing.
# Will attempt to load the file as indicated by the JAMFILE patterns. 
# Effect of calling this rule twice with the same 'dir' is underfined.

local rule load-jamfile (
    dir # The directory of the project Jamfile.
    )
{
    # See if the Jamfile is where it should be.
    #
    local jamfile-to-load = [ path.glob $(dir) : $(JAMROOT) ] ;
    if ! $(jamfile-to-load)
    {
        jamfile-to-load = [ find-jamfile $(dir) ] ;
    }
    
    
    # The module of the jamfile.
    #
    local jamfile-module = [ module-name  [ path.parent $(jamfile-to-load) ] ] ;

    # Initialize the jamfile module before loading.
    #    
    initialize $(jamfile-module) : [ path.parent $(jamfile-to-load) ] 
      : $(jamfile-to-load:BS) ;

    local saved-project = $(.current-project) ;
    # Now load the Jamfile in it's own context.
    # Initialization might have load parent Jamfiles, which might have
    # loaded the current Jamfile with use-project. Do a final check to make
    # sure it's not loaded already.
    if ! $(jamfile-module) in $(.jamfile-modules)
    {           
        .jamfile-modules += $(jamfile-module) ;        
        mark-as-user $(jamfile-module) ;
        modules.load $(jamfile-module) :  [ path.native $(jamfile-to-load) ] : . ;
        if $(jamfile-to-load:BS) = project-root.jam
        {
            jamfile = [ find-jamfile $(dir) : no-errors ] ;
            if $(jamfile)
            {                
                load-aux $(jamfile-module) : [ path.native $(jamfile) ] ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -