List Info

Thread: Boost.Build and CSharp




Boost.Build and CSharp
user name
2006-03-10 20:27:23
Pedro Lamarão escreveu:

> After a day of experiment, I feel a dotnet.jam similar
to msvc.jam for
> the .NET SDK could work very well; the paths for
toolsets in
> /WINNT/Microsoft.NET/Framework/ are very predictable.
This is my current
> attempt. At the end of the day I'll have proper
feature support.

Attached are the cs.jam and dotnet.jam I could come up with
so far.
dotnet.jam supports auto-discovery of .NET SDK in
$(SystemRoot)/Microsoft.NET/Framework/ , basic features like
<warnings>
and <debug> ; it reuses <include> and adds a new
<reference> feature ;
and supports C# outputting .exe and .dll.

Open issues:

*) It is common for .NET libraries to be named after the
contained
   namespaces like this: Namespace.Name.dll.
   All those dots are not supported by Boost.Build.

*) Mixing "managed" C++ with msvc and C# with
dotnet simply doesn't
   work. I suspect the answer for this conflict is in
python.jam,
   haven't looked there yet.

*) When a lib target is imported as source in another lib or
exe
   project, what should we do? Could not figure out this
one.

--
 Pedro Lamarão
# Copyright Pedro Lamarão (C) 2006.
# Distributed under the Boost Software License, version 1.0.
# (See accompanying file LICENSE_1_0.txt
#  or copy at http://www.boost
.org/LICENSE_1_0.txt)
type CS : cs ;# Copyright (c) 2003 David Abrahams.
# Copyright (c) 2005 Vladimir Prus.
# Copyright (c) 2005 Alexey Pakhunov.
# Copyright (c) 2006 Pedro Lamarão.
#
# Use, modification and distribution is subject to the Boost
Software
# License Version 1.0. (See accompanying file
LICENSE_1_0.txt or
# http://www.boost
.org/LICENSE_1_0.txt)

import property ;
import generators ;
import os ;
import type ;
import toolset : flags ;
import errors : error ;
import feature : feature get-values ;
import path ;
import sequence : unique ;
import common ;
import "class" : new ;

if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ]
]
{
    .debug-configuration = true ;
}

feature.extend toolset : dotnet ;

# List of all registered configurations
.versions = [ new configurations ] ;

RM =  [ common.rm-command ] ;
nl = "
" ;

# Initialize the toolset for a specific version. As the
result, path to
# compiler and, possible, program names are set up, and will
be used when
# that version of compiler is requested. For example, you
might have:
#
#    using dotnet : 1.0 : scs.exe ;
#    using dotnet : 2.0 :
c:/WINNT/Microsoft.NET/Framework/v2.0.50727/csc.exe ;
#
# The version paramater can be ommited:
#
#    using dotnet : :
c:/WINNT/Microsoft.NET/Framework/v2.0.50727/csc.exe ;
#
# Two special version keywords may be supplied:
#   - all - all detected versions will be registered;
#   - default - this is an equivalent to an empty version.
#
# Depending on a supplied version, detected configurations
and presence 
# 'csc.exe' in the path different results may be achieved.
The following 
# table describes all possible cases:
#
#                                      Nothing           
"x.y"
# Passed   Nothing       "x.y"         detected,
         detected,
# version  detected      detected      csc.exe in path   
csc.exe in path
# 
# default  Error         Use "x.y"     Create
"default"   Use "x.y"
# all      None          Use all       None              
Use all
# x.y      -             Use "x.y"     -        
         Use "x.y"
# a.b      Error         Error         Create
"a.b"       Create "a.b"
# 
# "x.y" - refers to a detected version;
# "a.b" - refers to an undetected version.
#
rule init ( 
    version ? # The dotnet version which is being
configured. When omitted
              # the tools invoked when no explicit version
is given will be configured.
    : command * 
    # the command to invoke the compiler. If not specified:
    #       - if version is given, default location for that
version will be searched
    # 
    #       - if version is not given, default locations for
2.0, 1.1 and 1.0 will 
    #         be searched    
    # 
    #       - if compiler is not found in default locations,
PATH will be searched.    
    : options * 
    # options can include <setup>,
<cs-compiler>, ...
)
{
    if $(command)
    {
        options += <command>$(command) ;
    }

    configure $(version) : $(options) ;
}


