|
Boost-Build : |
From: Pedro Lamarão (pedro.lamarao_at_[hidden])
Date: 2006-03-10 15: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:D) ;
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:D) ;
}
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) ] ;
}
}
Boost-Build list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk