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

📄 builtin.jam

📁 C++的一个好库。。。现在很流行
💻 JAM
📖 第 1 页 / 共 2 页
字号:
#  Copyright (C) Vladimir Prus 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.

#  Defines standard features and rules.

import "class" : new ;

import feature : feature compose ;
import toolset : flags ;
import errors : error ;
import type ;
import scanner ;
import generators ;
import regex ;
import virtual-target ;
import os ;
import symlink ;
import alias ;
import property ;
import print ;
import utility ;
import project ;

# This feature is used to determine which OS we're on.
# In future, this may become <target-os> and <host-os>
local os = [ modules.peek : OS ] ;
feature os : $(os) : propagated link-incompatible ;

feature toolset : : implicit propagated symmetric ;

feature stdlib : native : propagated composite ;

feature link : shared static : propagated ;
feature runtime-link : shared static : propagated ;
feature runtime-debugging : on off : propagated ;


feature optimization : off speed space : propagated ;
feature profiling : off on : propagated ;
feature inlining : off on full : propagated ;

feature threading : single multi : propagated ;
feature rtti : on off : propagated ;
feature exception-handling : on off : propagated ;
# Whether there is support for asynchronous EH (e.g. catching SEGVs)
feature asynch-exceptions : off on : propagated ;  
# Whether all extern "C" functions are considered nothrow by default
feature extern-c-nothrow : off on : propagated ;
feature debug-symbols : on off : propagated ;
feature define : : free ;
feature "include" : : free path ; #order-sensitive ;
feature cflags : : free ;
feature cxxflags : : free ;
feature fflags : : free ;
feature linkflags : : free ;
feature archiveflags : : free ;
feature version : : free ;

feature.feature location-prefix : : free ;


# The following features are incidental, since
# in themself they have no effect on build products.
# Not making them incidental will result in problems in corner
# cases, for example:
# 
#    unit-test a : a.cpp : <use>b ;
#    lib b : a.cpp b ;
# 
# Here, if <use> is not incidental, we'll decide we have two 
# targets for a.obj with different properties, and will complain.
#
# Note that making feature incidental does not mean it's ignored. It may
# be ignored when creating the virtual target, but the rest of build process
# will use them.
feature use : : free dependency incidental ;
feature dependency : : free dependency incidental ;
feature implicit-dependency : : free dependency incidental ;

feature source : : free dependency incidental ;
feature library : : free dependency incidental ;
feature file : : free dependency incidental ;
feature find-shared-library : : free ; #order-sensitive ;
feature find-static-library : : free ; #order-sensitive ;
feature library-path : : free path ; #order-sensitive ;
# Internal feature.
feature library-file : : free dependency ;

feature name : : free ;
feature tag : : free ;
feature search : : free path ; #order-sensitive ;
feature location : : free path ;

feature dll-path : : free path ;
feature hardcode-dll-paths : true false : incidental ;


# This is internal feature which holds the paths of all dependency
# dynamic libraries. On Windows, it's needed so that we can all
# those paths to PATH, when running applications.
# On Linux, it's needed to add proper -rpath-link command line options.
feature xdll-path : : free path ;

#provides means to specify def-file for windows dlls.
feature def-file : : free dependency ;

# This feature is used to allow specific generators to run.
# For example, QT tools can only be invoked when QT library
# is used. In that case, <allow>qt will be in usage requirement
# of the library.
feature allow : : free ;

# Windows-specific features

feature user-interface : console gui wince native auto ;

feature variant : : implicit composite propagated symmetric ;

# Declares a new variant.
# First determines explicit properties for this variant, by
# refining parents' explicit properties with the passed explicit
# properties. The result is remembered and will be used if
# this variant is used as parent.
#
# Second, determines the full property set for this variant by
# adding to the explicit properties default values for all properties 
# which neither present nor are symmetric.
#
# Lastly, makes appropriate value of 'variant' property expand
# to the full property set.
rule variant ( name           # Name of the variant
    : parents-or-properties * # Specifies parent variants, if 
                              # 'explicit-properties' are given,
                              # and explicit-properties otherwise.
    : explicit-properties *   # Explicit properties.
    )
{
    local parents ;
    if ! $(explicit-properties)
    {
        if $(parents-or-properties[1]:G)
        {
            explicit-properties = $(parents-or-properties) ;
        }
        else
        {
            parents = $(parents-or-properties) ;
        }
    }
    else
    {
        parents = $(parents-or-properties) ;
    }

    # The problem is that we have to check for conflicts
    # between base variants.
    if $(parents[2])
    {
        error "multiple base variants are not yet supported" ;
    }
    
    local inherited ;
    # Add explicitly specified properties for parents
    for local p in $(parents)
    {
        # TODO: the check may be sticter
        if ! [ feature.is-implicit-value $(p) ]
        {
            error "Invalid base varaint" $(p)  ;
        }
        
        inherited += $(.explicit-properties.$(p)) ;
    }
    property.validate $(explicit-properties) ;
    explicit-properties = [ property.refine $(inherited) : $(explicit-properties) ] ;
    
    # Record explicitly specified properties for this variant
    # We do this after inheriting parents' properties, so that
    # they affect other variants, derived from this one.
    .explicit-properties.$(name) = $(explicit-properties) ;
           
    feature.extend variant : $(name) ;
    feature.compose <variant>$(name) : $(explicit-properties) ;    
}
IMPORT $(__name__) : variant : : variant ;

variant debug : <optimization>off <debug-symbols>on <inlining>off <runtime-debugging>on ;
variant release : <optimization>speed <debug-symbols>off <inlining>full 
                  <runtime-debugging>off <define>NDEBUG ;
variant profile : release : <profiling>on <debug-symbols>on ;

class searched-lib-target : abstract-file-target
{
    rule __init__ ( name     
        : project 
        : shared ?                                
        : real-name ?
        : search *
        : action
    )
    {
        abstract-file-target.__init__ $(name) : SEARCHED_LIB : $(project) 
          : $(action) ;
        
        self.shared = $(shared) ;
        self.real-name = $(real-name) ;
        self.real-name ?= $(name) ;
        self.search = $(search) ;
    }
    
    
    rule shared ( )
    {
        return $(self.shared) ;
    }
    
    rule real-name ( ) 
    {
        return $(self.real-name) ;
    }
    
    rule search ( )
    {
        return $(self.search) ;
    }
        
    rule actualize-location ( target )
    {
        NOTFILE $(target) ;
    }    
    
    rule path ( )
    {
    }
}    

import types/register ;
import stage ;


class c-scanner : scanner 
{
    import regex virtual-target path scanner ;    
    
    rule __init__ ( includes * )
    {
        scanner.__init__ ;
    
        self.includes = $(includes) ;
    }    

    rule pattern ( )
    {
        return "#[ \t]*include[ ]*(<(.*)>|\"(.*)\")" ;
    }

    rule process ( target : matches * : binding )
    {
        local angle = [ regex.transform $(matches) : "<(.*)>" ] ;
        local quoted = [ regex.transform $(matches) : "\"(.*)\"" ] ;

        # CONSIDER: the new scoping rule seem to defeat "on target" variables.
        local g = [ on $(target) return $(HDRGRIST) ] ;  
        local b = [ NORMALIZE_PATH $(binding:D) ] ;

        # Attach binding of including file to included targets.
        # When target is directly created from virtual target
        # this extra information is unnecessary. But in other
        # cases, it allows to distinguish between two headers of the 
        # same name included from different places.      
        # We don't need this extra information for angle includes,
        # since they should not depend on including file (we can't
        # get literal "." in include path).
        local g2 = $(g)"#"$(b) ;
       
        angle = $(angle:G=$(g)) ;
        quoted = $(quoted:G=$(g2)) ;
        
        local all = $(angle) $(quoted) ;

        INCLUDES $(target) : $(all) ;
        NOCARE $(all) ;
        SEARCH on $(angle) = $(self.includes:G=) ;
        SEARCH on $(quoted) = $(b) $(self.includes:G=) ;
        
        # Just propagate current scanner to includes, in a hope
        # that includes do not change scanners. 
        scanner.propagate $(__name__) : $(angle) $(quoted) : $(target) ;
    }        
}

scanner.register c-scanner : include ;

type.set-scanner CPP : c-scanner ;


type.register H : h ;
type.register HPP : hpp : H ;
type.register C : c ;

type.set-scanner C : c-scanner ;

# The generator class for libraries (target type LIB). Depending on properties it will
# request building of the approapriate specific type -- SHARED_LIB, STATIC_LIB or 
# SHARED_LIB.
class lib-generator : generator
{
    rule __init__ ( * : * )
    {
        generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
    }
    
    rule run ( project name ? : property-set : sources * )
    {
        # The lib generator is composing, and can be only invoked with
        # explicit name. This check is present in generator.run (and so in
        # builtin.linking-generator), but duplicate it here to avoid doing
        # extra work.
        if $(name)
        {            
            local properties = [ $(property-set).raw ] ;
            # Determine the needed target type
            local actual-type ;
            if <search> in $(properties:G) || <name> in $(properties:G)
            {
                actual-type = SEARCHED_LIB ;
            }
            else if <file> in $(properties:G)
            {
                # The generator for 
                actual-type = LIB ;
            }        
            else if <link>shared in $(properties)
            {
                actual-type = SHARED_LIB ;
            }
            else 
            {
                actual-type = STATIC_LIB ;
            }
            property-set = [ $(property-set).add-raw <main-target-type>LIB ] ;
            # Construct the target.
            return [ generators.construct $(project) $(name) : $(actual-type) 
              : $(property-set) : $(sources) : LIB ] ;        
        }  
    }    
    
    rule viable-source-types ( )
    {
        return * ;
    }    
}

generators.register [ new lib-generator builtin.lib-generator :  : LIB ] ;

# The implementation of the 'lib' rule. Beyond standard syntax that rule allows
# simplified:
#    lib a b c ;
# so we need to write code to handle that syntax. 
rule lib ( names + : sources * : requirements * : default-build * 
    : usage-requirements * )
{
    local project = [ project.current ] ;
    
    # This is a circular module dependency, so it must be imported here
    import targets ;
    
    if $(names[2])
    {
        if <name> in $(requirements:G)
        {
            errors.user-error "When several names are given to the 'lib' rule" :
              "it's not allowed to specify the <name> feature. " ;
        }        
        if $(sources)

⌨️ 快捷键说明

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