# 'configure' is a newer version of 'init'. The
parameter 'command' is passed as 
# a part of the 'options' list.
rule configure (
    version ? :
    options * 
    )
{
    switch $(version)
    {
        case all :
            if $(options)
            {
                error "dotnet: options should be empty
when 'all' is specified" ;
            }

            # use all detected versions
            for local v in [ $(.versions).all ]
            {
                configure-really $(v) ;
            }

        case "default" :
            configure-really : $(options) ;

        case * :
            configure-really $(version) : $(options) ;
    }
}

local rule configure-really (
    version ? :
    options *
    )
{
    # If no version supplied use the default configuration.
Note that condition 
    # remains versionless.
    local v = $(version) ;
    if ! $(v)
    {
        # take the first detected version
        version = [ $(.versions).all ] ;
        version = $(version[1]) ;

        # Note: 'version' can still be empty at this point
if no versions were 
        # detected.
        version ?= "default" ;
    }

    # Check whether selected configuration is used already
    if $(version) in [ $(.versions).used ]
    {
        # Allow multiple 'toolset.usage' calls for the
same configuration
        # if the identical sets of options are used 
        if $(options) && ( $(options) != [
$(.versions).get $(version) : options ] )
        {
            error "dotnet: the toolset version
'$(version)' is configured already" ;
        }
    }
    else
    {
        # Register a new configuration 
        $(.versions).register $(version) ;

        # Set new options if any
        if $(options)
        {
            $(.versions).set $(version) : options :
$(options) ;
        }

        # Mark the configuration as 'used'.
        $(.versions).use $(version) ;

        # Get auto-detected or user-supplied options 
        options = [ $(.versions).get $(version) : options ]
;

        # Generate condition and save it
        local condition = [ common.check-init-parameters
dotnet : 
            version $(v) ] ;

        $(.versions).set $(version) : condition :
$(condition) ;


        local command = [ get-values <command> :
$(options) ] ;

        # If version is specified, we try to search first in
default paths,
        # and only then in PATH.
        command = [ common.get-invocation-command dotnet :
csc.exe : $(command)
          : [ default-paths $(version) ] : $(version) ] ;

        common.handle-options dotnet : $(condition) :
$(command) : $(options) ;
            

        if ! $(version) 
        {
            # Even if version is not explicitly specified,
try to detect the version
            # from the path.
            if [ MATCH "(2.0)" : $(command) ]
            {
                version = 2.0 ;
            }                 
            else if [ MATCH "(1.1)" : $(command)
]
            {
                version = 1.1 ;
            }
            else
            {
                version = 1.0 ;
            }
        }

        if $(.debug-configuration)
        {
            ECHO "dotnet: command:
'$(command)'" ;
        }

        local parent = $(command) ;

        cs-compiler = [ get-values <cs-compiler> :
<options> ] ;
        cs-compiler ?= csc ;

        if $(.debug-configuration)
        {
            ECHO "dotnet: condition: '$(condition)',
parent: '$(parent)'" ;
        }

        flags dotnet.compile .CSC $(condition) :
$(parent)"\\"$(cs-compiler) ;

    }
}

# Returns the default installation path for the given
version. 
local rule default-path ( version )
{
    # Use auto-detected path if possible 
    local path = [ get-values <command> : 
        [ $(.versions).get $(version) : options ] ] ;

    if $(path)
    {
        path = $(path) ;
    }
    else
    {
        # Check default path
        if ! $(path) && $(.version-$(version)-path)
        {
            path = [ path.native [ path.join $(.SystemRoot)
$(.version-$(version)-path) ] ] ;
        }
    }

    return $(path) ;
}

# Returns either the default installation path (if
'version' is not empty) or list of all 
# known default paths (if no version is given)
rule default-paths ( version ? )
{
    local possible-paths ;
    
    if $(version)
    {
        default-path += [ default-path $(version) ] ;
    }
    else
    {
        for local i in $(.known-versions)
        {
            default-path += [ default-path $(i) ] ;
        }
    }

    return $(possible-paths) ;
}


