2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-17 01:32:12 +00:00

Merge fixes from HEAD.

[SVN r33484]
This commit is contained in:
Vladimir Prus
2006-03-27 12:05:57 +00:00
parent 172135c54f
commit 28e0619911
10 changed files with 364 additions and 248 deletions

View File

@@ -658,7 +658,7 @@ rule expand-composites ( properties * )
error explicitly-specified values of non-free feature
$(f) conflict :
"existing values:" [ get-values $(f) : $(properties) ] :
"value from expanding " $(p) ":" (x:G=) ;
"value from expanding " $(p) ":" $(x:G=) ;
}
else
{

View File

@@ -674,6 +674,22 @@ rule current ( )
return $(.current-project) ;
}
# Temporary changes the current project to 'project'. Should
# be followed by 'pop-current'.
rule push-current ( project )
{
.saved-current-project += $(.current-project) ;
.current-project = $(project) ;
}
rule pop-current ( )
{
.current-project = $(.saved-current-project[-1]) ;
.saved-current-project = $(.saved-current-project[1--2]) ;
}
# Returns the project-attribute instance for the specified jamfile module.
rule attributes ( project )
{

View File

@@ -50,6 +50,7 @@ feature asynch-exceptions : off on : propagated ;
feature extern-c-nothrow : off on : propagated ;
feature debug-symbols : on off : propagated ;
feature define : : free ;
feature undef : : free ;
feature "include" : : free path ; #order-sensitive ;
feature cflags : : free ;
feature cxxflags : : free ;

View File

@@ -387,8 +387,9 @@ rule get-program-files-dir ( )
if [ os.name ] = NT
{
RM = del /f ;
RM = del /f /q ;
CP = copy ;
IGNORE = "2>nul >nul & setlocal" ;
}
else
{
@@ -546,6 +547,14 @@ actions copy
$(CP) "$(>)" "$(<)"
}
rule RmTemps
{
}
actions quietly updated piecemeal together RmTemps
{
$(RM) "$(>)" $(IGNORE)
}
rule __test__ ( ) {
import assert ;

View File

@@ -134,6 +134,9 @@ flags cw.compile CFLAGS <inlining>off : -inline off ;
flags cw.compile CFLAGS <inlining>on : -inline on ;
flags cw.compile CFLAGS <inlining>full : -inline all ;
flags cw.compile CFLAGS <exception-handling>off : -Cpp_exceptions off ;
flags cw.compile CFLAGS <rtti>on : -RTTI on ;
flags cw.compile CFLAGS <rtti>off : -RTTI off ;
flags cw.compile CFLAGS <warnings>on : -w on ;

View File

@@ -17,6 +17,12 @@ import set ;
import common ;
import errors ;
if [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ]
{
.debug-configuration = true ;
}
feature.extend toolset : gcc ;
import unix ;
@@ -28,7 +34,6 @@ generators.override gcc.prebuilt : builtin.prebuilt ;
generators.override gcc.searched-lib-generator : searched-lib-generator ;
# Make the "o" suffix used for gcc toolset on all
# platforms
type.set-generated-target-suffix OBJ : <toolset>gcc : o ;
@@ -58,17 +63,38 @@ rule init ( version ? : command * : options * )
}
init-link-flags gcc $(linker) $(condition) ;
# If gcc is installed in non-standard location, we'd need to
# add LD_LIBRARY_PATH when running programs created with it
# (for unit-test/run rules).
local root = [ feature.get-values <root> : $(options) ] ;
local bin ;
if $(command)
{
local path = [ common.get-absolute-tool-path $(command[-1]) ] ;
local lib_path = $(path:D)/lib ;
flags gcc.link RUN_PATH : $(lib_path) ;
bin ?= [ common.get-absolute-tool-path $(command[-1]) ] ;
root ?= $(bin:D) ;
}
# If gcc is installed in non-standard location, we'd need to
# add LD_LIBRARY_PATH when running programs created with it
# (for unit-test/run rules).
if $(command)
{
local lib_path = $(root)/lib ;
if $(.debug-configuration)
{
ECHO notice: using gcc libraries :: $(condition) :: $(lib_path) ;
}
flags gcc.link RUN_PATH $(condition) : $(lib_path) ;
}
#~ If it's not a system gcc install we should adjust the various
#~ programs as needed to prefer using the install specific versions.
#~ This is essential for correct use of MinGW and for cross-compiling.
local archiver =
[ common.get-invocation-command gcc
: ar : [ feature.get-values <archiver> : $(options) ] : $(bin) : PATH ] ;
flags gcc.archive .AR $(condition) : $(archiver[1]) ;
if $(.debug-configuration)
{
ECHO notice: using gcc archiver :: $(condition) :: $(archiver[1]) ;
}
}
if [ os.name ] = NT
@@ -323,21 +349,38 @@ actions link bind LIBRARIES
}
# Always remove archive and start again. Here's rationale from
# Andre Hentz:
# I had a file, say a1.c, that was included into liba.a.
# I moved a1.c to a2.c, updated my Jamfiles and rebuilt.
# My program was crashing with absurd errors.
# After some debugging I traced it back to the fact that a1.o was *still*
# in liba.a
RM = [ common.rm-command ] ;
flags gcc.archive AROPTIONS <archiveflags> ;
if [ os.name ] = NT
rule archive ( targets * : sources * : properties * )
{
RM = "if exist \"$(<[1])\" DEL \"$(<[1])\"" ;
# Always remove archive and start again. Here's rationale from
#
# Andre Hentz:
#
# I had a file, say a1.c, that was included into liba.a.
# I moved a1.c to a2.c, updated my Jamfiles and rebuilt.
# My program was crashing with absurd errors.
# After some debugging I traced it back to the fact that a1.o was *still*
# in liba.a
#
# Rene Rivera:
#
# Originally removing the archive was done by splicing an RM
# onto the archive action. That makes archives fail to build on NT
# when they have many files because it will no longer execute the
# action directly and blow the line length limit. Instead we
# remove the file in a different action, just before the building
# of the archive.
#
local clean.a = $(targets[1])(clean) ;
TEMPORARY $(clean.a) ;
NOCARE $(clean.a) ;
LOCATE on $(clean.a) = [ on $(targets[1]) return $(LOCATE) ] ;
DEPENDS $(clean.a) : $(sources) ;
DEPENDS $(targets) : $(clean.a) ;
common.RmTemps $(clean.a) : $(targets) ;
}
# Declare action for creating static libraries
# The 'r' letter means to add files to the archive with replacement
# Since we remove archive, we don't care about replacement, but
@@ -347,8 +390,7 @@ if [ os.name ] = NT
# some platforms, for whatever reasons.
actions piecemeal archive
{
$(RM) "$(<)"
ar rc "$(<)" "$(>)"
"$(.AR)" $(AROPTIONS) rc "$(<)" "$(>)"
}

