2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-15 13:02:11 +00:00

Continuing merge of CMake build system files into trunk with the encouragement of Doug Gregor

[SVN r49510]
This commit is contained in:
Michael A. Jackson
2008-11-01 13:15:41 +00:00
parent 4e3b76d0d6
commit 9780f0a589
19 changed files with 3384 additions and 0 deletions

157
CMake/BoostBuildSlave.cmake Normal file
View File

@@ -0,0 +1,157 @@
##########################################################################
# Boost Build Slave Support #
##########################################################################
# Copyright (C) 2008 Troy D. Straszheim #
# #
# 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 #
##########################################################################
option(BOOST_BUILD_SLAVE "Be a build slave, report build/testing" OFF)
file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}" BOOST_BUILD_SLAVE_PYTHONPATH)
if(BOOST_BUILD_SLAVE)
set(BOOST_BUILD_SLAVE_SUBMIT_URL "http://boost:boost@boost.resophonic.com/trac/login/xmlrpc"
CACHE STRING "URL to post regression testing results to.")
file(TO_NATIVE_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}" BOOST_BUILD_SLAVE_PYTHONPATH)
set(BOOST_BUILD_SLAVE_TIMEOUT 300
CACHE STRING "Seconds until build slave times out any individual build step")
set(BOOST_BUILD_SLAVE_DETAILS_FILE "slave-description.txt"
CACHE FILEPATH "Path to file, absolute or relative to build directory, containing descriptive text about the build (configuration peculiarities, etc) to be reported to the server")
set(BOOST_BUILD_SLAVE_CONTACT_INFO "buildmeister@example.com"
CACHE STRING "Contact information regarding this build")
set(BOOST_BUILD_SLAVE_HOSTNAME ""
CACHE STRING "If set, don't report what python determines to be the FQDN of this host, report this string instead.")
set(BOOST_BUILD_SLAVE_SLEEP_DURATION "60"
CACHE STRING "Number of seconds to sleep between checks for updates from the repository.")
endif(BOOST_BUILD_SLAVE)
message(STATUS "Configuring test/compile drivers")
if(CMAKE_VERBOSE_MAKEFILE)
set(BOOST_DRIVER_VERBOSE True)
else(CMAKE_VERBOSE_MAKEFILE)
set(BOOST_DRIVER_VERBOSE False)
endif(CMAKE_VERBOSE_MAKEFILE)
#
# the programs that do the dirty work.
#
foreach(PYFILE boost_build_slave passthru marshal start finish info post classify)
configure_file(tools/build/CMake/${PYFILE}.py.in
${BOOST_BUILD_SLAVE_PYTHONPATH}/${PYFILE}.py
@ONLY
)
endforeach()
if(WIN32)
configure_file(tools/build/CMake/windows_kill.py.in
${BOOST_BUILD_SLAVE_PYTHONPATH}/kill_subprocess.py
COPYONLY
)
else(WIN32)
configure_file(tools/build/CMake/unix_kill.py.in
${BOOST_BUILD_SLAVE_PYTHONPATH}/kill_subprocess.py
COPYONLY
)
endif(WIN32)
#
# the test driver is either marshal or passthru depending on whether
# you're in build slave mode or not. The compilation/link rules
# aren't modified if you're not in slave mode, BUUUT the tests still
# need a driver script that knows whether to expect failure or not
# and 'flips' the return status accordingly: thus passthru.py.
#
if(BOOST_BUILD_SLAVE)
file(TO_NATIVE_PATH ${BOOST_BUILD_SLAVE_PYTHONPATH}/marshal.py BOOST_TEST_DRIVER)
configure_file(tools/build/CMake/run_continuous_slave.py.in
${CMAKE_BINARY_DIR}/run_continuous_slave.py
@ONLY
)
else(BOOST_BUILD_SLAVE)
file(TO_NATIVE_PATH ${BOOST_BUILD_SLAVE_PYTHONPATH}/passthru.py BOOST_TEST_DRIVER)
endif(BOOST_BUILD_SLAVE)
if(BOOST_BUILD_SLAVE)
#
# Redirect various build steps
#
set(CMAKE_CXX_COMPILE_OBJECT
"\"${PYTHON_EXECUTABLE}\" \"${BOOST_TEST_DRIVER}\" <CMAKE_CURRENT_BINARY_DIR> cxx_compile_object <OBJECT> ${CMAKE_CXX_COMPILE_OBJECT}" )
set(CMAKE_CXX_CREATE_SHARED_LIBRARY
"\"${PYTHON_EXECUTABLE}\" \"${BOOST_TEST_DRIVER}\" <CMAKE_CURRENT_BINARY_DIR> create_shared_library <TARGET> ${CMAKE_CXX_CREATE_SHARED_LIBRARY}")
set(CMAKE_CXX_CREATE_STATIC_LIBRARY
"\"${PYTHON_EXECUTABLE}\" \"${BOOST_TEST_DRIVER}\" <CMAKE_CURRENT_BINARY_DIR> create_static_library <TARGET> ${CMAKE_CXX_CREATE_STATIC_LIBRARY}")
set(CMAKE_CXX_LINK_EXECUTABLE
"\"${PYTHON_EXECUTABLE}\" \"${BOOST_TEST_DRIVER}\" <CMAKE_CURRENT_BINARY_DIR> link_executable <TARGET> ${CMAKE_CXX_LINK_EXECUTABLE}")
#
# Custom targets for talking to the server via xmlrpc
#
#
# Get us a new build id from the server
#
file(TO_NATIVE_PATH ${BOOST_BUILD_SLAVE_PYTHONPATH}/start.py
BOOST_BUILD_SLAVE_START_PY)
add_custom_target(slave-start
COMMAND ${PYTHON_EXECUTABLE} ${BOOST_BUILD_SLAVE_START_PY}
COMMENT "Slave starting build"
)
#
# Tell server we're done... it'll update finish time in the db.
#
file(TO_NATIVE_PATH ${BOOST_BUILD_SLAVE_PYTHONPATH}/finish.py
BOOST_BUILD_SLAVE_FINISH_PY)
add_custom_target(slave-finish
COMMAND ${PYTHON_EXECUTABLE} ${BOOST_BUILD_SLAVE_FINISH_PY}
COMMENT "Slave finishing build"
)
#
# Local only: show what we report to server (our platform description, toolset, etc)
#
file(TO_NATIVE_PATH ${BOOST_BUILD_SLAVE_PYTHONPATH}/info.py
BOOST_BUILD_SLAVE_INFO_PY)
add_custom_target(slave-info
COMMAND ${PYTHON_EXECUTABLE} ${BOOST_BUILD_SLAVE_INFO_PY}
COMMENT "Print slave info"
)
endif(BOOST_BUILD_SLAVE)
#
# Used over in BoostTesting and BoostCore to attach xmlrpc submission rules
# to various intermediate build targets (libraries, test suites)
#
file(TO_NATIVE_PATH ${BOOST_BUILD_SLAVE_PYTHONPATH}/post.py
BOOST_BUILD_SLAVE_POST_PY)
macro(boost_post_results PROJECT_NAME_ PARENT_TARGET BUILD_OR_TEST LOGDIR)
if(BOOST_BUILD_SLAVE)
add_custom_command(TARGET ${PARENT_TARGET}
POST_BUILD
COMMAND ${PYTHON_EXECUTABLE} ${BOOST_BUILD_SLAVE_POST_PY} ${PROJECT_NAME_} ${PARENT_TARGET} ${BUILD_OR_TEST} ${LOGDIR}
COMMENT "Submitting results for '${BUILD_OR_TEST}' of ${PARENT_TARGET} in ${PROJECT_NAME_}"
)
set_directory_properties(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES ${LOGDIR}/Log.marshal)
add_dependencies(test ${PARENT_TARGET})
endif(BOOST_BUILD_SLAVE)
endmacro(boost_post_results PARENT_TARGET)

161
CMake/BoostConfig.cmake Normal file
View File