# Declare generators

generators.register-linker dotnet.compile.cs2exe : CS : EXE
: <toolset>dotnet ;
generators.register-linker dotnet.compile.cs2dll : CS : LIB
: <toolset>dotnet ;

#
# Declare flags and action for compilation
#
feature.feature reference : : free ;

flags dotnet.compile CSFLAGS <optimization>speed :
/optimize ;
flags dotnet.compile CSFLAGS <optimization>space :
/optimize ;
flags dotnet.compile CSFLAGS <optimization>off : ;

flags dotnet.compile CSFLAGS
<debug-symbols>on/<debug-store>object : /debug ;
flags dotnet.compile CSFLAGS
<debug-symbols>on/<debug-store>database : /debug
;

flags dotnet.compile CSFLAGS <warnings>on : /warn:3 ;
flags dotnet.compile CSFLAGS <warnings>off : /warn:0 ;
flags dotnet.compile CSFLAGS <warnings>all : /warn:4 ;
flags dotnet.compile CSFLAGS <warnings-as-errors>on :
/warnaserrors ;

flags dotnet.compile USER_CSFLAGS <cflags> : ;
flags dotnet.compile USER_CSFLAGS <cxxflags> : ;

flags dotnet.compile DEFINES <define> ;
flags dotnet.compile INCLUDES <include> ;
flags dotnet.compile REFERENCES <reference> ;

rule compile.cs2exe ( targets + : sources * : properties * )
{
    DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
}

rule compile.cs2dll ( targets + : sources * : properties * )
{
    DEPENDS $(<) : [ on $(<) return $(DEF_FILE) ] ;
}

actions compile.cs2exe
{
    $(.CSC) /nologo /target:exe
/out:"$(<[1]:W)" "($(<[1]:W).rsp:E=$(nl)"$(>)"
$(nl)/define:$(DEFINES) $(nl)"/lib:$(INCLUDES)"
$(nl)/reference:$(REFERENCES))" $(CSFLAGS)
$(USER_CSFLAGS)
}

actions compile.cs2dll
{
    $(.CSC) /nologo /target:library
/out:"$(<[1]:W)" "($(<[1]:W).rsp:E=$(nl)"$(>)"
$(nl)/define:$(DEFINES) $(nl)"/lib:$(INCLUDES)"
$(nl)/reference:$(REFERENCES))" $(CSFLAGS)
$(USER_CSFLAGS)
}

#
# Autodetection code
#     detects versions listed as '.known-versions'
checking default paths. 
#

rule get-system-root-dir ( )
{
    local SystemRoot = [ modules.peek : SystemRoot ] ;
    if $(SystemRoot)
    {
        SystemRoot = "$(SystemRoot)" ;
    }
    else
    {
        SystemRoot = "c:\\WINNT" ;
    }
    return $(SystemRoot) ;
}

.SystemRoot = [ path.make [ get-system-root-dir ] ] ;

.known-versions = 2.0 1.1 1.0 ;

# Path to .NET SDK
.version-2.0-path =
"Microsoft.NET\\Framework\\v2.0.50727" ;
.version-1.1-path =
"Microsoft.NET\\Framework\\v1.1.4322" ;
.version-1.0-path =
"Microsoft.NET\\Framework\\v1.0.3705" ;

# Validates given path, registers found configuration and
prints debug information 
# about it.
local rule register-configuration ( version : path ? )
{
    if $(path)
    {
        local command = [ GLOB $(path) : csc.exe ] ;

        if $(command)
        {
            if $(.debug-configuration)
            {
                ECHO "notice: dotnet-$(version)
detected, command: '$(command)'" ;
            }

            $(.versions).register $(version) ;
            $(.versions).set $(version) : options :
<command>$(command) ;
        }
    }
}

# Check environment and default installation paths
for local i in $(.known-versions)
{
    if ! $(i) in [ $(.versions).all ]
    {
        register-configuration $(i) : [ default-path $(i) ]
;
    }
}
_______________________________________________
Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost-build
[1]

about | contact  Other archives ( Real Estate discussion Medical topics )