mirror of
https://github.com/boostorg/build.git
synced 2026-02-17 01:32:12 +00:00
sane-testing merged
[SVN r16674]
This commit is contained in:
381
testing.jam
381
testing.jam
@@ -6,23 +6,13 @@ if ! $(.testing.jam-included)
|
||||
{
|
||||
.testing.jam-included = "}" ; # The brace makes emacs indentation happy
|
||||
|
||||
#######################################################################################
|
||||
# Tests generate a number of files reflecting their status in the subvariant-directory
|
||||
#
|
||||
# <test-name>.test - a marker so that Jam knows when it needs to be
|
||||
# rebuilt. It will contain the paths from this
|
||||
# directory to the source files used for the test
|
||||
#
|
||||
# <test-name>.success - present only if the test last succeeded.
|
||||
# Contains the string "succeeded"
|
||||
#
|
||||
# <test-name>.failure - present only if the test last failed. Contains the string
|
||||
# "failed".
|
||||
#
|
||||
# <test-name>.output - contains the output of the test if it was a run test.
|
||||
#######################################################################################
|
||||
|
||||
|
||||
local rule get-var-value ( name + )
|
||||
{
|
||||
# ECHO $(name) ;
|
||||
# ECHO $($(name)) ;
|
||||
return $($(name)) ;
|
||||
}
|
||||
|
||||
# Declares a test target. If name is not supplied, it is taken from the name of
|
||||
# the first source file, sans extension and directory path.
|
||||
@@ -32,161 +22,108 @@ if ! $(.testing.jam-included)
|
||||
# RETURNS the name(s) of the generated test target(s).
|
||||
rule boost-test ( sources + : target-type : requirements * : test-name ? )
|
||||
{
|
||||
local result ;
|
||||
if ! $(gIN_LIB_INCLUDE) # No need to execute this code twice
|
||||
{
|
||||
# manufacture a test name if none supplied explicitly
|
||||
test-name ?= $(sources[1]:D=:S=) ;
|
||||
local result ;
|
||||
{
|
||||
# manufacture a test name if none supplied explicitly
|
||||
test-name ?= $(sources[1]:D=:S=) ;
|
||||
|
||||
# Make sure that targets don't become part of "all"
|
||||
local gSUPPRESS_FAKE_TARGETS = true ;
|
||||
|
||||
result = [
|
||||
declare-local-target $(test-name)
|
||||
: $(sources)
|
||||
: $(requirements) <sysinclude>$(BOOST_ROOT)
|
||||
: # default build
|
||||
: $(target-type)
|
||||
] ;
|
||||
|
||||
if $(result) in $(.all-boost-tests)
|
||||
{
|
||||
EXIT boost-test \"$(result)\" declared twice ;
|
||||
.all-boost-tests += $(result) ;
|
||||
}
|
||||
|
||||
if ( --dump-tests in $(ARGV) )
|
||||
{
|
||||
local srcs = [ on $(result) get-var-value source-files ] ;
|
||||
local source-files ;
|
||||
for local s in $(srcs)
|
||||
{
|
||||
source-files += [
|
||||
SEARCH_FOR_TARGET $(s:G=)
|
||||
: [ on $(s) get-var-value LOCATE SEARCH ]
|
||||
] ;
|
||||
}
|
||||
|
||||
# Make sure that targets don't become part of "all"
|
||||
local gSUPPRESS_FAKE_TARGETS = true ;
|
||||
ECHO "(boost-test" \"$(test-name)\" ":" \"$(source-files)\" ")" ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
local dependencies = [ select-gristed $(sources) ] ;
|
||||
local source-files = [ select-ungristed $(sources) ] ;
|
||||
result = [
|
||||
declare-local-target $(test-name)
|
||||
: $(source-files) $(dependencies) # sources
|
||||
: $(requirements) <sysinclude>$(BOOST_ROOT) # requirements
|
||||
: # default build
|
||||
: $(target-type)
|
||||
] ;
|
||||
Clean clean : $(result) ;
|
||||
|
||||
# make NOTFILE targets of the same base name as the sources which can
|
||||
# be used to build a single test.
|
||||
type-DEPENDS $(sources:B:S=) : $(result) ;
|
||||
|
||||
# The NOTFILE target called "test" builds all tests
|
||||
type-DEPENDS test : $(result) ;
|
||||
|
||||
# Make sure the test result doesn't hang around if the test fails
|
||||
RMOLD $(result) ;
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
Clean clean : $(result) ;
|
||||
|
||||
# make NOTFILE targets of the same base name as the sources which can
|
||||
# be used to build a single test.
|
||||
type-DEPENDS $(sources:B:S=) : $(result) ;
|
||||
|
||||
# The NOTFILE target called "test" builds all tests
|
||||
type-DEPENDS test : $(result) ;
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
#######
|
||||
|
||||
BOOST_TEST_SUFFIX ?= .test ;
|
||||
|
||||
# Set a variable which says how to dump a file to stdout
|
||||
if $(NT)
|
||||
{
|
||||
CATENATE = type ;
|
||||
}
|
||||
else
|
||||
{
|
||||
CATENATE = cat ;
|
||||
}
|
||||
|
||||
actions **passed** bind source-files
|
||||
{
|
||||
echo $(source-files) > $(<)
|
||||
}
|
||||
|
||||
actions (failed-as-expected)
|
||||
{
|
||||
echo failed as expected > $(<)
|
||||
}
|
||||
|
||||
# a utility rule which causes test-file to be built successfully only if
|
||||
# dependency fails to build. Used for expected-failure tests.
|
||||
rule failed-test-file ( test-file : dependency + )
|
||||
{
|
||||
catenate-output-on-failure $(test-file) : $(dependency[1]) ;
|
||||
DEPENDS $(test-file) : $(dependency) ;
|
||||
NOCARE $(dependency) ;
|
||||
TEMPORARY $(dependency) ;
|
||||
local grist = [ MATCH ^<(.*)> : $(dependency:G) ] ;
|
||||
local marker = $(dependency:G=$(grist)*fail) ;
|
||||
(failed-as-expected) $(marker) ;
|
||||
FAIL_EXPECTED $(dependency) ;
|
||||
MakeLocate $(marker) : $(LOCATE_TARGET) ;
|
||||
RMOLD $(marker) ;
|
||||
DEPENDS $(marker) : $(dependency) ;
|
||||
|
||||
succeeded-test-file $(test-file) : $(marker) ;
|
||||
}
|
||||
|
||||
# a utility rule which causes test-file to be built successfully only if
|
||||
# dependency builds. Used for expected-success tests.
|
||||
rule succeeded-test-file ( test-file : dependency + )
|
||||
{
|
||||
catenate-output-on-failure $(test-file) : $(dependency[1]) ;
|
||||
**passed** $(test-file) ;
|
||||
DEPENDS $(test-file) : $(dependency) ;
|
||||
NOCARE $(dependency) ;
|
||||
TEMPORARY $(dependency) ;
|
||||
}
|
||||
|
||||
rule catenate-output-on-failure ( test-file : dependency )
|
||||
{
|
||||
if $(gTEST_OUTPUT_FILE($(dependency)))
|
||||
{
|
||||
output-file on $(test-file) = $(gTEST_OUTPUT_FILE($(dependency))) ;
|
||||
}
|
||||
}
|
||||
|
||||
if $(NT)
|
||||
{
|
||||
CATENATE1 = "if exist \"" ;
|
||||
CATENATE2 = "\" ( ECHO *** output file follows ***
|
||||
type \"" ;
|
||||
CATENATE3 = "\"
|
||||
ECHO *** end of output file *** )" ;
|
||||
|
||||
actions failed-test-file bind output-file source-files
|
||||
{
|
||||
echo "$(source-files)" > $(<:S=.test)
|
||||
if EXIST "$(>)". (
|
||||
if EXIST "$(<:S=.success)". del /f/q "$(<:S=.success)".
|
||||
echo "failed" > "$(<:S=.failure)"
|
||||
|
||||
$(CATENATE1)$(output-file)$(CATENATE2)$(output-file)$(CATENATE3)
|
||||
echo *
|
||||
echo ***************** failed above test: $(<:B:S=) ********************
|
||||
echo *
|
||||
) ELSE (
|
||||
if EXIST "$(<:S=.failure)". del /f/q "$(<:S=.failure)".
|
||||
echo succeeded > "$(<:S=.success)"
|
||||
)
|
||||
}
|
||||
|
||||
actions succeeded-test-file bind output-file source-files
|
||||
{
|
||||
echo "$(source-files)" > $(<:S=.test)
|
||||
if EXIST "$(>)". (
|
||||
if EXIST "$(<:S=.failure)". del /f/q "$(<:S=.failure)".
|
||||
echo succeeded > "$(<:S=.success)"
|
||||
) ELSE (
|
||||
if EXIST "$(<:S=.success)". del /f/q "$(<:S=.success)".
|
||||
echo failed > "$(<:S=.failure)"
|
||||
|
||||
$(CATENATE1)$(output-file)$(CATENATE2)$(output-file)$(CATENATE3)
|
||||
echo *
|
||||
echo ***************** failed above test: $(<:B:S=) ********************
|
||||
echo *
|
||||
)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CATENATE = "cat " ;
|
||||
CATENATE1 = "if [ -f \"" ;
|
||||
CATENATE2 = "\" ] ; then
|
||||
echo *** output file follows ***
|
||||
cat \"" ;
|
||||
CATENATE3 = "\" ; echo *** end of output file ***
|
||||
fi" ;
|
||||
|
||||
actions failed-test-file bind output-file source-files
|
||||
{
|
||||
echo "$(source-files)" > $(<:S=.test)
|
||||
if [ -f "$(>)" ] ; then
|
||||
if [ -f "$(<:S=.success)" ] ; then
|
||||
$(RM) "$(<:S=.success)"
|
||||
fi
|
||||
echo "failed" > $(<:S=.failure)
|
||||
$(CATENATE1)$(output-file)$(CATENATE2)$(output-file)$(CATENATE3)
|
||||
echo "*"
|
||||
echo "***************** failed above test: $(<:B:S=) ********************"
|
||||
echo "*"
|
||||
else
|
||||
if [ -f "$(<:S=.failure)" ] ; then
|
||||
$(RM) "$(<:S=.failure)"
|
||||
fi
|
||||
echo "succeeded" > "$(<:S=.success)"
|
||||
fi
|
||||
}
|
||||
|
||||
actions succeeded-test-file bind output-file source-files
|
||||
{
|
||||
echo "$(source-files)" > "$(<:S=.test)"
|
||||
if [ -f "$(>)" ] ; then
|
||||
if [ -f "$(<:S=.failure)" ] ; then
|
||||
$(RM) "$(<:S=.failure)"
|
||||
fi
|
||||
echo "succeeded" > "$(<:S=.success)"
|
||||
else
|
||||
if [ -f "$(<:S=.success)" ] ; then
|
||||
$(RM) "$(<:S=.success)"
|
||||
fi
|
||||
echo "failed" > "$(<:S=.failure)"
|
||||
$(CATENATE1)$(output-file)$(CATENATE2)$(output-file)$(CATENATE3)
|
||||
echo "*"
|
||||
echo "***************** failed above test: $(<:B:S=) ********************"
|
||||
echo "*"
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
rule declare-build-succeed-test ( test-type : dependency-type )
|
||||
@@ -206,13 +143,6 @@ rule declare-build-fail-test ( test-type : dependency-type )
|
||||
SUF$(test-type) = $(BOOST_TEST_SUFFIX) ;
|
||||
}
|
||||
|
||||
# A temporary measure in case people don't rebuild their Jam
|
||||
# executables. Define the builtin RMOLD if it's missing.
|
||||
if ! ( RMOLD in [ RULENAMES ] )
|
||||
{
|
||||
rule RMOLD { }
|
||||
}
|
||||
|
||||
# When the appropriate generator function is bound to the
|
||||
# test-file-generator argument, this is a target generator function
|
||||
# for target types declared with declare-build-succeed-test and
|
||||
@@ -233,9 +163,9 @@ rule build-test ( test-file-generator test-file + : sources + : requirements * )
|
||||
# file.
|
||||
source-files on $(test-file) = $(sources) ;
|
||||
|
||||
# Make sure that the dependency is erased, so as not to give a
|
||||
# false indication of success.
|
||||
RMOLD $(dependency) ;
|
||||
# Make sure that the test-file is erased upon failure, so as not
|
||||
# to give a false indication of success.
|
||||
RMOLD $(test-file) ;
|
||||
|
||||
# Call dependency-type's generator function to attempt the build
|
||||
local ignored = [
|
||||
@@ -244,18 +174,17 @@ rule build-test ( test-file-generator test-file + : sources + : requirements * )
|
||||
# Generator functions don't handle this job for us; perhaps they should.
|
||||
set-target-variables $(dependency) ;
|
||||
|
||||
if $(test-file:S) != $(BOOST_TEST_SUFFIX)
|
||||
{
|
||||
EXIT unexpected test file suffix. Filename: $(test-file) ;
|
||||
}
|
||||
|
||||
# The test files go with the other subvariant targets
|
||||
local test-files = $(test-file:S=.test) $(test-file:S=.success) $(test-file:S=.failure) ;
|
||||
MakeLocate $(test-files) : $(LOCATE_TARGET) ;
|
||||
Clean clean : $(test-files) ;
|
||||
MakeLocate $(test-file) : $(LOCATE_TARGET) ;
|
||||
Clean clean : $(test-file) ;
|
||||
|
||||
# Generate the test file
|
||||
$(test-file-generator) $(test-file) : $(dependency) ;
|
||||
|
||||
if $(RUN_ALL_TESTS)
|
||||
{
|
||||
ALWAYS $(test-file) ;
|
||||
}
|
||||
}
|
||||
|
||||
### Rules for testing whether a file compiles ###
|
||||
@@ -283,8 +212,10 @@ rule compile-fail ( sources + : requirements * : test-name ? )
|
||||
|
||||
gGENERATOR_FUNCTION(RUN_TEST) = run-test ;
|
||||
SUFRUN_TEST = .run ;
|
||||
rule run-test ( target : sources + : requirements * )
|
||||
rule run-test ( run-target : sources + : requirements * )
|
||||
{
|
||||
local top-target = $(target) ;
|
||||
local target = $(run-target) ;
|
||||
local executable = $(target:S=$(SUFEXE)) ;
|
||||
|
||||
local parent = $(target:S=.test) ;
|
||||
@@ -292,8 +223,29 @@ rule run-test ( target : sources + : requirements * )
|
||||
gRUN_LD_LIBRARY_PATH($(executable)) = $(gRUN_LD_LIBRARY_PATH($(parent))) ;
|
||||
gRUN_PATH($(executable)) = $(gRUN_PATH($(parent))) ;
|
||||
|
||||
executable-file $(executable) : $(sources) : $(requirements) ;
|
||||
set-target-variables $(executable) ;
|
||||
local depends = $(gTARGET_DEPS($(top-target))) ;
|
||||
local libs dlls ;
|
||||
{
|
||||
# Protect target variables against modification while lib dependencies
|
||||
# are built. They will be made empty here, and restored when this scope exits
|
||||
local $(gTARGET_VARIABLES) ;
|
||||
|
||||
# extract the simple properties from dependent-properties
|
||||
local simple-properties = $(gBUILD_PROPERTIES) ;
|
||||
segregate-free-properties simple-properties ;
|
||||
|
||||
# generate library build instructions
|
||||
local BUILD = $(BUILD) ;
|
||||
BUILD ?= $(gTARGET_DEFAULT_BUILD($(target))) ;
|
||||
libs = [ link-libraries [ get-values <$(STATIC_TYPES)> : $(depends) ]
|
||||
: $(toolset) $(variant) : $(simple-properties) ] ;
|
||||
dlls = [ link-libraries [ get-values <$(SHARED_TYPES)> : $(depends) ]
|
||||
: $(toolset) $(variant) : $(simple-properties) ] ;
|
||||
}
|
||||
depend-on-libraries $(executable) : $(libs) ;
|
||||
depend-on-dlls $(executable) : $(dlls) ;
|
||||
executable-file $(executable) : $(sources) : $(requirements) ;
|
||||
|
||||
# The .test file goes with the other subvariant targets
|
||||
# normalization is a hack to get the slashes going the right way on Windoze
|
||||
@@ -311,47 +263,72 @@ rule capture-run-output ( target : executable + )
|
||||
{
|
||||
gTEST_OUTPUT_FILE($(target)) = $(target:S=.output) ;
|
||||
INCLUDES $(target) : $(target:S=.output) ;
|
||||
MakeLocate $(test-file:S=.failure) : $(LOCATE_TARGET) ;
|
||||
MakeLocate $(test-file:S=.output) : $(LOCATE_TARGET) ;
|
||||
Clean clean $(test-file:S=.output) ;
|
||||
capture-run-output1 $(target) : $(executable) ;
|
||||
}
|
||||
|
||||
rule capture-run-output1 ( target : executable )
|
||||
if $(NT)
|
||||
{
|
||||
output-file on $(target) = $(target:S=.output) ;
|
||||
local targets = $(target) $(target:S=.output) ;
|
||||
|
||||
RUN_PATH on $(targets) = [ join $(gRUN_PATH($(executable))) : $(SPLITPATH) ] ;
|
||||
if $(UNIX)
|
||||
{
|
||||
RUN_LD_LIBRARY_PATH on $(targets) = [ join $(gRUN_LD_LIBRARY_PATH($(executable))) : $(SPLITPATH) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if $(UNIX)
|
||||
{
|
||||
actions capture-run-output1 bind INPUT_FILES output-file
|
||||
{
|
||||
$(SHELL_SET)PATH=$(RUN_PATH:J=:):$PATH
|
||||
$(SHELL_EXPORT)PATH
|
||||
$(SHELL_SET)LD_LIBRARY_PATH=$(RUN_LD_LIBRARY_PATH):$LD_LIBRARY_PATH
|
||||
$(SHELL_EXPORT)LD_LIBRARY_PATH
|
||||
$(>) $(ARGS) $(INPUT_FILES) > $(output-file) 2>&1 && $(CP) $(output-file) $(<[1])
|
||||
}
|
||||
ENV_PATH = %PATH% ;
|
||||
CATENATE = type ;
|
||||
}
|
||||
else
|
||||
{
|
||||
actions capture-run-output1 bind INPUT_FILES output-file
|
||||
{
|
||||
$(SHELL_SET)PATH=$(RUN_PATH:J=;);%PATH%
|
||||
$(SHELL_EXPORT)PATH
|
||||
$(>) $(ARGS) $(INPUT_FILES) > $(output-file) 2>&1 && $(CP) $(output-file) $(<[1])
|
||||
}
|
||||
ENV_PATH = $PATH ;
|
||||
ENV_LD_LIBRARY_PATH = $LD_LIBRARY_PATH ;
|
||||
CATENATE = cat ;
|
||||
}
|
||||
|
||||
rule capture-run-output1 ( target : executable )
|
||||
{
|
||||
output-file on $(target) = $(target:S=.output) ;
|
||||
|
||||
# Make sure no confusing output about setting or exporting PATH or
|
||||
# LD_LIBRARY_PATH is seen unless it is actually used.
|
||||
local p = $(gRUN_PATH($(executable))) ;
|
||||
if $(p)
|
||||
{
|
||||
RUN_PATH on $(target) = $(p) $(ENV_PATH) ;
|
||||
PATH_VAR on $(target) = PATH ;
|
||||
}
|
||||
else
|
||||
{
|
||||
RUN_PATH on $(target) = ;
|
||||
PATH_VAR on $(target) = ;
|
||||
}
|
||||
|
||||
p = $(gRUN_LD_LIBRARY_PATH($(executable))) ;
|
||||
if $(NT)
|
||||
{
|
||||
RUN_LD_LIBRARY_PATH on $(target) = ;
|
||||
LD_LIBRARY_PATH_VAR on $(target) = ;
|
||||
}
|
||||
else if $(p)
|
||||
{
|
||||
RUN_LD_LIBRARY_PATH on $(target) = $(p) $(ENV_LD_LIBRARY_PATH) ;
|
||||
LD_LIBRARY_PATH_VAR on $(target) = LD_LIBRARY_PATH ;
|
||||
}
|
||||
execute-test $(target) : $(executable) ;
|
||||
}
|
||||
|
||||
RUN_OUTPUT_HEADER = "echo ====== BEGIN OUTPUT ====== &&" ;
|
||||
RUN_OUTPUT_FOOTER = " && echo ====== END OUTPUT ======" ;
|
||||
if --verbose-test in $(ARGV)
|
||||
{
|
||||
VERBOSE_CAT = "&& "$(RUN_OUTPUT_HEADER)" "$(CATENATE)" " ;
|
||||
}
|
||||
|
||||
actions execute-test bind INPUT_FILES output-file
|
||||
{
|
||||
$(SHELL_SET)PATH=$(RUN_PATH:J=$(SPLITPATH))
|
||||
$(SHELL_EXPORT)$(PATH_VAR)
|
||||
$(SHELL_SET)LD_LIBRARY_PATH=$(RUN_LD_LIBRARY_PATH:J=$(SPLITPATH))
|
||||
$(SHELL_EXPORT)$(LD_LIBRARY_PATH_VAR)
|
||||
$(>) $(ARGS) $(INPUT_FILES) > $(output-file) 2>&1 && $(CP) $(output-file) $(<) $(VERBOSE_CAT)$(<)$(RUN_OUTPUT_FOOTER) || ( $(RUN_OUTPUT_HEADER) $(CATENATE) $(output-file) $(RUN_OUTPUT_FOOTER) && exit 1 )
|
||||
}
|
||||
|
||||
|
||||
declare-build-fail-test RUN_FAIL : RUN_TEST ;
|
||||
declare-build-succeed-test RUN : RUN_TEST ;
|
||||
rule run ( sources + : args * : input-files * : requirements * : name ? )
|
||||
@@ -378,6 +355,12 @@ rule link-fail ( sources + : requirements * : name ? )
|
||||
return [ boost-test $(<) : LINK_FAIL : $(2) : $(name) ] ;
|
||||
}
|
||||
|
||||
declare-build-succeed-test LINK : EXE ;
|
||||
rule link ( sources + : requirements * : name ? )
|
||||
{
|
||||
return [ boost-test $(<) : LINK : $(2) : $(name) ] ;
|
||||
}
|
||||
|
||||
### Rules for grouping tests into suites:
|
||||
|
||||
rule test-suite # pseudotarget-name : test-targets...
|
||||
|
||||
381
v1/testing.jam
381
v1/testing.jam
@@ -6,23 +6,13 @@ if ! $(.testing.jam-included)
|
||||
{
|
||||
.testing.jam-included = "}" ; # The brace makes emacs indentation happy
|
||||
|
||||
#######################################################################################
|
||||
# Tests generate a number of files reflecting their status in the subvariant-directory
|
||||
#
|
||||
# <test-name>.test - a marker so that Jam knows when it needs to be
|
||||
# rebuilt. It will contain the paths from this
|
||||
# directory to the source files used for the test
|
||||
#
|
||||
# <test-name>.success - present only if the test last succeeded.
|
||||
# Contains the string "succeeded"
|
||||
#
|
||||
# <test-name>.failure - present only if the test last failed. Contains the string
|
||||
# "failed".
|
||||
#
|
||||
# <test-name>.output - contains the output of the test if it was a run test.
|
||||
#######################################################################################
|
||||
|
||||
|
||||
local rule get-var-value ( name + )
|
||||
{
|
||||
# ECHO $(name) ;
|
||||
# ECHO $($(name)) ;
|
||||
return $($(name)) ;
|
||||
}
|
||||
|
||||
# Declares a test target. If name is not supplied, it is taken from the name of
|
||||
# the first source file, sans extension and directory path.
|
||||
@@ -32,161 +22,108 @@ if ! $(.testing.jam-included)
|
||||
# RETURNS the name(s) of the generated test target(s).
|
||||
rule boost-test ( sources + : target-type : requirements * : test-name ? )
|
||||
{
|
||||
local result ;
|
||||
if ! $(gIN_LIB_INCLUDE) # No need to execute this code twice
|
||||
{
|
||||
# manufacture a test name if none supplied explicitly
|
||||
test-name ?= $(sources[1]:D=:S=) ;
|
||||
local result ;
|
||||
{
|
||||
# manufacture a test name if none supplied explicitly
|
||||
test-name ?= $(sources[1]:D=:S=) ;
|
||||
|
||||
# Make sure that targets don't become part of "all"
|
||||
local gSUPPRESS_FAKE_TARGETS = true ;
|
||||
|
||||
result = [
|
||||
declare-local-target $(test-name)
|
||||
: $(sources)
|
||||
: $(requirements) <sysinclude>$(BOOST_ROOT)
|
||||
: # default build
|
||||
: $(target-type)
|
||||
] ;
|
||||
|
||||
if $(result) in $(.all-boost-tests)
|
||||
{
|
||||
EXIT boost-test \"$(result)\" declared twice ;
|
||||
.all-boost-tests += $(result) ;
|
||||
}
|
||||
|
||||
if ( --dump-tests in $(ARGV) )
|
||||
{
|
||||
local srcs = [ on $(result) get-var-value source-files ] ;
|
||||
local source-files ;
|
||||
for local s in $(srcs)
|
||||
{
|
||||
source-files += [
|
||||
SEARCH_FOR_TARGET $(s:G=)
|
||||
: [ on $(s) get-var-value LOCATE SEARCH ]
|
||||
] ;
|
||||
}
|
||||
|
||||
# Make sure that targets don't become part of "all"
|
||||
local gSUPPRESS_FAKE_TARGETS = true ;
|
||||
ECHO "(boost-test" \"$(test-name)\" ":" \"$(source-files)\" ")" ;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
local dependencies = [ select-gristed $(sources) ] ;
|
||||
local source-files = [ select-ungristed $(sources) ] ;
|
||||
result = [
|
||||
declare-local-target $(test-name)
|
||||
: $(source-files) $(dependencies) # sources
|
||||
: $(requirements) <sysinclude>$(BOOST_ROOT) # requirements
|
||||
: # default build
|
||||
: $(target-type)
|
||||
] ;
|
||||
Clean clean : $(result) ;
|
||||
|
||||
# make NOTFILE targets of the same base name as the sources which can
|
||||
# be used to build a single test.
|
||||
type-DEPENDS $(sources:B:S=) : $(result) ;
|
||||
|
||||
# The NOTFILE target called "test" builds all tests
|
||||
type-DEPENDS test : $(result) ;
|
||||
|
||||
# Make sure the test result doesn't hang around if the test fails
|
||||
RMOLD $(result) ;
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
Clean clean : $(result) ;
|
||||
|
||||
# make NOTFILE targets of the same base name as the sources which can
|
||||
# be used to build a single test.
|
||||
type-DEPENDS $(sources:B:S=) : $(result) ;
|
||||
|
||||
# The NOTFILE target called "test" builds all tests
|
||||
type-DEPENDS test : $(result) ;
|
||||
|
||||
return $(result) ;
|
||||
}
|
||||
|
||||
#######
|
||||
|
||||
BOOST_TEST_SUFFIX ?= .test ;
|
||||
|
||||
# Set a variable which says how to dump a file to stdout
|
||||
if $(NT)
|
||||
{
|
||||
CATENATE = type ;
|
||||
}
|
||||
else
|
||||
{
|
||||
CATENATE = cat ;
|
||||
}
|
||||
|
||||
actions **passed** bind source-files
|
||||
{
|
||||
echo $(source-files) > $(<)
|
||||
}
|
||||
|
||||
actions (failed-as-expected)
|
||||
{
|
||||
echo failed as expected > $(<)
|
||||
}
|
||||
|
||||
# a utility rule which causes test-file to be built successfully only if
|
||||
# dependency fails to build. Used for expected-failure tests.
|
||||
rule failed-test-file ( test-file : dependency + )
|
||||
{
|
||||
catenate-output-on-failure $(test-file) : $(dependency[1]) ;
|
||||
DEPENDS $(test-file) : $(dependency) ;
|
||||
NOCARE $(dependency) ;
|
||||
TEMPORARY $(dependency) ;
|
||||
local grist = [ MATCH ^<(.*)> : $(dependency:G) ] ;
|
||||
local marker = $(dependency:G=$(grist)*fail) ;
|
||||
(failed-as-expected) $(marker) ;
|
||||
FAIL_EXPECTED $(dependency) ;
|
||||
MakeLocate $(marker) : $(LOCATE_TARGET) ;
|
||||
RMOLD $(marker) ;
|
||||
DEPENDS $(marker) : $(dependency) ;
|
||||
|
||||
succeeded-test-file $(test-file) : $(marker) ;
|
||||
}
|
||||
|
||||
# a utility rule which causes test-file to be built successfully only if
|
||||
# dependency builds. Used for expected-success tests.
|
||||
rule succeeded-test-file ( test-file : dependency + )
|
||||
{
|
||||
catenate-output-on-failure $(test-file) : $(dependency[1]) ;
|
||||
**passed** $(test-file) ;
|
||||
DEPENDS $(test-file) : $(dependency) ;
|
||||
NOCARE $(dependency) ;
|
||||
TEMPORARY $(dependency) ;
|
||||
}
|
||||
|
||||
rule catenate-output-on-failure ( test-file : dependency )
|
||||
{
|
||||
if $(gTEST_OUTPUT_FILE($(dependency)))
|
||||
{
|
||||
output-file on $(test-file) = $(gTEST_OUTPUT_FILE($(dependency))) ;
|
||||
}
|
||||
}
|
||||
|
||||
if $(NT)
|
||||
{
|
||||
CATENATE1 = "if exist \"" ;
|
||||
CATENATE2 = "\" ( ECHO *** output file follows ***
|
||||
type \"" ;
|
||||
CATENATE3 = "\"
|
||||
ECHO *** end of output file *** )" ;
|
||||
|
||||
actions failed-test-file bind output-file source-files
|
||||
{
|
||||
echo "$(source-files)" > $(<:S=.test)
|
||||
if EXIST "$(>)". (
|
||||
if EXIST "$(<:S=.success)". del /f/q "$(<:S=.success)".
|
||||
echo "failed" > "$(<:S=.failure)"
|
||||
|
||||
$(CATENATE1)$(output-file)$(CATENATE2)$(output-file)$(CATENATE3)
|
||||
echo *
|
||||
echo ***************** failed above test: $(<:B:S=) ********************
|
||||
echo *
|
||||
) ELSE (
|
||||
if EXIST "$(<:S=.failure)". del /f/q "$(<:S=.failure)".
|
||||
echo succeeded > "$(<:S=.success)"
|
||||
)
|
||||
}
|
||||
|
||||
actions succeeded-test-file bind output-file source-files
|
||||
{
|
||||
echo "$(source-files)" > $(<:S=.test)
|
||||
if EXIST "$(>)". (
|
||||
if EXIST "$(<:S=.failure)". del /f/q "$(<:S=.failure)".
|
||||
echo succeeded > "$(<:S=.success)"
|
||||
) ELSE (
|
||||
if EXIST "$(<:S=.success)". del /f/q "$(<:S=.success)".
|
||||
echo failed > "$(<:S=.failure)"
|
||||
|
||||
$(CATENATE1)$(output-file)$(CATENATE2)$(output-file)$(CATENATE3)
|
||||
echo *
|
||||
echo ***************** failed above test: $(<:B:S=) ********************
|
||||
echo *
|
||||
)
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CATENATE = "cat " ;
|
||||
CATENATE1 = "if [ -f \"" ;
|
||||
CATENATE2 = "\" ] ; then
|
||||
echo *** output file follows ***
|
||||
cat \"" ;
|
||||
CATENATE3 = "\" ; echo *** end of output file ***
|
||||
fi" ;
|
||||
|
||||
actions failed-test-file bind output-file source-files
|
||||
{
|
||||
echo "$(source-files)" > $(<:S=.test)
|
||||
if [ -f "$(>)" ] ; then
|
||||
if [ -f "$(<:S=.success)" ] ; then
|
||||
$(RM) "$(<:S=.success)"
|
||||
fi
|
||||
echo "failed" > $(<:S=.failure)
|
||||
$(CATENATE1)$(output-file)$(CATENATE2)$(output-file)$(CATENATE3)
|
||||
echo "*"
|
||||
echo "***************** failed above test: $(<:B:S=) ********************"
|
||||
echo "*"
|
||||
else
|
||||
if [ -f "$(<:S=.failure)" ] ; then
|
||||
$(RM) "$(<:S=.failure)"
|
||||
fi
|
||||
echo "succeeded" > "$(<:S=.success)"
|
||||
fi
|
||||
}
|
||||
|
||||
actions succeeded-test-file bind output-file source-files
|
||||
{
|
||||
echo "$(source-files)" > "$(<:S=.test)"
|
||||
if [ -f "$(>)" ] ; then
|
||||
if [ -f "$(<:S=.failure)" ] ; then
|
||||
$(RM) "$(<:S=.failure)"
|
||||
fi
|
||||
echo "succeeded" > "$(<:S=.success)"
|
||||
else
|
||||
if [ -f "$(<:S=.success)" ] ; then
|
||||
$(RM) "$(<:S=.success)"
|
||||
fi
|
||||
echo "failed" > "$(<:S=.failure)"
|
||||
$(CATENATE1)$(output-file)$(CATENATE2)$(output-file)$(CATENATE3)
|
||||
echo "*"
|
||||
echo "***************** failed above test: $(<:B:S=) ********************"
|
||||
echo "*"
|
||||
fi
|
||||
}
|
||||
}
|
||||
|
||||
rule declare-build-succeed-test ( test-type : dependency-type )
|
||||
@@ -206,13 +143,6 @@ rule declare-build-fail-test ( test-type : dependency-type )
|
||||
SUF$(test-type) = $(BOOST_TEST_SUFFIX) ;
|
||||
}
|
||||
|
||||
# A temporary measure in case people don't rebuild their Jam
|
||||
# executables. Define the builtin RMOLD if it's missing.
|
||||
if ! ( RMOLD in [ RULENAMES ] )
|
||||
{
|
||||
rule RMOLD { }
|
||||
}
|
||||
|
||||
# When the appropriate generator function is bound to the
|
||||
# test-file-generator argument, this is a target generator function
|
||||
# for target types declared with declare-build-succeed-test and
|
||||
@@ -233,9 +163,9 @@ rule build-test ( test-file-generator test-file + : sources + : requirements * )
|
||||
# file.
|
||||
source-files on $(test-file) = $(sources) ;
|
||||
|
||||
# Make sure that the dependency is erased, so as not to give a
|
||||
# false indication of success.
|
||||
RMOLD $(dependency) ;
|
||||
# Make sure that the test-file is erased upon failure, so as not
|
||||
# to give a false indication of success.
|
||||
RMOLD $(test-file) ;
|
||||
|
||||
# Call dependency-type's generator function to attempt the build
|
||||
local ignored = [
|
||||
@@ -244,18 +174,17 @@ rule build-test ( test-file-generator test-file + : sources + : requirements * )
|
||||
# Generator functions don't handle this job for us; perhaps they should.
|
||||
set-target-variables $(dependency) ;
|
||||
|
||||
if $(test-file:S) != $(BOOST_TEST_SUFFIX)
|
||||
{
|
||||
EXIT unexpected test file suffix. Filename: $(test-file) ;
|
||||
}
|
||||
|
||||
# The test files go with the other subvariant targets
|
||||
local test-files = $(test-file:S=.test) $(test-file:S=.success) $(test-file:S=.failure) ;
|
||||
MakeLocate $(test-files) : $(LOCATE_TARGET) ;
|
||||
Clean clean : $(test-files) ;
|
||||
MakeLocate $(test-file) : $(LOCATE_TARGET) ;
|
||||
Clean clean : $(test-file) ;
|
||||
|
||||
# Generate the test file
|
||||
$(test-file-generator) $(test-file) : $(dependency) ;
|
||||
|
||||
if $(RUN_ALL_TESTS)
|
||||
{
|
||||
ALWAYS $(test-file) ;
|
||||
}
|
||||
}
|
||||
|
||||
### Rules for testing whether a file compiles ###
|
||||
@@ -283,8 +212,10 @@ rule compile-fail ( sources + : requirements * : test-name ? )
|
||||
|
||||
gGENERATOR_FUNCTION(RUN_TEST) = run-test ;
|
||||
SUFRUN_TEST = .run ;
|
||||
rule run-test ( target : sources + : requirements * )
|
||||
rule run-test ( run-target : sources + : requirements * )
|
||||
{
|
||||
local top-target = $(target) ;
|
||||
local target = $(run-target) ;
|
||||
local executable = $(target:S=$(SUFEXE)) ;
|
||||
|
||||
local parent = $(target:S=.test) ;
|
||||
@@ -292,8 +223,29 @@ rule run-test ( target : sources + : requirements * )
|
||||
gRUN_LD_LIBRARY_PATH($(executable)) = $(gRUN_LD_LIBRARY_PATH($(parent))) ;
|
||||
gRUN_PATH($(executable)) = $(gRUN_PATH($(parent))) ;
|
||||
|
||||
executable-file $(executable) : $(sources) : $(requirements) ;
|
||||
set-target-variables $(executable) ;
|
||||
local depends = $(gTARGET_DEPS($(top-target))) ;
|
||||
local libs dlls ;
|
||||
{
|
||||
# Protect target variables against modification while lib dependencies
|
||||
# are built. They will be made empty here, and restored when this scope exits
|
||||
local $(gTARGET_VARIABLES) ;
|
||||
|
||||
# extract the simple properties from dependent-properties
|
||||
local simple-properties = $(gBUILD_PROPERTIES) ;
|
||||
segregate-free-properties simple-properties ;
|
||||
|
||||
# generate library build instructions
|
||||
local BUILD = $(BUILD) ;
|
||||
BUILD ?= $(gTARGET_DEFAULT_BUILD($(target))) ;
|
||||
libs = [ link-libraries [ get-values <$(STATIC_TYPES)> : $(depends) ]
|
||||
: $(toolset) $(variant) : $(simple-properties) ] ;
|
||||
dlls = [ link-libraries [ get-values <$(SHARED_TYPES)> : $(depends) ]
|
||||
: $(toolset) $(variant) : $(simple-properties) ] ;
|
||||
}
|
||||
depend-on-libraries $(executable) : $(libs) ;
|
||||
depend-on-dlls $(executable) : $(dlls) ;
|
||||
executable-file $(executable) : $(sources) : $(requirements) ;
|
||||
|
||||
# The .test file goes with the other subvariant targets
|
||||
# normalization is a hack to get the slashes going the right way on Windoze
|
||||
@@ -311,47 +263,72 @@ rule capture-run-output ( target : executable + )
|
||||
{
|
||||
gTEST_OUTPUT_FILE($(target)) = $(target:S=.output) ;
|
||||
INCLUDES $(target) : $(target:S=.output) ;
|
||||
MakeLocate $(test-file:S=.failure) : $(LOCATE_TARGET) ;
|
||||
MakeLocate $(test-file:S=.output) : $(LOCATE_TARGET) ;
|
||||
Clean clean $(test-file:S=.output) ;
|
||||
capture-run-output1 $(target) : $(executable) ;
|
||||
}
|
||||
|
||||
rule capture-run-output1 ( target : executable )
|
||||
if $(NT)
|
||||
{
|
||||
output-file on $(target) = $(target:S=.output) ;
|
||||
local targets = $(target) $(target:S=.output) ;
|
||||
|
||||
RUN_PATH on $(targets) = [ join $(gRUN_PATH($(executable))) : $(SPLITPATH) ] ;
|
||||
if $(UNIX)
|
||||
{
|
||||
RUN_LD_LIBRARY_PATH on $(targets) = [ join $(gRUN_LD_LIBRARY_PATH($(executable))) : $(SPLITPATH) ] ;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if $(UNIX)
|
||||
{
|
||||
actions capture-run-output1 bind INPUT_FILES output-file
|
||||
{
|
||||
$(SHELL_SET)PATH=$(RUN_PATH:J=:):$PATH
|
||||
$(SHELL_EXPORT)PATH
|
||||
$(SHELL_SET)LD_LIBRARY_PATH=$(RUN_LD_LIBRARY_PATH):$LD_LIBRARY_PATH
|
||||
$(SHELL_EXPORT)LD_LIBRARY_PATH
|
||||
$(>) $(ARGS) $(INPUT_FILES) > $(output-file) 2>&1 && $(CP) $(output-file) $(<[1])
|
||||
}
|
||||
ENV_PATH = %PATH% ;
|
||||
CATENATE = type ;
|
||||
}
|
||||
else
|
||||
{
|
||||
actions capture-run-output1 bind INPUT_FILES output-file
|
||||
{
|
||||
$(SHELL_SET)PATH=$(RUN_PATH:J=;);%PATH%
|
||||
$(SHELL_EXPORT)PATH
|
||||
$(>) $(ARGS) $(INPUT_FILES) > $(output-file) 2>&1 && $(CP) $(output-file) $(<[1])
|
||||
}
|
||||
ENV_PATH = $PATH ;
|
||||
ENV_LD_LIBRARY_PATH = $LD_LIBRARY_PATH ;
|
||||
CATENATE = cat ;
|
||||
}
|
||||
|
||||
rule capture-run-output1 ( target : executable )
|
||||
{
|
||||
output-file on $(target) = $(target:S=.output) ;
|
||||
|
||||
# Make sure no confusing output about setting or exporting PATH or
|
||||
# LD_LIBRARY_PATH is seen unless it is actually used.
|
||||
local p = $(gRUN_PATH($(executable))) ;
|
||||
if $(p)
|
||||
{
|
||||
RUN_PATH on $(target) = $(p) $(ENV_PATH) ;
|
||||
PATH_VAR on $(target) = PATH ;
|
||||
}
|
||||
else
|
||||
{
|
||||
RUN_PATH on $(target) = ;
|
||||
PATH_VAR on $(target) = ;
|
||||
}
|
||||
|
||||
p = $(gRUN_LD_LIBRARY_PATH($(executable))) ;
|
||||
if $(NT)
|
||||
{
|
||||
RUN_LD_LIBRARY_PATH on $(target) = ;
|
||||
LD_LIBRARY_PATH_VAR on $(target) = ;
|
||||
}
|
||||
else if $(p)
|
||||
{
|
||||
RUN_LD_LIBRARY_PATH on $(target) = $(p) $(ENV_LD_LIBRARY_PATH) ;
|
||||
LD_LIBRARY_PATH_VAR on $(target) = LD_LIBRARY_PATH ;
|
||||
}
|
||||
execute-test $(target) : $(executable) ;
|
||||
}
|
||||
|
||||
RUN_OUTPUT_HEADER = "echo ====== BEGIN OUTPUT ====== &&" ;
|
||||
RUN_OUTPUT_FOOTER = " && echo ====== END OUTPUT ======" ;
|
||||
if --verbose-test in $(ARGV)
|
||||
{
|
||||
VERBOSE_CAT = "&& "$(RUN_OUTPUT_HEADER)" "$(CATENATE)" " ;
|
||||
}
|
||||
|
||||
actions execute-test bind INPUT_FILES output-file
|
||||
{
|
||||
$(SHELL_SET)PATH=$(RUN_PATH:J=$(SPLITPATH))
|
||||
$(SHELL_EXPORT)$(PATH_VAR)
|
||||
$(SHELL_SET)LD_LIBRARY_PATH=$(RUN_LD_LIBRARY_PATH:J=$(SPLITPATH))
|
||||
$(SHELL_EXPORT)$(LD_LIBRARY_PATH_VAR)
|
||||
$(>) $(ARGS) $(INPUT_FILES) > $(output-file) 2>&1 && $(CP) $(output-file) $(<) $(VERBOSE_CAT)$(<)$(RUN_OUTPUT_FOOTER) || ( $(RUN_OUTPUT_HEADER) $(CATENATE) $(output-file) $(RUN_OUTPUT_FOOTER) && exit 1 )
|
||||
}
|
||||
|
||||
|
||||
declare-build-fail-test RUN_FAIL : RUN_TEST ;
|
||||
declare-build-succeed-test RUN : RUN_TEST ;
|
||||
rule run ( sources + : args * : input-files * : requirements * : name ? )
|
||||
@@ -378,6 +355,12 @@ rule link-fail ( sources + : requirements * : name ? )
|
||||
return [ boost-test $(<) : LINK_FAIL : $(2) : $(name) ] ;
|
||||
}
|
||||
|
||||
declare-build-succeed-test LINK : EXE ;
|
||||
rule link ( sources + : requirements * : name ? )
|
||||
{
|
||||
return [ boost-test $(<) : LINK : $(2) : $(name) ] ;
|
||||
}
|
||||
|
||||
### Rules for grouping tests into suites:
|
||||
|
||||
rule test-suite # pseudotarget-name : test-targets...
|
||||
|
||||
Reference in New Issue
Block a user