@@ -0,0 +1,161 @@
##########################################################################
# Boost Configuration Support #
##########################################################################
# Copyright (C) 2007 Douglas Gregor <doug.gregor@gmail.com> #
# Copyright (C) 2007 Troy Straszheim #
# #
# 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 #
##########################################################################
# This module defines several variables that provide information about #
# the target compiler and platform. #
# #
# Variables defined: #
# #
# BOOST_TOOLSET: #
# The Boost toolset name, used by the library version mechanism to #
# encode the compiler and version into the name of the #
# library. This toolset name will correspond with Boost.Build #
# version 2's toolset name, including version number. #
# #
# MULTI_THREADED_COMPILE_FLAGS: #
# Compilation flags when building multi-threaded programs. #
# #
# MULTI_THREADED_LINK_FLAGS: #
# Linker flags when building multi-threaded programs. #
##########################################################################
include(CheckCXXSourceCompiles)
#
# Python interpreter
#
include(FindPythonInterp)
message(STATUS "found python executable ${PYTHON_EXECUTABLE}")
include(FindPythonLibs)
message(STATUS "found python includes ${PYTHON_INCLUDE_PATH}")
message(STATUS "found python libs ${PYTHON_LIBRARIES}")
# Toolset detection.
if (NOT BOOST_TOOLSET)
set(BOOST_TOOLSET "unknown")
if (MSVC60)
set(BOOST_TOOLSET "vc6")
elseif(MSVC70)
set(BOOST_TOOLSET "vc7")
elseif(MSVC71)
set(BOOST_TOOLSET "vc71")
elseif(MSVC80)
set(BOOST_TOOLSET "vc80")
elseif(MSVC90)
set(BOOST_TOOLSET "vc90")
elseif(MSVC)
set(BOOST_TOOLSET "vc")
elseif(BORLAND)
set(BOOST_TOOLSET "bcb")
elseif(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
# Execute GCC with the -dumpversion option, to give us a version string
execute_process(
COMMAND ${CMAKE_CXX_COMPILER} "-dumpversion"
OUTPUT_VARIABLE GCC_VERSION_STRING)
# Match only the major and minor versions of the version string
string(REGEX MATCH "[0-9]+.[0-9]+" GCC_MAJOR_MINOR_VERSION_STRING
"${GCC_VERSION_STRING}")
# Strip out the period between the major and minor versions
string(REGEX REPLACE "\\." "" BOOST_VERSIONING_GCC_VERSION
"${GCC_MAJOR_MINOR_VERSION_STRING}")
# Set the GCC versioning toolset
set(BOOST_TOOLSET "gcc${BOOST_VERSIONING_GCC_VERSION}")
endif(MSVC60)
endif (NOT BOOST_TOOLSET)
# Multi-threading support
if(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
set(MULTI_THREADED_COMPILE_FLAGS "-pthreads")
set(MULTI_THREADED_LINK_LIBS rt)
elseif(CMAKE_SYSTEM_NAME STREQUAL "BeOS")
# No threading options necessary for BeOS
elseif(CMAKE_SYSTEM_NAME MATCHES ".*BSD")
set(MULTI_THREADED_COMPILE_FLAGS "-pthread")
set(MULTI_THREADED_LINK_LIBS pthread)
elseif(CMAKE_SYSTEM_NAME STREQUAL "DragonFly")
# DragonFly is FreeBSD bariant
set(MULTI_THREADED_COMPILE_FLAGS "-pthread")
elseif(CMAKE_SYSTEM_NAME STREQUAL "IRIX")
# TODO: GCC on Irix doesn't support multi-threading?
elseif(CMAKE_SYSTEM_NAME STREQUAL "HP-UX")
# TODO: gcc on HP-UX does not support multi-threading?
elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin")
# No threading options necessary for Mac OS X
elseif(UNIX)
# Assume -pthread and -lrt on all other variants
set(MULTI_THREADED_COMPILE_FLAGS "-pthread -D_REENTRANT")
set(MULTI_THREADED_LINK_FLAGS "")
set(MULTI_THREADED_LINK_LIBS pthread rt)
endif(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
# Setup DEBUG_COMPILE_FLAGS, RELEASE_COMPILE_FLAGS, DEBUG_LINK_FLAGS and
# and RELEASE_LINK_FLAGS based on the CMake equivalents
if(CMAKE_CXX_FLAGS_DEBUG)
if(MSVC)
# Eliminate the /MDd flag; we'll add it back when we need it
string(REPLACE "/MDd" "" CMAKE_CXX_FLAGS_DEBUG
"${CMAKE_CXX_FLAGS_DEBUG}")
endif(MSVC)
set(DEBUG_COMPILE_FLAGS "${CMAKE_CXX_FLAGS_DEBUG}" CACHE STRING "Compilation flags for debug libraries")
endif(CMAKE_CXX_FLAGS_DEBUG)
if(CMAKE_CXX_FLAGS_RELEASE)
if(MSVC)
# Eliminate the /MD flag; we'll add it back when we need it
string(REPLACE "/MD" "" CMAKE_CXX_FLAGS_RELEASE
"${CMAKE_CXX_FLAGS_RELEASE}")
endif(MSVC)
set(RELEASE_COMPILE_FLAGS "${CMAKE_CXX_FLAGS_RELEASE}" CACHE STRING "Compilation flags for release libraries")
endif(CMAKE_CXX_FLAGS_RELEASE)
if(CMAKE_SHARED_LINKER_FLAGS_DEBUG)
set(DEBUG_LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_DEBUG}" CACHE STRING "Linker flags for debug libraries")
endif(CMAKE_SHARED_LINKER_FLAGS_DEBUG)
if(CMAKE_SHARED_LINKER_FLAGS_RELEASE)
set(RELEASE_LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}" CACHE STRING "Link flags for release libraries")
endif(CMAKE_SHARED_LINKER_FLAGS_RELEASE)
# Set DEBUG_EXE_LINK_FLAGS, RELEASE_EXE_LINK_FLAGS
if (CMAKE_EXE_LINKER_FLAGS_DEBUG)
set(DEBUG_EXE_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS_DEBUG}")
endif (CMAKE_EXE_LINKER_FLAGS_DEBUG)
if (CMAKE_EXE_LINKER_FLAGS_RELEASE)
set(RELEASE_EXE_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS_RELEASE}")
endif (CMAKE_EXE_LINKER_FLAGS_RELEASE)
# Tweak the configuration and build types appropriately.
if(CMAKE_CONFIGURATION_TYPES)
# Limit CMAKE_CONFIGURATION_TYPES to Debug and Release
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Semicolon-separate list of supported configuration types" FORCE)
else(CMAKE_CONFIGURATION_TYPES)
# Build in release mode by default
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are Release or Debug" FORCE)
endif (NOT CMAKE_BUILD_TYPE)
endif(CMAKE_CONFIGURATION_TYPES)
# Clear out the built-in C++ compiler and link flags for each of the
# configurations.
set(CMAKE_CXX_FLAGS_DEBUG "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_MODULE_LINKER_FLAGS_DEBUG "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_CXX_FLAGS_RELEASE "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_MODULE_LINKER_FLAGS_RELEASE "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_CXX_FLAGS_MINSIZEREL "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_EXE_LINKER_FLAGS_MINSIZEREL "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO "" CACHE INTERNAL "Unused by Boost")
set(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO "" CACHE INTERNAL "Unused by Boost")

1360
CMake/BoostCore.cmake Normal file

File diff suppressed because it is too large Load Diff

520
CMake/BoostDocs.cmake Normal file
View File

@@ -0,0 +1,520 @@
##########################################################################
# Boost Documentation Generation #
##########################################################################
# Copyright (C) 2008 Douglas Gregor <doug.gregor@gmail.com> #
# #
# 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 #
##########################################################################
# Important developer macros in this file: #
# #
##########################################################################
# Transforms the source XML file by applying the given XSL stylesheet.
#
# xsl_transform(output input [input2 input3 ...]
# STYLESHEET stylesheet
# [CATALOG catalog]
# [DIRECTORY mainfile]
# [PARAMETERS param1=value1 param2=value2 ...]
# [[MAKE_ALL_TARGET | MAKE_TARGET] target]
# [COMMENT comment])
#
# This macro builds a custom command that transforms an XML file
# (input) via the given XSL stylesheet. The output will either be a
# single file (the default) or a directory (if the DIRECTION argument
# is specified). The STYLESBEET stylesheet must be a valid XSL
# stylesheet. Any extra input files will be used as additional
# dependencies for the target. For example, these extra input files
# might refer to other XML files that are included by the input file
# through XInclude.
#
# When the XSL transform output is going to a directory, the mainfile
# argument provides the name of a file that will be generated within
# the output directory. This file will be used for dependency tracking.
#
# XML catalogs can be used to remap parts of URIs within the
# stylesheet to other (typically local) entities. To provide an XML
# catalog file, specify the name of the XML catalog file via the
# CATALOG argument. It will be provided to the XSL transform.
#
# The PARAMETERS argument is followed by param=value pairs that set
# additional parameters to the XSL stylesheet. The parameter names
# that can be used correspond to the <xsl:param> elements within the
# stylesheet.
#
# To associate a target name with the result of the XSL
# transformation, use the MAKE_TARGET or MAKE_ALL_TARGET option and
# provide the name of the target. The MAKE_ALL_TARGET option only
# differs from MAKE_TARGET in that MAKE_ALL_TARGET will make the
# resulting target a part of the default build.
#
# If a COMMENT argument is provided, it will be used as the comment
# CMake provides when running this XSL transformation. Otherwise, the
# comment will be "Generating "output" via XSL transformation...".
macro(xsl_transform OUTPUT INPUT)
parse_arguments(THIS_XSL
"STYLESHEET;CATALOG;MAKE_ALL_TARGET;MAKE_TARGET;PARAMETERS;DIRECTORY;COMMENT"
""
${ARGN}
)
# TODO: Is this the best way to handle catalogs? The alternative is
# that we could provide explicit remappings to the xsl_transform
# macro, and it could generate a temporary XML catalog file.
if (THIS_XSL_CATALOG)
set(THIS_XSL_CATALOG "XML_CATALOG_FILES=${THIS_XSL_CATALOG}")
endif ()
# Translate XSL parameters into a form that xsltproc can use.
set(THIS_XSL_EXTRA_FLAGS)
foreach(PARAM ${THIS_XSL_PARAMETERS})
string(REGEX REPLACE "([^=]*)=([^;]*)" "\\1;\\2"
XSL_PARAM_LIST ${PARAM})
list(GET XSL_PARAM_LIST 0 XSL_PARAM_NAME)
list(GET XSL_PARAM_LIST 1 XSL_PARAM_VALUE)
list(APPEND THIS_XSL_EXTRA_FLAGS
--stringparam ${XSL_PARAM_NAME} ${XSL_PARAM_VALUE})
endforeach(PARAM)
# If the user didn't provide a comment for this transformation,
# create a default one.
if(NOT THIS_XSL_COMMENT)
set(THIS_XSL_COMMENT "Generating ${OUTPUT} via XSL transformation...")
endif()
# Figure out the actual output file that we tell CMake about
# (THIS_XSL_OUTPUT_FILE) and the output file or directory that we
# tell xsltproc about (THIS_XSL_OUTPUT).
if (THIS_XSL_DIRECTORY)
set(THIS_XSL_OUTPUT_FILE ${OUTPUT}/${THIS_XSL_DIRECTORY})
set(THIS_XSL_OUTPUT ${OUTPUT}/)
else()
set(THIS_XSL_OUTPUT_FILE ${OUTPUT})
set(THIS_XSL_OUTPUT ${OUTPUT})
endif()
if(NOT THIS_XSL_STYLESHEET)
message(SEND_ERROR
"xsl_transform macro invoked without a STYLESHEET argument")
else()
# Run the XSLT processor to do the XML transformation.
add_custom_command(OUTPUT ${THIS_XSL_OUTPUT_FILE}
COMMAND ${THIS_XSL_CATALOG} ${XSLTPROC} ${XSLTPROC_FLAGS}
${THIS_XSL_EXTRA_FLAGS} -o ${THIS_XSL_OUTPUT}
--path ${CMAKE_CURRENT_BINARY_DIR}
${THIS_XSL_STYLESHEET} ${INPUT}
COMMENT ${THIS_XSL_COMMENT}
DEPENDS ${INPUT} ${THIS_XSL_DEFAULT_ARGS})
set_source_files_properties(${THIS_XSL_OUTPUT_FILE}
PROPERTIES GENERATED TRUE)
# Create a custom target to refer to the result of this
# transformation.
if (THIS_XSL_MAKE_ALL_TARGET)
add_custom_target(${THIS_XSL_MAKE_ALL_TARGET} ALL
DEPENDS ${THIS_XSL_OUTPUT_FILE})
elseif(THIS_XSL_MAKE_TARGET)
add_custom_target(${THIS_XSL_MAKE_TARGET}
DEPENDS ${THIS_XSL_OUTPUT_FILE})
endif()
endif()
endmacro(xsl_transform)
# Use Doxygen to parse header files and produce BoostBook output.
#
# doxygen_to_boostbook(output header1 header2 ...
# [PARAMETERS param1=value1 param2=value2 ... ])
#
# This macro sets up rules to transform a set of C/C++ header files
# into BoostBook reference documentation. The resulting BoostBook XML
# file will be named by the "output" parameter, and the set of headers
# is provided following the output file. The actual parsing of header
# files is provided by Doxygen, and is transformed into XML through
# various XSLT transformations.
#
# Doxygen has a variety of configuration parameters. One can supply
# extra Doxygen configuration parameters by providing NAME=VALUE pairs
# following the PARAMETERS argument. These parameters will be added to
# the Doxygen configuration file.
#
# This macro is intended to be used internally by
# boost_add_documentation.
macro(doxygen_to_boostbook OUTPUT)
parse_arguments(THIS_DOXY
"PARAMETERS"
""
${ARGN})
# Create a Doxygen configuration file template
# TODO: We would like to create this file at build time rather
# than at configuration time
get_filename_component(DOXYFILE_PATH ${OUTPUT} PATH)
get_filename_component(DOXYFILE_NAME ${OUTPUT} NAME_WE)
set(DOXYFILE ${DOXYFILE_PATH}/${DOXYFILE_NAME}.doxyfile)
execute_process(
COMMAND ${DOXYGEN} -s -g ${DOXYFILE}
OUTPUT_QUIET ERROR_QUIET)
# Update the Doxygen configuration file for XML generation
file(APPEND ${DOXYFILE} "OUTPUT_DIRECTORY = ${CMAKE_CURRENT_BINARY_DIR}\n")
file(APPEND ${DOXYFILE} "GENERATE_LATEX = NO\n")
file(APPEND ${DOXYFILE} "GENERATE_HTML = NO\n")
file(APPEND ${DOXYFILE} "GENERATE_XML = YES\n")
foreach(PARAM ${THIS_DOXY_PARAMETERS})
file(APPEND ${DOXYFILE} "${PARAM}\n")
endforeach(PARAM)
set(THIS_DOXY_HEADER_PATH ${CMAKE_SOURCE_DIR}/libs/${libname}/include)
set(THIS_DOXY_HEADER_LIST "")
set(THIS_DOXY_HEADERS)
foreach(HDR ${THIS_DOXY_DEFAULT_ARGS})
list(APPEND THIS_DOXY_HEADERS ${THIS_DOXY_HEADER_PATH}/${HDR})
set(THIS_DOXY_HEADER_LIST
"${THIS_DOXY_HEADER_LIST} ${THIS_DOXY_HEADER_PATH}/${HDR}")
endforeach(HDR)
file(APPEND ${DOXYFILE} "INPUT = ${THIS_DOXY_HEADER_LIST}\n")
# Generate Doxygen XML
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/xml/index.xml
COMMAND ${DOXYGEN} ${DOXYFILE}
COMMENT "Generating Doxygen XML output for Boost.${PROJECT_NAME}..."
DEPENDS ${THIS_DOXY_HEADERS})
# Collect Doxygen XML into a single XML file
set_source_files_properties(
${CMAKE_CURRENT_BINARY_DIR}/xml/combine.xslt
PROPERTIES GENERATED TRUE)
xsl_transform(
${CMAKE_CURRENT_BINARY_DIR}/xml/all.xml
${CMAKE_CURRENT_BINARY_DIR}/xml/index.xml
STYLESHEET ${CMAKE_CURRENT_BINARY_DIR}/xml/combine.xslt
COMMENT "Collecting Doxygen XML output for Boost.${PROJECT_NAME}...")
# Transform single Doxygen XML file into BoostBook XML
xsl_transform(${OUTPUT}
${CMAKE_CURRENT_BINARY_DIR}/xml/all.xml
STYLESHEET ${BOOSTBOOK_XSL_DIR}/doxygen/doxygen2boostbook.xsl
COMMENT "Transforming Doxygen XML into BoostBook XML for Boost.${PROJECT_NAME}...")
endmacro(doxygen_to_boostbook)
# Adds documentation for the current library or tool project
#
# boost_add_documentation(source1 source2 source3 ...
# [HEADERS header1 header2 ...]
# [DOXYGEN_PARAMETERS param1=value1 param2=value2 ...])
#
# This macro describes the documentation for a library or tool, which
# will be built and installed as part of the normal build
# process. Documentation can be in a variety of formats, and the input
# format will determine how that documentation is transformed. The
# documentation's format is determined by its extension, and the
# following input formats are supported:
#
# QuickBook
# BoostBook (.XML extension):
macro(boost_add_documentation SOURCE)
parse_arguments(THIS_DOC
"HEADERS;DOXYGEN_PARAMETERS"
""
${ARGN})
# If SOURCE is not a full path, it's in the current source
# directory.
get_filename_component(THIS_DOC_SOURCE_PATH ${SOURCE} PATH)
if(THIS_DOC_SOURCE_PATH STREQUAL "")
set(THIS_DOC_SOURCE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/${SOURCE}")
else()
set(THIS_DOC_SOURCE_PATH ${SOURCE})
endif()
# If we are parsing C++ headers (with Doxygen) for reference
# documentation, do so now and produce the requested BoostBook XML
# file.
if (THIS_DOC_HEADERS)
set(DOC_HEADER_FILES)
set(DOC_BOOSTBOOK_FILE)
foreach(HEADER ${THIS_DOC_HEADERS})
get_filename_component(HEADER_EXT ${HEADER} EXT)
string(TOUPPER ${HEADER_EXT} HEADER_EXT)
if (HEADER_EXT STREQUAL ".XML")
if (DOC_BOOSTBOOK_FILE)
# Generate this BoostBook file from the headers
doxygen_to_boostbook(
${CMAKE_CURRENT_BINARY_DIR}/${DOC_BOOSTBOOK_FILE}
${DOC_HEADER_FILES}
PARAMETERS ${THIS_DOC_DOXYGEN_PARAMETERS})
list(APPEND THIS_DOC_DEFAULT_ARGS
${CMAKE_CURRENT_BINARY_DIR}/${DOC_BOOSTBOOK_FILE})
endif()
set(DOC_BOOSTBOOK_FILE ${HEADER})
set(DOC_HEADER_FILES)
else()
if (NOT DOC_BOOSTBOOK_FILE)
message(SEND_ERROR
"HEADERS argument to boost_add_documentation must start with a BoostBook XML file name for output")
endif()
list(APPEND DOC_HEADER_FILES ${HEADER})
endif()
endforeach()
if (DOC_HEADER_FILES)
# Generate this BoostBook file from the headers
doxygen_to_boostbook(
${CMAKE_CURRENT_BINARY_DIR}/${DOC_BOOSTBOOK_FILE}
${DOC_HEADER_FILES}
PARAMETERS ${THIS_DOC_DOXYGEN_PARAMETERS})
list(APPEND THIS_DOC_DEFAULT_ARGS
${CMAKE_CURRENT_BINARY_DIR}/${DOC_BOOSTBOOK_FILE})
endif()
endif (THIS_DOC_HEADERS)
# Figure out the source file extension, which will tell us how to
# build the documentation.
get_filename_component(THIS_DOC_EXT ${SOURCE} EXT)
string(TOUPPER ${THIS_DOC_EXT} THIS_DOC_EXT)
if (THIS_DOC_EXT STREQUAL ".QBK")
if (BUILD_QUICKBOOK)
# Transform Quickbook into BoostBook XML
get_filename_component(SOURCE_FILENAME ${SOURCE} NAME_WE)
set(BOOSTBOOK_FILE ${SOURCE_FILENAME}.xml)
add_custom_command(OUTPUT ${BOOSTBOOK_FILE}
COMMAND quickbook "--output-file=${BOOSTBOOK_FILE}"
${THIS_DOC_SOURCE_PATH}
DEPENDS ${THIS_DOC_SOURCE_PATH} ${THIS_DOC_DEFAULT_ARGS}
COMMENT "Generating BoostBook documentation for Boost.${PROJECT_NAME}...")
# Transform BoostBook into other formats
boost_add_documentation(${CMAKE_CURRENT_BINARY_DIR}/${BOOSTBOOK_FILE})
else()
message(SEND_ERROR
"Quickbook is required to build Boost documentation.\nQuickbook can be built by enabling the BUILD_QUICKBOOK.")
endif()
elseif (THIS_DOC_EXT STREQUAL ".XML")
# Transform BoostBook XML into DocBook XML
get_filename_component(SOURCE_FILENAME ${SOURCE} NAME_WE)
set(DOCBOOK_FILE ${SOURCE_FILENAME}.docbook)
xsl_transform(${DOCBOOK_FILE} ${THIS_DOC_SOURCE_PATH}
${THIS_DOC_DEFAULT_ARGS}
STYLESHEET ${BOOSTBOOK_XSL_DIR}/docbook.xsl
CATALOG ${CMAKE_BINARY_DIR}/catalog.xml
COMMENT "Generating DocBook documentation for Boost.${PROJECT_NAME}..."
MAKE_TARGET ${PROJECT_NAME}-docbook)
# Transform DocBook into other formats
boost_add_documentation(${CMAKE_CURRENT_BINARY_DIR}/${DOCBOOK_FILE})
elseif(THIS_DOC_EXT STREQUAL ".DOCBOOK")
# If requested, build HTML documentation
if (BUILD_DOCUMENTATION_HTML)
xsl_transform(
${CMAKE_CURRENT_BINARY_DIR}/html
${THIS_DOC_SOURCE_PATH}
STYLESHEET ${BOOSTBOOK_XSL_DIR}/html.xsl
CATALOG ${CMAKE_BINARY_DIR}/catalog.xml
DIRECTORY HTML.manifest
PARAMETERS admon.graphics.path=images
navig.graphics.path=images
boost.image.src=boost.png
COMMENT "Generating HTML documentation for Boost.${PROJECT_NAME}..."
MAKE_TARGET ${PROJECT_NAME}-html)
# Install generated documentation
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/html
DESTINATION share/boost-${BOOST_VERSION}
COMPONENT ${ULIBNAME}_DOCS
PATTERN "*.manifest" EXCLUDE)
endif ()
# If requested, build Unix man pages
if (BUILD_DOCUMENTATION_MAN_PAGES)
xsl_transform(
${CMAKE_CURRENT_BINARY_DIR}/man
${THIS_DOC_SOURCE_PATH}
STYLESHEET ${BOOSTBOOK_XSL_DIR}/manpages.xsl
CATALOG ${CMAKE_BINARY_DIR}/catalog.xml
DIRECTORY man.manifest
COMMENT "Generating man pages for Boost.${PROJECT_NAME}..."
MAKE_ALL_TARGET ${PROJECT_NAME}-man)
# Install man pages
install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/man
DESTINATION .
COMPONENT ${ULIBNAME}_DOCS
PATTERN "*.manifest" EXCLUDE)
endif ()
else()
message(SEND_ERROR "Unknown documentation source kind ${SOURCE}.")
endif()
endmacro(boost_add_documentation)
##########################################################################
# Documentation tools configuration #
##########################################################################
# Downloads the DocBook DTD into a place where DOCBOOK_DTD_DIR can
# find it.
macro(download_docbook_dtd)
if (NOT DOCBOOK_DTD_DIR)
set(DOCBOOK_DTD_FILENAME "docbook-xml-${WANT_DOCBOOK_DTD_VERSION}.zip")
set(DOCBOOK_DTD_URL
"http://www.oasis-open.org/docbook/xml/${WANT_DOCBOOK_DTD_VERSION}/${DOCBOOK_DTD_FILENAME}")
message(STATUS "Downloading DocBook DTD from ${DOCBOOK_DTD_URL}...")
file(DOWNLOAD
"${DOCBOOK_DTD_URL}"
"${CMAKE_BINARY_DIR}/${DOCBOOK_DTD_FILENAME}"
TIMEOUT 60 STATUS DOCBOOK_DTD_STATUS)
list(GET DOCBOOK_DTD_STATUS 0 DOCBOOK_DTD_ERROR)
if (DOCBOOK_DTD_ERROR EQUAL 0)
# Download successful! Extract the DTD ZIP file.
message(STATUS "Extracting DocBook DTD...")
execute_process(
COMMAND ${UNZIP} -d docbook-dtd-${WANT_DOCBOOK_DTD_VERSION} -q "${CMAKE_BINARY_DIR}/${DOCBOOK_DTD_FILENAME}"
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
RESULT_VARIABLE UNZIP_DTD_RESULT)
if (UNZIP_DTD_RESULT EQUAL 0)
# Extraction successful. Cleanup the downloaded file.
file(REMOVE ${CMAKE_BINARY_DIR}/${DOCBOOK_DTD_FILENAME})
set(DOCBOOK_DTD_DIR
${CMAKE_BINARY_DIR}/docbook-dtd-${WANT_DOCBOOK_DTD_VERSION}
CACHE PATH "Path to the DocBook DTD" FORCE)
else()
# We failed: report the error to the user
message(SEND_ERROR "Extraction of DocBook DTD archive ${DOCBOOK_DTD_FILENAME} failed with error \"${UNZIP_DTD_RESULT}\". DocBook DTD and XSL autoconfiguration cannot continue.")
endif ()
else()
list(GET DOCBOOK_DTD_STATUS 1 DOCBOOK_DTD_ERRORMSG)
message(SEND_ERROR "Unable to download DocBook DTD from ${DOCBOOK_DTD_URL}. Error was: \"${DOCBOOK_DTD_ERRORMSG}\"")
endif()
endif()
endmacro(download_docbook_dtd)
# Downloads the DocBook XSL into a place where DOCBOOK_XSL_DIR can
# find it.
macro(download_docbook_xsl)
if (NOT DOCBOOK_XSL_DIR)
set(DOCBOOK_XSL_FILENAME "docbook-xsl-${WANT_DOCBOOK_XSL_VERSION}.zip")
set(DOCBOOK_XSL_URL
"${SOURCEFORGE_MIRROR}/sourceforge/docbook/${DOCBOOK_XSL_FILENAME}")
message(STATUS "Downloading DocBook XSL from ${DOCBOOK_XSL_URL}...")
file(DOWNLOAD
"${DOCBOOK_XSL_URL}"
"${CMAKE_BINARY_DIR}/${DOCBOOK_XSL_FILENAME}"
TIMEOUT 60 STATUS DOCBOOK_XSL_STATUS)
list(GET DOCBOOK_XSL_STATUS 0 DOCBOOK_XSL_ERROR)
if (DOCBOOK_XSL_ERROR EQUAL 0)
# Download successful! Extract the XSL ZIP file.
message(STATUS "Extracting DocBook XSL stylesheets...")
execute_process(
COMMAND ${UNZIP} -q "${CMAKE_BINARY_DIR}/${DOCBOOK_XSL_FILENAME}"
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
RESULT_VARIABLE UNZIP_XSL_RESULT)
if (UNZIP_XSL_RESULT EQUAL 0)
# Extraction successful. Clean up the downloaded file.
file(REMOVE ${CMAKE_BINARY_DIR}/${DOCBOOK_XSL_FILENAME})
set(DOCBOOK_XSL_DIR
${CMAKE_BINARY_DIR}/docbook-xsl-${WANT_DOCBOOK_XSL_VERSION}
CACHE PATH "Path to the DocBook XSL stylesheets" FORCE)
else()
# We failed: report the error to the user
message(SEND_ERROR "Extraction of DocBook XSL archive ${DOCBOOK_XSL_FILENAME} failed with error \"${UNZIP_XSL_RESULT}\". DocBook XSL and XSL autoconfiguration cannot continue.")
endif ()
else()
list(GET DOCBOOK_XSL_STATUS 1 DOCBOOK_XSL_ERRORMSG)
message(SEND_ERROR "Unable to download DocBook XSL from ${DOCBOOK_XSL_URL}. Error was: \"${DOCBOOK_XSL_ERRORMSG}\". You might want to try another SourceForge mirror site by changing the advanced configuration variable SOURCEFORGE_MIRROR.")
endif()
endif()
endmacro(download_docbook_xsl)
# Preferred versions of DocBook stylesheets and utilities. We don't
# require these, but we know that they work.
set(WANT_DOCBOOK_DTD_VERSION 4.2)
set(WANT_DOCBOOK_XSL_VERSION 1.73.2)
# Find xsltproc to transform XML documents via XSLT
find_program(XSLTPROC xsltproc DOC "xsltproc transforms XML via XSLT")
set(XSLTPROC_FLAGS "--xinclude" CACHE STRING
"Flags to pass to xsltproc to transform XML documents")
# Find the DocBook DTD (version 4.2)
find_path(DOCBOOK_DTD_DIR docbookx.dtd
PATHS "${CMAKE_BINARY_DIR}/docbook-dtd-${WANT_DOCBOOK_DTD_VERSION}"
DOC "Path to the DocBook DTD")
# Find the DocBook XSL stylesheets
find_path(DOCBOOK_XSL_DIR html/html.xsl
PATHS "${CMAKE_BINARY_DIR}/docbook-xsl-${WANT_DOCBOOK_XSL_VERSION}"
DOC "Path to the DocBook XSL stylesheets")
# Find the BoostBook DTD (it should be in the distribution!)
find_path(BOOSTBOOK_DTD_DIR boostbook.dtd
PATHS ${CMAKE_SOURCE_DIR}/tools/boostbook/dtd
DOC "Path to the BoostBook DTD")
mark_as_advanced(BOOSTBOOK_DTD_DIR)
# Find the BoostBook XSL stylesheets (they should be in the distribution!)
find_path(BOOSTBOOK_XSL_DIR docbook.xsl
PATHS ${CMAKE_SOURCE_DIR}/tools/boostbook/xsl
DOC "Path to the BoostBook XSL stylesheets")
mark_as_advanced(BOOSTBOOK_XSL_DIR)
# Try to find Doxygen
find_package(Doxygen)
if (XSLTPROC AND DOXYGEN)
if (DOCBOOK_DTD_DIR AND DOCBOOK_XSL_DIR)
# Documentation build options
option(BUILD_DOCUMENTATION "Whether to build library documentation" ON)
option(BUILD_DOCUMENTATION_HTML "Whether to build HTML documentation" ON)
option(BUILD_DOCUMENTATION_MAN_PAGES "Whether to build Unix man pages" ON)
# Generate an XML catalog file.
configure_file(${CMAKE_SOURCE_DIR}/tools/build/CMake/catalog.xml.in
${CMAKE_BINARY_DIR}/catalog.xml
@ONLY)
else()
# Look for "unzip", because we'll need it to download the DocBook
# DTD and XSL stylesheets as part of autoconfiguration.
find_program(UNZIP unzip DOC "Used to extract ZIP archives")
if (UNZIP)
option(DOCBOOK_AUTOCONFIG
"Automatically download and configure DocBook DTD and XSL" OFF)
set(SOURCEFORGE_MIRROR "http://dl.sourceforge.net"
CACHE STRING "SourceForge mirror used to download DocBook XSL during autoconfiguration")
mark_as_advanced(SOURCEFORGE_MIRROR)
if (DOCBOOK_AUTOCONFIG)
message(STATUS "Initiating DocBook DTD and XSL autoconfiguration...")
download_docbook_dtd()
download_docbook_xsl()
endif (DOCBOOK_AUTOCONFIG)
endif()
endif()
endif()
# Turn off BUILD_DOCUMENTATION if it isn't going to succeed.
if (BUILD_DOCUMENTATION)
set(BUILD_DOCUMENTATION_OKAY TRUE)
if (NOT XSLTPROC)
set(BUILD_DOCUMENTATION_OKAY FALSE)
elseif (NOT DOXYGEN)
set(BUILD_DOCUMENTATION_OKAY FALSE)
elseif (NOT DOCBOOK_DTD_DIR)
set(BUILD_DOCUMENTATION_OKAY FALSE)
elseif (NOT DOCBOOK_XSL_DIR)
set(BUILD_DOCUMENTATION_OKAY FALSE)
else()
set(BUILD_DOCUMENTATION_OKAY TRUE)
endif()
if (NOT BUILD_DOCUMENTATION_OKAY)
if (BUILD_DOCUMENTATION)
set(BUILD_DOCUMENTATION OFF CACHE BOOL
"Whether to build library documentation" FORCE)
endif()
endif()
endif()

382
CMake/BoostTesting.cmake Normal file
View File

@@ -0,0 +1,382 @@
##########################################################################
# Regression Testing Support for Boost #
##########################################################################
# Copyright (C) 2007-8 Douglas Gregor <doug.gregor@gmail.com> #
# Copyright (C) 2007-8 Troy D. Straszheim #
# #
# 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 #
##########################################################################
# This file provides a set of CMake macros that support regression
# testing for Boost libraries. For each of the test macros below, the
# first argument, testname, states the name of the test that will be
# created. If no other arguments are provided, the source file
# testname.cpp will be used as the source file; otherwise, source
# files should be listed immediately after the name of the test.
#
# The macros for creating regression tests are:
# boost_test_run: Builds an executable and runs it as a test. The test
# succeeds if it builds and returns 0 when executed.
#
# boost_test_run_fail: Builds an executable and runs it as a test. The
# test succeeds if it builds but returns a non-zero
# exit code when executed.
#
# boost_test_compile: Tests that the given source file compiles without
# any errors.
#
# boost_test_compile_fail: Tests that the given source file produces
# errors when compiled.
# User-controlled option that can be used to enable/disable regression
# testing. By default, we disable testing, because most users won't
# want or need to perform regression testing on Boost. The Boost build
# is significantly faster when we aren't also building regression
# tests.
option(BUILD_TESTING "Enable testing" OFF)
if (BUILD_TESTING)
add_custom_target(test COMMENT "Running all tests")
option(TEST_INSTALLED_TREE "Enable testing of an already-installed tree" OFF)
if (TEST_INSTALLED_TREE)
include("${CMAKE_INSTALL_PREFIX}/lib/Boost${BOOST_VERSION}/boost-targets.cmake")
endif (TEST_INSTALLED_TREE)
endif (BUILD_TESTING)
option(BOOST_BUILD_SANITY_TEST
"Don't build regular boost libraries, build libraries that test the boost cmake build system itself" OFF)
if(BOOST_BUILD_SANITY_TEST)
set(BOOST_LIBS_DIR ${CMAKE_SOURCE_DIR}/tools/build/CMake/sanity)
configure_file(${CMAKE_SOURCE_DIR}/libs/CMakeLists.txt ${BOOST_LIBS_DIR}/CMakeLists.txt COPYONLY)
else(BOOST_BUILD_SANITY_TEST)
set(BOOST_LIBS_DIR ${CMAKE_SOURCE_DIR}/libs)
endif(BOOST_BUILD_SANITY_TEST)
# This macro is an internal utility macro that helps parse the
# arguments passed to the Boost testing commands. It will generally
# not be used by Boost developers.
macro(boost_test_add_dependent_includes includes)
foreach (include ${includes})
#message(STATUS "include: ${include}")
include_directories("${Boost_SOURCE_DIR}/libs/${include}/include")
endforeach (include ${includes})
endmacro(boost_test_add_dependent_includes includes)
# This macro is an internal utility macro that helps parse the
# arguments passed to the Boost testing commands. It will generally
# not be used by Boost developers.
#
# boost_test_parse_args(testname
# [source1 source2 ...]
# [ARGS arg1 arg2... ]
# [COMPILE_FLAGS compileflags]
# [LINK_FLAGS linkflags]
# [LINK_LIBS linklibs]
# [DEPENDS libdepend1 libdepend2 ...]
# [COMPILE] [RUN] [FAIL])
#
# testname is the name of the test. The remaining arguments passed to
# this macro will be parsed and categorized for the developer-level
# test macros to use.
#
# Variables affected:
#
# BOOST_TEST_OKAY: Will be set to TRUE if it is okay to build and
# run this test.
#
# BOOST_TEST_SOURCES: Will be populated with the set of source files
# that should be used to compile this test. If the user has provided
# source files, BOOST_TEST_SOURCES will contain those; otherwise,
# BOOST_TEST_SOURCES will only contain "testname.cpp".
#
# BOOST_TEST_TAG: compile, compile_fail, run, or run_fail.
# Used in test-reporting systems.
#
# BOOST_TEST_TESTNAME: A (hopefully) globally unique target name
# for the test, constructed from PROJECT-testname-TAG
#
# BOOST_TEST_arg: Will be populated with the arguments provided for
# the arguemnt "arg", where "arg" can be any of the extra arguments
# specified above.
#
#
macro(boost_test_parse_args testname)
#message("boost_test_parse_args ${testname} ${ARGN}")
set(BOOST_TEST_OKAY TRUE)
set(BOOST_TEST_COMPILE_FLAGS "")
parse_arguments(BOOST_TEST
"LINK_LIBS;LINK_FLAGS;DEPENDS;COMPILE_FLAGS;ARGS;EXTRA_OPTIONS"
"COMPILE;RUN;LINK;FAIL;RELEASE;DEBUG"
${ARGN}
)
# Check each of the dependencies to see if we can still build this
# test.
foreach(ARG ${BOOST_TEST_DEPENDS})
get_target_property(DEPEND_TYPE ${ARG} TYPE)
get_target_property(DEPEND_LOCATION ${ARG} LOCATION)
# If building static libraries is turned off, don't try to build
# the test
if (NOT BUILD_STATIC AND ${DEPEND_TYPE} STREQUAL "STATIC_LIBRARY")
set(BOOST_TEST_OKAY FALSE)
endif (NOT BUILD_STATIC AND ${DEPEND_TYPE} STREQUAL "STATIC_LIBRARY")
# If building shared libraries is turned off, don't try to build
# the test
if (NOT BUILD_SHARED AND ${DEPEND_TYPE} STREQUAL "SHARED_LIBRARY")
set(BOOST_TEST_OKAY FALSE)
endif (NOT BUILD_SHARED AND ${DEPEND_TYPE} STREQUAL "SHARED_LIBRARY")
endforeach(ARG ${BOOST_TEST_DEPENDS})
# Setup the SOURCES variables. If no sources are specified, use the
# name of the test.cpp
if (BOOST_TEST_DEFAULT_ARGS)
set(BOOST_TEST_SOURCES ${BOOST_TEST_DEFAULT_ARGS})
else (BOOST_TEST_DEFAULT_ARGS)
set(BOOST_TEST_SOURCES "${testname}.cpp")
endif (BOOST_TEST_DEFAULT_ARGS)
#message("Sources: ${BOOST_TEST_SOURCES}")
if (BOOST_TEST_RUN)
set(BOOST_TEST_TAG "run")
elseif(BOOST_TEST_COMPILE)
set(BOOST_TEST_TAG "compile")
elseif(BOOST_TEST_LINK)
set(BOOST_TEST_TAG "link")
endif(BOOST_TEST_RUN)
if (BOOST_TEST_FAIL)
set(BOOST_TEST_TAG ${BOOST_TEST_TAG}-fail)
endif(BOOST_TEST_FAIL)
set(BOOST_TEST_TESTNAME "${PROJECT_NAME}-${testname}-${BOOST_TEST_TAG}")
#message("testname: ${BOOST_TEST_TESTNAME}")
# If testing is turned off, this test is not okay
if (NOT BUILD_TESTING)
set(BOOST_TEST_OKAY FALSE)
endif(NOT BUILD_TESTING)
endmacro(boost_test_parse_args)
# This macro creates a Boost regression test that will be executed. If
# the test can be built, executed, and exits with a return code of
# zero, it will be considered to have passed.
#
# boost_test_run(testname
# [source1 source2 ...]
# [ARGS arg1 arg2... ]
# [COMPILE_FLAGS compileflags]
# [LINK_FLAGS linkflags]
# [LINK_LIBS linklibs]
# [DEPENDS libdepend1 libdepend2 ...]
# [EXTRA_OPTIONS option1 option2 ...])
#
# testname is the name of the test. source1, source2, etc. are the
# source files that will be built and linked into the test
# executable. If no source files are provided, the file "testname.cpp"
# will be used instead.
#
# There are several optional arguments to control how the regression
# test is built and executed:
#
# ARGS: Provides additional arguments that will be passed to the
# test executable when it is run.
#
# COMPILE_FLAGS: Provides additional compilation flags that will be
# used when building this test. For example, one might want to add
# "-DBOOST_SIGNALS_ASSERT=1" to turn on assertions within the library.
#
# LINK_FLAGS: Provides additional flags that will be passed to the
# linker when linking the test excecutable. This option should not
# be used to link in additional libraries; see LINK_LIBS and
# DEPENDS.
#
# LINK_LIBS: Provides additional libraries against which the test
# executable will be linked. For example, one might provide "expat"
# as options to LINK_LIBS, to state that this executable should be
# linked against the external "expat" library. Use LINK_LIBS for
# libraries external to Boost; for Boost libraries, use DEPENDS.
#
# DEPENDS: States that this test executable depends on and links
# against another Boost library. The argument to DEPENDS should be
# the name of a particular variant of a Boost library, e.g.,
# boost_signals-static.
#
# EXTRA_OPTIONS: Provide extra options that will be passed on to
# boost_add_executable.
#
# Example:
# boost_test_run(signal_test DEPENDS boost_signals)
macro(boost_test_run testname)
boost_test_parse_args(${testname} ${ARGN} RUN)
if (BOOST_TEST_OKAY)
boost_add_executable(${testname} ${BOOST_TEST_SOURCES}
OUTPUT_NAME tests/${PROJECT_NAME}/${testname}
DEPENDS "${BOOST_TEST_DEPENDS}"
LINK_LIBS ${BOOST_TEST_LINK_LIBS}
LINK_FLAGS ${BOOST_TEST_LINK_FLAGS}
COMPILE_FLAGS ${BOOST_TEST_COMPILE_FLAGS}
NO_INSTALL
${BOOST_TEST_EXTRA_OPTIONS})
if (THIS_EXE_OKAY)
# This target builds and runs the test
add_custom_target(${BOOST_TEST_TESTNAME})
file( TO_NATIVE_PATH "${BOOST_TEST_DRIVER}" NATIVE_BOOST_TEST_DRIVER )
set(THIS_TEST_PREFIX_ARGS
${PYTHON_EXECUTABLE} ${NATIVE_BOOST_TEST_DRIVER}
${CMAKE_CURRENT_BINARY_DIR} ${BOOST_TEST_TAG} ${testname}
)
add_custom_command(TARGET ${BOOST_TEST_TESTNAME}
POST_BUILD
COMMAND
${THIS_TEST_PREFIX_ARGS}
${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${CMAKE_CFG_INTDIR}/tests/${PROJECT_NAME}/${testname}
${BOOST_TEST_ARGS}
COMMENT "Running ${testname} in project ${PROJECT_NAME}"
)
add_dependencies(${BOOST_TEST_TESTNAME}
${PROJECT_NAME}-${testname}
)
add_dependencies(${PROJECT_NAME}-test
${BOOST_TEST_TESTNAME}
)
endif(THIS_EXE_OKAY)
endif (BOOST_TEST_OKAY)
endmacro(boost_test_run)
#
# This macro creates a boost regression test that will be run but is
# expected to fail (exit with nonzero return code).
# See boost_test_run()
#
macro(boost_test_run_fail testname)
boost_test_run(${testname} ${ARGN} FAIL)
endmacro(boost_test_run_fail)
# This macro creates a Boost regression test that will be compiled,
# but not linked or executed. If the test can be compiled with no
# failures, the test passes.
#
# boost_test_compile(testname
# [source1]
# [COMPILE_FLAGS compileflags])
#
# testname is the name of the test. source1 is the name of the source
# file that will be built. If no source file is provided, the file
# "testname.cpp" will be used instead.
#
# The COMPILE_FLAGS argument provides additional arguments that will
# be passed to the compiler when building this test.
# Example:
# boost_test_compile(advance)
macro(boost_test_compile testname)
boost_test_parse_args(${testname} ${ARGN} COMPILE)
if (BOOST_TEST_OKAY)
# Determine the include directories to pass along to the underlying
# project.
# works but not great
get_directory_property(BOOST_TEST_INCLUDE_DIRS INCLUDE_DIRECTORIES)
set(BOOST_TEST_INCLUDES "")
foreach(DIR ${BOOST_TEST_INCLUDE_DIRS})
set(BOOST_TEST_INCLUDES "${BOOST_TEST_INCLUDES};-I${DIR}")
endforeach(DIR ${BOOST_TEST_INCLUDE_DIRS})
set(THIS_TEST_PREFIX_ARGS
${PYTHON_EXECUTABLE} ${BOOST_TEST_DRIVER} ${CMAKE_CURRENT_BINARY_DIR} ${BOOST_TEST_TAG} ${testname}
)
add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${BOOST_TEST_TESTNAME}.${CMAKE_CXX_OUTPUT_EXTENSION}
COMMAND
${THIS_TEST_PREFIX_ARGS}
${CMAKE_CXX_COMPILER}
${BOOST_TEST_COMPILE_FLAGS}
${BOOST_TEST_INCLUDES}
-c ${BOOST_TEST_SOURCES}
-o ${CMAKE_CURRENT_BINARY_DIR}/${BOOST_TEST_TESTNAME}${CMAKE_CXX_OUTPUT_EXTENSION}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
DEPENDS ${BOOST_TEST_SOURCES}
COMMENT "Running ${testname} in project ${PROJECT_NAME}"
)
add_custom_target(${BOOST_TEST_TESTNAME}
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${BOOST_TEST_TESTNAME}.${CMAKE_CXX_OUTPUT_EXTENSION}
)
add_dependencies(${PROJECT_NAME}-test
${BOOST_TEST_TESTNAME}
)
endif(BOOST_TEST_OKAY)
endmacro(boost_test_compile)
#
# This macro creates a Boost regression test that is expected to
# *fail* to compile. See boost_test_compile()
#
macro(boost_test_compile_fail testname)
boost_test_compile(${testname} ${ARGN} FAIL)
endmacro(boost_test_compile_fail)
#
# boost_test_link:
#
# Under construction.
#
macro(boost_test_link testname)
boost_test_parse_args(${testname} ${ARGN} LINK)
if(BOOST_TEST_OKAY)
set(THIS_TEST_PREFIX_ARGS
${PYTHON_EXECUTABLE} ${BOOST_TEST_DRIVER} ${CMAKE_CURRENT_BINARY_DIR} test_link ${testname}
)
#
# FIXME: no ctest.
#
add_custom_target(TARGET ${BOOST_TEST_TESTNAME}
COMMAND /link/tests/are/failing/at/the/moment
COMMENT "Link test ${testname} in ${PROJECT_NAME} is failing."
)
# POST_BUILD
# COMMAND
# ${THIS_TEST_PREFIX_ARGS}
# ${CMAKE_CTEST_COMMAND}
# --build-and-test
# ${Boost_SOURCE_DIR}/tools/build/CMake/LinkTest
# ${Boost_BINARY_DIR}/tools/build/CMake/LinkTest
# --build-generator \\"${CMAKE_GENERATOR}\\"
# --build-makeprogram \\"${MAKEPROGRAM}\\"
# --build-project LinkTest
# --build-options -DSOURCE=${CMAKE_CURRENT_SOURCE_DIR}/${BOOST_TEST_SOURCES} -DINCLUDES=${Boost_SOURCE_DIR} -DCOMPILE_FLAGS=\\"${BOOST_TEST_COMPILE_FLAGS}\\"
# COMMENT "Running ${testname} (link) in project ${PROJECT_NAME}"
# )
add_dependencies(${PROJECT_NAME}-test
${BOOST_TEST_TESTNAME}
)
endif(BOOST_TEST_OKAY)
endmacro(boost_test_link)

213
CMake/BoostUtils.cmake Normal file
View File

@@ -0,0 +1,213 @@
##########################################################################
# Boost Utilities #
##########################################################################
# Copyright (C) 2007 Douglas Gregor <doug.gregor@gmail.com> #
# Copyright (C) 2007 Troy Straszheim #
# #
# 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 #
##########################################################################
# Macros in this module: #
# #
# list_contains: Determine whether a string value is in a list. #
# #
# car: Return the first element in a list #
# #
# cdr: Return all but the first element in a list #
# #
# parse_arguments: Parse keyword arguments for use in other macros. #
##########################################################################
# This utility macro determines whether a particular string value
# occurs within a list of strings:
#
# list_contains(result string_to_find arg1 arg2 arg3 ... argn)
#
# This macro sets the variable named by result equal to TRUE if
# string_to_find is found anywhere in the following arguments.
macro(list_contains var value)
set(${var})
foreach (value2 ${ARGN})
if (${value} STREQUAL ${value2})
set(${var} TRUE)
endif (${value} STREQUAL ${value2})
endforeach (value2)
endmacro(list_contains)
# This utility macro extracts the first argument from the list of
# arguments given, and places it into the variable named var.
#
# car(var arg1 arg2 ...)
macro(car var)
set(${var} ${ARGV1})
endmacro(car)
# This utility macro extracts all of the arguments given except the
# first, and places them into the variable named var.
#
# car(var arg1 arg2 ...)
macro(cdr var junk)
set(${var} ${ARGN})
endmacro(cdr)
# The PARSE_ARGUMENTS macro will take the arguments of another macro and
# define several variables. The first argument to PARSE_ARGUMENTS is a
# prefix to put on all variables it creates. The second argument is a
# list of names, and the third argument is a list of options. Both of
# these lists should be quoted. The rest of PARSE_ARGUMENTS are
# arguments from another macro to be parsed.
#
# PARSE_ARGUMENTS(prefix arg_names options arg1 arg2...)
#
# For each item in options, PARSE_ARGUMENTS will create a variable with
# that name, prefixed with prefix_. So, for example, if prefix is
# MY_MACRO and options is OPTION1;OPTION2, then PARSE_ARGUMENTS will
# create the variables MY_MACRO_OPTION1 and MY_MACRO_OPTION2. These
# variables will be set to true if the option exists in the command line
# or false otherwise.
#
# For each item in arg_names, PARSE_ARGUMENTS will create a variable
# with that name, prefixed with prefix_. Each variable will be filled
# with the arguments that occur after the given arg_name is encountered
# up to the next arg_name or the end of the arguments. All options are
# removed from these lists. PARSE_ARGUMENTS also creates a
# prefix_DEFAULT_ARGS variable containing the list of all arguments up
# to the first arg_name encountered.
MACRO(PARSE_ARGUMENTS prefix arg_names option_names)
SET(DEFAULT_ARGS)
FOREACH(arg_name ${arg_names})
SET(${prefix}_${arg_name})
ENDFOREACH(arg_name)
FOREACH(option ${option_names})
SET(${prefix}_${option} FALSE)
ENDFOREACH(option)
SET(current_arg_name DEFAULT_ARGS)
SET(current_arg_list)
FOREACH(arg ${ARGN})
LIST_CONTAINS(is_arg_name ${arg} ${arg_names})
IF (is_arg_name)
SET(${prefix}_${current_arg_name} ${current_arg_list})
SET(current_arg_name ${arg})
SET(current_arg_list)
ELSE (is_arg_name)
LIST_CONTAINS(is_option ${arg} ${option_names})
IF (is_option)
SET(${prefix}_${arg} TRUE)
ELSE (is_option)
SET(current_arg_list ${current_arg_list} ${arg})
ENDIF (is_option)
ENDIF (is_arg_name)
ENDFOREACH(arg)
SET(${prefix}_${current_arg_name} ${current_arg_list})
ENDMACRO(PARSE_ARGUMENTS)
# Perform a reverse topological sort on the given LIST.
#
# topological_sort(my_list "MY_" "_EDGES")
#
# LIST is the name of a variable containing a list of elements to be
# sorted in reverse topological order. Each element in the list has a
# set of outgoing edges (for example, those other list elements that
# it depends on). In the resulting reverse topological ordering
# (written back into the variable named LIST), an element will come
# later in the list than any of the elements that can be reached by
# following its outgoing edges and the outgoing edges of any vertices
# they target, recursively. Thus, if the edges represent dependencies
# on build targets, for example, the reverse topological ordering is
# the order in which one would build those targets.
#
# For each element E in this list, the edges for E are contained in
# the variable named ${PREFIX}${E}${SUFFIX}, where E is the
# upper-cased version of the element in the list. If no such variable
# exists, then it is assumed that there are no edges. For example, if
# my_list contains a, b, and c, one could provide a dependency graph
# using the following variables:
#
# MY_A_EDGES b
# MY_B_EDGES
# MY_C_EDGES a b
#
# With the involcation of topological_sort shown above and these
# variables, the resulting reverse topological ordering will be b, a,
# c.
function(topological_sort LIST PREFIX SUFFIX)
# Clear the stack and output variable
set(VERTICES "${${LIST}}")
set(STACK)
set(${LIST})
# Loop over all of the vertices, starting the topological sort from
# each one.
foreach(VERTEX ${VERTICES})
string(TOUPPER ${VERTEX} UPPER_VERTEX)
# If we haven't already processed this vertex, start a depth-first
# search from where.
if (NOT FOUND_${UPPER_VERTEX})
# Push this vertex onto the stack with all of its outgoing edges
string(REPLACE ";" " " NEW_ELEMENT
"${VERTEX};${${PREFIX}${UPPER_VERTEX}${SUFFIX}}")
list(APPEND STACK ${NEW_ELEMENT})
# We've now seen this vertex
set(FOUND_${UPPER_VERTEX} TRUE)
# While the depth-first search stack is not empty
list(LENGTH STACK STACK_LENGTH)
while(STACK_LENGTH GREATER 0)
# Remove the vertex and its remaining out-edges from the top
# of the stack
list(GET STACK -1 OUT_EDGES)
list(REMOVE_AT STACK -1)
# Get the source vertex and the list of out-edges
separate_arguments(OUT_EDGES)
list(GET OUT_EDGES 0 SOURCE)
list(REMOVE_AT OUT_EDGES 0)
# While there are still out-edges remaining
list(LENGTH OUT_EDGES OUT_DEGREE)
while (OUT_DEGREE GREATER 0)
# Pull off the first outgoing edge
list(GET OUT_EDGES 0 TARGET)
list(REMOVE_AT OUT_EDGES 0)
string(TOUPPER ${TARGET} UPPER_TARGET)
if (NOT FOUND_${UPPER_TARGET})
# We have not seen the target before, so we will traverse
# its outgoing edges before coming back to our
# source. This is the key to the depth-first traversal.
# We've now seen this vertex
set(FOUND_${UPPER_TARGET} TRUE)
# Push the remaining edges for the current vertex onto the
# stack
string(REPLACE ";" " " NEW_ELEMENT
"${SOURCE};${OUT_EDGES}")
list(APPEND STACK ${NEW_ELEMENT})
# Setup the new source and outgoing edges
set(SOURCE ${TARGET})
string(TOUPPER ${SOURCE} UPPER_SOURCE)
set(OUT_EDGES
${${PREFIX}${UPPER_SOURCE}${SUFFIX}})
endif(NOT FOUND_${UPPER_TARGET})
list(LENGTH OUT_EDGES OUT_DEGREE)
endwhile (OUT_DEGREE GREATER 0)
# We have finished all of the outgoing edges for
# SOURCE; add it to the resulting list.
list(APPEND ${LIST} ${SOURCE})
# Check the length of the stack
list(LENGTH STACK STACK_LENGTH)
endwhile(STACK_LENGTH GREATER 0)
endif (NOT FOUND_${UPPER_VERTEX})
endforeach(VERTEX)
set(${LIST} ${${LIST}} PARENT_SCOPE)
endfunction(topological_sort)

51
CMake/FindICU.cmake Normal file
View File

@@ -0,0 +1,51 @@
# Finds the International Components for Unicode (ICU) Library
#
# ICU_FOUND - True if ICU found.
# ICU_I18N_FOUND - True if ICU's internationalization library found.
# ICU_INCLUDE_DIRS - Directory to include to get ICU headers
# Note: always include ICU headers as, e.g.,
# unicode/utypes.h
# ICU_LIBRARIES - Libraries to link against for the common ICU
# ICU_I18N_LIBRARIES - Libraries to link against for ICU internationaliation
# (note: in addition to ICU_LIBRARIES)
# Look for the header file.
find_path(
ICU_INCLUDE_DIR
NAMES unicode/utypes.h
DOC "Include directory for the ICU library")
mark_as_advanced(ICU_INCLUDE_DIR)
# Look for the library.
find_library(
ICU_LIBRARY
NAMES icuuc cygicuuc cygicuuc32
DOC "Libraries to link against for the common parts of ICU")
mark_as_advanced(ICU_LIBRARY)
# Copy the results to the output variables.
if(ICU_INCLUDE_DIR AND ICU_LIBRARY)
set(ICU_FOUND 1)
set(ICU_LIBRARIES ${ICU_LIBRARY})
set(ICU_INCLUDE_DIRS ${ICU_INCLUDE_DIR})
# Look for the ICU internationalization libraries
find_library(
ICU_I18N_LIBRARY
NAMES icuin icui18n cygicuin cygicuin32
DOC "Libraries to link against for ICU internationalization")
mark_as_advanced(ICU_I18N_LIBRARY)
if (ICU_I18N_LIBRARY)
set(ICU_I18N_FOUND 1)
set(ICU_I18N_LIBRARIES ${ICU_I18N_LIBRARY})
else (ICU_I18N_LIBRARY)
set(ICU_I18N_FOUND 0)
set(ICU_I18N_LIBRARIES)
endif (ICU_I18N_LIBRARY)
else(ICU_INCLUDE_DIR AND ICU_LIBRARY)
set(ICU_FOUND 0)
set(ICU_I18N_FOUND 0)
set(ICU_LIBRARIES)
set(ICU_I18N_LIBRARIES)
set(ICU_INCLUDE_DIRS)
endif(ICU_INCLUDE_DIR AND ICU_LIBRARY)

57
CMake/boost_build_slave.py.in Executable file
View File

@@ -0,0 +1,57 @@
#!/usr/bin/python
#
# copyright (C) 2008 troy d. straszheim <troy@resophonic.com>
#
# 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
#
#
# Utilities, variables, imports for build slave python
#
import os, os.path, marshal, xmlrpclib, pysvn, socket, platform
from pprint import pprint
repo_path = "@CMAKE_SOURCE_DIR@"
client = pysvn.Client()
svn_entry = client.info(repo_path)
_configured_hostname = "@BOOST_BUILD_SLAVE_HOSTNAME@"
fqdn = _configured_hostname if len(_configured_hostname) > 0 else socket.getfqdn()
uname = platform.uname()
toolset = "@BOOST_TOOLSET@"
timeout_seconds = @BOOST_BUILD_SLAVE_TIMEOUT@
slave_details_file = "@BOOST_BUILD_SLAVE_DETAILS_FILE@"
contact_info = "@BOOST_BUILD_SLAVE_CONTACT_INFO@"
xmlrpc_url = "@BOOST_BUILD_SLAVE_SUBMIT_URL@"
build_id_file = os.path.join(r'@BOOST_BUILD_SLAVE_PYTHONPATH@', "build_id.txt")
try:
f = open(build_id_file)
build_id = int(f.read())
except:
build_id = None
def set_build_id(build_id):
print "Setting new build id %d locally" % build_id
f = open(build_id_file, "w")
f.write(str(build_id))
f.close()
def details():
if os.path.isabs(slave_details_file):
thefile = slave_details_file
else:
thefile = os.path.join("@CMAKE_BINARY_DIR@", slave_details_file)
if os.path.exists(thefile):
f = open(thefile)
txt = f.read()
else:
txt = "Build slave details file @BOOST_BUILD_SLAVE_DETAILS_FILE@ not found."
return txt

9
CMake/catalog.xml.in Normal file
View File

@@ -0,0 +1,9 @@
<?xml version="1.0"?>
<!DOCTYPE catalog
PUBLIC "-//OASIS/DTD Entity Resolution XML Catalog V1.0//EN"
"http://www.oasis-open.org/committees/entity/release/1.0/catalog.dtd">
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<rewriteURI uriStartString="http://www.boost.org/tools/boostbook/dtd/" rewritePrefix="file://@BOOSTBOOK_DTD_DIR@/"/>
<rewriteURI uriStartString="http://docbook.sourceforge.net/release/xsl/current/" rewritePrefix="file://@DOCBOOK_XSL_DIR@/"/>
<rewriteURI uriStartString="http://www.oasis-open.org/docbook/xml/4.2/" rewritePrefix="file://@DOCBOOK_DTD_DIR@/"/>
</catalog>

51
CMake/classify.py.in Executable file
View File

@@ -0,0 +1,51 @@
#
# Classifies pass/fail/warn for the sake of traash
#
toolset = '@BOOST_TOOLSET@'
import os
# 'cxx_compile_object'
# 'run'
# 'link_executable'
# 'create_shared_library'
# 'create_static_library'
# 'compile-fail'
def classify(step):
print "step=", step
if 'errno' in step:
if step['errno'] == 666:
step['status'] = 'timeout'
else:
step['status'] = 'not_executed'
return
if step['returncode'] != 0 and not step['expect_fail']:
step['status'] = 'fail'
return
if step['returncode'] == 0 and step['expect_fail']:
step['status'] = 'unexpected_pass'
return
#
# if it is an expected failure, don't warn just cause of warnings.
#
if step['returncode'] != 0 and step['expect_fail']:
step['status'] = 'pass'
return
if step['op'] != 'run' and len(step['stderr']) != 0 and not step['stderr'].isspace():
step['status'] = 'warn'
return
# on windoze, warnings are to be found in stdout... but the compiler always
# prints the name of the file first. So warn if there is more than one line
# in stdout. For now.
if os.name == 'nt' and step['op'] == 'cxx_compile_object' and step['stdout'].count('\n') > 1:
step['status'] = 'warn'
return
step['status'] = 'pass'

23
CMake/finish.py.in Executable file
View File

@@ -0,0 +1,23 @@
#!/usr/bin/python
#
# copyright (C) 2008 troy d. straszheim <troy@resophonic.com>
#
# 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
#
#
# Start a new build, notify server via xmlrpc
#
import sys
sys.path.append("@BOOST_BUILD_SLAVE_PYTHONPATH@")
from boost_build_slave import *
print '\nFinishing build %d with %s via XML-RPC' % (build_id, xmlrpc_url)
s = xmlrpclib.Server(xmlrpc_url)
s.traash.finish_build(build_id)

26
CMake/info.py.in Executable file
View File

@@ -0,0 +1,26 @@
#!/usr/bin/python
#
# copyright (C) 2008 troy d. straszheim <troy@resophonic.com>
#
# 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
#
#
# Start a new build, notify server via xmlrpc
#
import sys
sys.path.append("@BOOST_BUILD_SLAVE_PYTHONPATH@")
from boost_build_slave import *
print ' Url:', svn_entry.url, "at rev", svn_entry.revision.number
print ' FQDN:', fqdn
print ' Uname:', uname
print ' Toolset:', toolset
print ' Build ID:', build_id
print ' Contact:', contact_info
pref = '\n '
print ' Details: ' + pref.join(details().splitlines()), '\n\n'

110
CMake/marshal.py.in Executable file
View File

@@ -0,0 +1,110 @@
#!/usr/bin/python
#
# copyright (C) 2008 troy d. straszheim <troy@resophonic.com>
#
# 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
#
#
# Compiler driver. Takes a few arguments describing what is to be done
# (used to mark up the output) and executes compiler in a subshell, checking
# for errors and marshalling output to disk.
#
import sys, signal, threading, subprocess
sys.path.append("@BOOST_BUILD_SLAVE_PYTHONPATH@")
from boost_build_slave import *
import datetime, time, signal
from subprocess import Popen, PIPE
from kill_subprocess import kill_subprocess
from classify import classify
log = os.path.join(sys.argv[1], "Log.marshal")
op = sys.argv[2]
target = sys.argv[3]
argv = sys.argv[4:]
expect_fail = op.endswith("fail")
if os.name == 'nt':
os.environ['PATH'] = r'@CMAKE_LIBRARY_OUTPUT_DIRECTORY@;' + os.environ['PATH']
print "***\n*** Executing op:" + op + "\n*** " + str(argv) + "\n*** log=" + log + "\n***"
#
# execute subprocess, watch for timeout
#
class SubprocThread(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.ex = None
def run(self):
try:
self.proc = Popen(argv, stdout=PIPE, stderr=PIPE)
(self.stdout, self.stderr) = self.proc.communicate()
except EnvironmentError, e:
self.ex = e
t = SubprocThread()
starttime = datetime.datetime.now()
t.start()
t.join(timeout_seconds)
if t.isAlive():
print "*** Killing subprocess after timeout"
kill_subprocess(t.proc.pid)
e = OSError()
e.errno = 666
e.message = e.strerror = "TIMEOUT AFTER %d SECONDS" % timeout_seconds
e.filename = argv[0]
t.ex = e
duration = datetime.datetime.now() - starttime
#
# Collect and store subprocess info
#
result = { 'expect_fail' : expect_fail,
'wallclock_duration' : duration.seconds + duration.microseconds * 10**-6 }
if not t.ex:
result['returncode'] = t.proc.returncode
result['stdout'] = t.stdout
result['stderr'] = t.stderr
if t.proc.returncode != 0 and not expect_fail:
print "*** returncode: %d" % t.proc.returncode
print "*** stdout:" + result['stdout']
print "*** stderr:" + result['stderr']
else:
result['errno'] = t.ex.errno
result['filename'] = t.ex.filename
result['message'] = t.ex.message
result['strerror'] = t.ex.strerror
print "Errno:" + str(t.ex.errno) + ": " + t.ex.strerror
result.update({'op' : op,
'target' : target,
'cmdline' : argv })
classify(result)
print "post classification: result=", result
f = open(log, "ab", 0)
marshal.dump(result, f)
f.close()
if t.ex:
sys.exit(t.ex.errno)
else:
if expect_fail:
if t.proc.returncode != 0:
sys.exit(0)
else:
print "UNEXPECTED SUCCESS"
sys.exit(1) # we need an exit status for 'unexpected success'
else:
sys.exit(t.proc.returncode)

73
CMake/passthru.py.in Executable file
View File

@@ -0,0 +1,73 @@
#!/usr/bin/python
#
# copyright (C) 2008 troy d. straszheim <troy@resophonic.com>
#
# 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
#
#
# "Passthru" driver, only responsible for 'flipping' exit status of
# tests that are expected to fail. See driver.py for the version
# that is run when BOOST_BUILD_SLAVE is on, which does xmlizaton
# and the like
#
import sys, os, os.path
from subprocess import Popen, PIPE
def verbose(what):
if @BOOST_DRIVER_VERBOSE@:
print what
# ignored
# log = os.path.join(sys.argv[1], "Log.xml")
op = sys.argv[2]
# target = sys.argv[3]
argv = sys.argv[4:]
expect_fail = op.endswith("fail")
#
# execute subprocess
#
subproc = None
returncode = None
ex = None
stdout = None
stderr = None
try:
subproc = Popen(argv, stdout=PIPE, stderr=PIPE)
(stdout, stderr) = subproc.communicate()
except EnvironmentError, e:
ex = e
returncode = subproc.returncode
if stdout:
print stdout
if stderr:
print stderr
if not ex:
# possibly flip the return code
if not expect_fail:
if not returncode:
verbose("ok.")
else:
verbose("error.")
sys.exit(returncode)
else:
if returncode != 0:
verbose("ok.")
sys.exit(0)
else:
verbose("*** UNEXPECTED SUCCESS ***")
sys.exit(1) # we need an exit status for 'unexpected success'
else:
# if there is an os error 'above' the actual exit status of the subprocess,
# use the errno
print "Error in build system: " + str(ex.strerror)
sys.exit(ex.errno)

56
CMake/post.py.in Executable file
View File

@@ -0,0 +1,56 @@
#!/usr/bin/python
#
# copyright (C) 2008 troy d. straszheim <troy@resophonic.com>
#
# 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
#
#
# Send the build log via XML-RPC
#
import sys
sys.path.append("@BOOST_BUILD_SLAVE_PYTHONPATH@")
from boost_build_slave import *
s = xmlrpclib.Server(xmlrpc_url, allow_none=True)
project_name = sys.argv[1]
parent_target = sys.argv[2]
build_or_test = sys.argv[3]
logdir = sys.argv[4]
# print "\n>>>\n>>> Project " + project_name \
# + "\n>>> POST build log for " + parent_target \
# + "\n>>> from log dir" + logdir \
# + "\n>>> to " + xmlrpc_url \
# + "\n>>> Server build ID: %d" % build_id \
# + "\n>>>"
p = os.path.join(logdir, "Log.marshal")
if not os.path.exists(p):
print "No results to submit"
sys.exit(0)
f = open(p, "rb")
i = 0
while True:
try:
r = marshal.load(f)
r.update({ 'build_id' : build_id,
'project' : project_name,
'parent_target' : parent_target,
'build_or_test' : build_or_test })
s.traash.step(r)
i += 1
except EOFError, e:
break
print "Submitted ", i, " steps."
f.close()
os.remove(p)

View File

@@ -0,0 +1,82 @@
#!/usr/bin/python
#
# Build slave script.
#
import pysvn, os, time
from optparse import OptionParser
parser = OptionParser()
parser.add_option("-b", "--build-first",
action="store_true", dest="build_first", default=False,
help="Build on startup")
parser.add_option("-c", "--clean-first",
action="store_true", dest="clean_first", default=False,
help="Clean on startup")
parser.add_option("-C", "--clean-every-time",
action="store_true", dest="clean_every_time", default=False,
help="Clean before every build")
parser.add_option("-k", "--keep-rebuilding",
action="store_true", dest="keep_rebuilding", default=False,
help="Rebuild even if there are no updates to svn")
(options, args) = parser.parse_args()
client = pysvn.Client()
wc_path = r'@CMAKE_SOURCE_DIR@'
def do_build(clean_):
if clean_:
clean = 'clean'
else:
clean = ''
if os.name == 'nt':
cmd = 'nmake /I ' + clean + ' slave-start test slave-finish'
else:
cmd = 'make -i ' + clean + ' slave-start test slave-finish'
print "Starting build:\n>>> ", cmd
os.system(cmd)
if options.build_first:
do_build(options.clean_first)
while True:
try:
svn_entry = client.info(wc_path)
print "Wc has url %s rev %d.\nChecking for updates." \
% (svn_entry.url, svn_entry.revision.number)
ds = client.diff_summarize(url_or_path1=svn_entry.url,
revision1=pysvn.Revision(pysvn.opt_revision_kind.number,
svn_entry.revision.number),
url_or_path2=svn_entry.url,
revision2=pysvn.Revision(pysvn.opt_revision_kind.head)
)
if len(ds):
print "There are %d changesets:" % len(ds)
for j in ds:
print ">>>", j.path
print "Updating."
client.update(wc_path)
if len(ds) or options.keep_rebuilding:
do_build(options.clean_every_time)
else:
print "No updates."
except Exception, e:
print e
print "Error. Will retry."
print "Sleeping %d seconds" % @BOOST_BUILD_SLAVE_SLEEP_DURATION@
time.sleep(@BOOST_BUILD_SLAVE_SLEEP_DURATION@)

38
CMake/start.py.in Executable file
View File

@@ -0,0 +1,38 @@
#!/usr/bin/python
#
# copyright (C) 2008 troy d. straszheim <troy@resophonic.com>
#
# 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
#
#
# Start a new build, notify server via xmlrpc
#
import sys
sys.path.append("@BOOST_BUILD_SLAVE_PYTHONPATH@")
from boost_build_slave import *
print 'Url:', svn_entry.url, "at rev", svn_entry.revision.number
print 'FQDN:', fqdn
print 'Uname:', uname
print 'Toolset:', toolset
print '\nNotifying %s of new build via XML-RPC' % xmlrpc_url
s = xmlrpclib.Server(xmlrpc_url)
build_id = s.traash.start_build({ 'svn_url' : svn_entry.url,
'svn_rev' : svn_entry.revision.number,
'sysname' : uname[0],
'nodename' : uname[1],
'sys_release' : uname[2],
'sys_version' : uname[3],
'sys_machine' : uname[4],
'fqdn' : fqdn,
'toolset' : toolset,
'contact' : contact_info,
'details' : details() })
set_build_id(build_id)

6
CMake/unix_kill.py.in Executable file
View File

@@ -0,0 +1,6 @@
import os, signal
def kill_subprocess(pid):
os.kill(pid, signal.SIGKILL)
os.waitpid(-1, os.WNOHANG)

9
CMake/windows_kill.py.in Executable file
View File

@@ -0,0 +1,9 @@
import os
def kill_subprocess(pid):
cmd = 'TASKKILL /PID ' + str(pid) + ' /T /F'
print "Timeout, killing subprocess:\n" + cmd
os.popen(cmd)
import win32api, win32con
win32api.SetErrorMode( win32con.SEM_NOGPFAULTERRORBOX | win32con.SEM_FAILCRITICALERRORS )