View File

@@ -39,6 +39,19 @@ import toolset : flags ;
project.initialize $(__name__) ;
project python ;
# Save the project so that if 'init' is called several
# times we define new targets in the python project,
# not in whatever project we were called by.
.project = [ project.current ] ;
# Dynamic linker lib. Necessary to specify it explicitly
# on some platforms.
lib dl ;
# This contains 'openpty' function need by python. Again, on
# some system need to pass this to linker explicitly.
lib util ;
# Initializes the Python toolset.
# - version -- the version of Python to use. Should be in Major.Minor format,
# for example 2.3
@@ -57,9 +70,12 @@ project python ;
# using python 2.3 : /usr/local ; # Root specified, include and lib paths
# # will be guessed
#
rule init ( version ? : root ? : includes ? : libraries ? : cygwin-condition ? )
rule init ( version ? : root ? : includes ? : libraries ?
: cygwin-condition * )
{
.configured = true ;
project.push-current $(.project) ;
if [ os.name ] = NT
{
@@ -71,46 +87,64 @@ rule init ( version ? : root ? : includes ? : libraries ? : cygwin-condition ? )
}
else if [ modules.peek : UNIX ]
{
init-unix $(version) : $(root) : $(includes) : $(libraries) ;
init-unix $(version) : $(root) : $(includes) : $(libraries) : $(cygwin-condition) ;
}
project.pop-current ;
}
rule init-unix ( version ? : root ? : includes ? : libraries ? )
rule init-unix ( version ? : root ? : includes ? : libraries ? : condition * )
{
root ?= /usr ;
includes ?= $(root)/include/python$(version) ;
libraries ?= $(root)/lib/python$(version)/config ;
# Find the 'python' binary, which is used for testing.
# Look first in $(root)/bin, then in PATH.
# Look first in $(root)/bin, then in PATH.
local interpreter = [ common.get-invocation-command
python : python : : $(root)/bin : path-last ] ;
if $(interpreter:D) != $(root)/bin
{
ECHO "warning: was expecting Python interpreter in " $(root)/bin ;
ECHO "warning: found only in PATH:" $(interpreter) ;
}
if --debug-configuration in [ modules.peek : ARGV ]
{
ECHO "notice: Python include path is" $(includes) ;
ECHO "notice: Python library path is" $(libraries) ;
ECHO "notice: Python interpreter is" $(interpreter) ;
ECHO "notice: Python interpreter is" $(interpreter) ;
}
flags python.capture-output PYTHON : $(interpreter) ;
# If not specific condition is specified, set global value
# If condition is specified, set PYTHON on target. It will
# override the global value.
if ! $(condition)
{
PYTHON = $(interpreter) ;
}
else
{
flags python.capture-output PYTHON $(condition:J=/) : $(interpreter) ;
}
# On Linux, we don't want to link either Boost.Python or
# Python extensions to libpython, so that when extensions
# loaded in the interpreter, the symbols in the interpreter
# are used. If we linked to libpython, we'd get duplicate
# symbols. So declare two targets -- one for headers and another
# for library.
# for library.
alias python_for_extensions
:
:
:
: $(condition)
:
: <include>$(includes)
;
alias python
:
:
: dl util
: $(condition)
:
: <include>$(includes)
<library-path>$(libraries)

View File

@@ -1,208 +1,17 @@
# 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.
# Copyright (c) 2006 Vladimir Prus.
#
# 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 modules ;
import feature ;
import errors ;
import type ;
import "class" : new ;
import generators ;
import project ;
import toolset : flags ;
# Forwarning toolset file to Qt GUI library. Forwards to the toolset file
# for the current version of Qt.
# Convert this module into a project, so that we can declare
# targets here.
import qt4 ;
project.initialize $(__name__) ;
project qt ;
# Initialized the QT support module. The 'prefix' parameter
# tells where QT is installed. When not given, environmental
# variable QTDIR should be set.
rule init ( prefix ? )
{
if ! $(prefix)
{
prefix = [ modules.peek : QTDIR ] ;
if ! $(prefix)
{
errors.error
"QT installation prefix not given and QTDIR variable is empty" ;
}
}
if $(.initialized)
{
if $(prefix) != $(.prefix)
{
errors.error
"Attempt the reinitialize QT with different installation prefix" ;
}
}
else
{
.initialized = true ;
.prefix = $(prefix) ;
generators.register-standard qt.moc : H : CPP(moc_%) : <allow>qt ;
# Note: the OBJ target type here is fake, take a look
# at qt4.jam/uic-h-generator for explanations that
# apply in this case as well.
generators.register [ new moc-h-generator
qt.moc.cpp : MOCCABLE_CPP : OBJ : <allow>qt ] ;
# The UI type is defined in types/qt.jam,
# and UIC_H is only used in qt.jam, but not in qt4.jam, so
# define it here.
type.register UIC_H : : H ;
generators.register-standard qt.uic-h : UI : UIC_H : <allow>qt ;
# The following generator is used to convert UI files to CPP
# It creates UIC_H from UI, and constructs CPP from UI/UIC_H
# In addition, it also returns UIC_H target, so that it can bee
# mocced.
class qt::uic-cpp-generator : generator
{
rule __init__ ( )
{
generator.__init__ qt.uic-cpp : UI UIC_H : CPP : <allow>qt ;
}
rule run ( project name ? : properties * : sources + )
{
# Consider this:
# obj test : test_a.cpp : <optimization>off ;
#
# This generator will somehow be called in this case, and,
# will fail -- which is okay. However, if there are <library>
# properties they will be converted to sources, so the size of
# 'sources' will be more than 1. In this case, the base generator
# will just crash -- and that's not good. Just use a quick test
# here.
local result ;
if ! $(sources[2])
{
# Construct CPP as usual
result = [ generator.run $(project) $(name)
: $(properties) : $(sources) ] ;
# If OK, process UIC_H with moc. It's pretty clear that
# the object generated with UIC will have Q_OBJECT macro.
if $(result)
{
local action = [ $(result[1]).action ] ;
local sources = [ $(action).sources ] ;
local mocced = [ generators.construct $(project) $(name)
: CPP : $(properties) : $(sources[2]) ] ;
result += $(mocced[2-]) ;
}
}
return $(result) ;
}
}
generators.register [ new qt::uic-cpp-generator ] ;
# Finally, declare prebuilt target for QT library.
local usage-requirements =
<include>$(.prefix)/include
<dll-path>$(.prefix)/lib
<library-path>$(.prefix)/lib
<allow>qt
;
lib qt : : <name>qt-mt <threading>multi : : $(usage-requirements) ;
lib qt : : <name>qt <threading>single : : $(usage-requirements) ;
}
}
class moc-h-generator : generator
{
rule __init__ ( * : * )
{
generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
}
rule run ( project name ? : property-set : sources * )
{
if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP
{
name = [ $(sources[1]).name ] ;
name = $(name:B) ;
local a = [ new action $(sources[1]) : qt.moc.cpp :
$(property-set) ] ;
local target = [
new file-target $(name) : MOC : $(project) : $(a) ] ;
local r = [ virtual-target.register $(target) ] ;
# Since this generator will return H target, the linking generator
# won't use it at all, and won't set any dependency on it.
# However, we need to target to be seen by bjam, so that dependency
# from sources to this generated header is detected -- if jam does
# not know about this target, it won't do anything.
DEPENDS all : [ $(r).actualize ] ;
return $(r) ;
}
}
}
# Query the installation directory
# This is needed in at least two scenarios
# First, when re-using sources from the Qt-Tree.
# Second, to "install" custom Qt plugins to the Qt-Tree.
rule directory
{
return $(.prefix) ;
}
# -f forces moc to include the processed source file.
# Without it, it would think that .qpp is not a header and would not
# include it from the generated file.
actions moc
{
$(.prefix)/bin/moc -f $(>) -o $(<)
}
# When moccing .cpp files, we don't need -f, otherwise generated
# code will include .cpp and we'll get duplicated symbols.
actions moc.cpp
{
$(.prefix)/bin/moc $(>) -o $(<)
}
space = " " ;
# Sometimes it's required to make 'plugins' available during
# uic invocation. To help with this we add paths to all dependency
# libraries to uic commane line. The intention is that it's possible
# to write
#
# exe a : ... a.ui ... : <uses>some_plugin ;
#
# and have everything work. We'd add quite a bunch of unrelated paths
# but it won't hurt.
flags qt.uic-h LIBRARY_PATH <xdll-path> ;
actions uic-h
{
$(.prefix)/bin/uic $(>) -o $(<) -L$(space)$(LIBRARY_PATH)
}
flags qt.uic-cpp LIBRARY_PATH <xdll-path> ;
# The second target is uic-generated header name. It's placed in
# build dir, but we want to include it using only basename.
actions uic-cpp
{
$(.prefix)/bin/uic $(>[1]) -i $(>[2]:D=) -o $(<) -L$(space)$(LIBRARY_PATH)
qt4.init $(prefix) ;
}

213
v2/tools/qt3.jam Normal file
View File

@@ -0,0 +1,213 @@
# 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.
# Support for the Qt GUI library version 3
# (http://www.trolltech.com/products/qt3/index.html).
# For new developments, it's recommented to use Qt4 via the qt4
# Boost.Build module.
import modules ;
import feature ;
import errors ;
import type ;
import "class" : new ;
import generators ;
import project ;
import toolset : flags ;
# Convert this module into a project, so that we can declare
# targets here.
project.initialize $(__name__) ;
project qt3 ;
# Initialized the QT support module. The 'prefix' parameter
# tells where QT is installed. When not given, environmental
# variable QTDIR should be set.
rule init ( prefix ? )
{
if ! $(prefix)
{
prefix = [ modules.peek : QTDIR ] ;
if ! $(prefix)
{
errors.error
"QT installation prefix not given and QTDIR variable is empty" ;
}
}
if $(.initialized)
{
if $(prefix) != $(.prefix)
{
errors.error
"Attempt the reinitialize QT with different installation prefix" ;
}
}
else
{
.initialized = true ;
.prefix = $(prefix) ;
generators.register-standard qt.moc : H : CPP(moc_%) : <allow>qt ;
# Note: the OBJ target type here is fake, take a look
# at qt4.jam/uic-h-generator for explanations that
# apply in this case as well.
generators.register [ new moc-h-generator
qt.moc.cpp : MOCCABLE_CPP : OBJ : <allow>qt ] ;
# The UI type is defined in types/qt.jam,
# and UIC_H is only used in qt.jam, but not in qt4.jam, so
# define it here.
type.register UIC_H : : H ;
generators.register-standard qt.uic-h : UI : UIC_H : <allow>qt ;
# The following generator is used to convert UI files to CPP
# It creates UIC_H from UI, and constructs CPP from UI/UIC_H
# In addition, it also returns UIC_H target, so that it can bee
# mocced.
class qt::uic-cpp-generator : generator
{
rule __init__ ( )
{
generator.__init__ qt.uic-cpp : UI UIC_H : CPP : <allow>qt ;
}
rule run ( project name ? : properties * : sources + )
{
# Consider this:
# obj test : test_a.cpp : <optimization>off ;
#
# This generator will somehow be called in this case, and,
# will fail -- which is okay. However, if there are <library>
# properties they will be converted to sources, so the size of
# 'sources' will be more than 1. In this case, the base generator
# will just crash -- and that's not good. Just use a quick test
# here.
local result ;
if ! $(sources[2])
{
# Construct CPP as usual
result = [ generator.run $(project) $(name)
: $(properties) : $(sources) ] ;
# If OK, process UIC_H with moc. It's pretty clear that
# the object generated with UIC will have Q_OBJECT macro.
if $(result)
{
local action = [ $(result[1]).action ] ;
local sources = [ $(action).sources ] ;
local mocced = [ generators.construct $(project) $(name)
: CPP : $(properties) : $(sources[2]) ] ;
result += $(mocced[2-]) ;
}
}
return $(result) ;
}
}
generators.register [ new qt::uic-cpp-generator ] ;
# Finally, declare prebuilt target for QT library.
local usage-requirements =
<include>$(.prefix)/include
<dll-path>$(.prefix)/lib
<library-path>$(.prefix)/lib
<allow>qt
;
lib qt : : <name>qt-mt <threading>multi : : $(usage-requirements) ;
lib qt : : <name>qt <threading>single : : $(usage-requirements) ;
}
}
class moc-h-generator : generator
{
rule __init__ ( * : * )
{
generator.__init__ $(1) : $(2) : $(3) : $(4) : $(5) : $(6) : $(7) : $(8) : $(9) ;
}
rule run ( project name ? : property-set : sources * )
{
if ! $(sources[2]) && [ $(sources[1]).type ] = MOCCABLE_CPP
{
name = [ $(sources[1]).name ] ;
name = $(name:B) ;
local a = [ new action $(sources[1]) : qt.moc.cpp :
$(property-set) ] ;
local target = [
new file-target $(name) : MOC : $(project) : $(a) ] ;
local r = [ virtual-target.register $(target) ] ;
# Since this generator will return H target, the linking generator
# won't use it at all, and won't set any dependency on it.
# However, we need to target to be seen by bjam, so that dependency
# from sources to this generated header is detected -- if jam does
# not know about this target, it won't do anything.
DEPENDS all : [ $(r).actualize ] ;
return $(r) ;
}
}
}
# Query the installation directory
# This is needed in at least two scenarios
# First, when re-using sources from the Qt-Tree.
# Second, to "install" custom Qt plugins to the Qt-Tree.
rule directory
{
return $(.prefix) ;
}
# -f forces moc to include the processed source file.
# Without it, it would think that .qpp is not a header and would not
# include it from the generated file.
actions moc
{
$(.prefix)/bin/moc -f $(>) -o $(<)
}
# When moccing .cpp files, we don't need -f, otherwise generated
# code will include .cpp and we'll get duplicated symbols.
actions moc.cpp
{
$(.prefix)/bin/moc $(>) -o $(<)
}
space = " " ;
# Sometimes it's required to make 'plugins' available during
# uic invocation. To help with this we add paths to all dependency
# libraries to uic commane line. The intention is that it's possible
# to write
#
# exe a : ... a.ui ... : <uses>some_plugin ;
#
# and have everything work. We'd add quite a bunch of unrelated paths
# but it won't hurt.
flags qt.uic-h LIBRARY_PATH <xdll-path> ;
actions uic-h
{
$(.prefix)/bin/uic $(>) -o $(<) -L$(space)$(LIBRARY_PATH)
}
flags qt.uic-cpp LIBRARY_PATH <xdll-path> ;
# The second target is uic-generated header name. It's placed in
# build dir, but we want to include it using only basename.
actions uic-cpp
{
$(.prefix)/bin/uic $(>[1]) -i $(>[2]:D=) -o $(<) -L$(space)$(LIBRARY_PATH)
}

View File

@@ -46,23 +46,12 @@ import os ;
import virtual-target ;
project.initialize $(__name__) ;
project qt4 ;
project qt ;
# Initialized the QT support module. The 'prefix' parameter
# tells where QT is installed. When not given, environmental
# variable QTDIR should be set.
rule init ( prefix ? )
# tells where QT is installed.
rule init ( prefix )
{
if ! $(prefix)
{
prefix = [ modules.peek : QTDIR ] ;
if ! $(prefix)
{
errors.error
"QT installation prefix not given and QTDIR variable is empty" ;
}
}
if $(.initialized)
{
if $(prefix) != $(.prefix)