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:
157
CMake/BoostBuildSlave.cmake
Normal file
157
CMake/BoostBuildSlave.cmake
Normal 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
161
CMake/BoostConfig.cmake
Normal 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
1360
CMake/BoostCore.cmake
Normal file
File diff suppressed because it is too large
Load Diff
520
CMake/BoostDocs.cmake
Normal file
520
CMake/BoostDocs.cmake
Normal 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
382
CMake/BoostTesting.cmake
Normal 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
213
CMake/BoostUtils.cmake
Normal 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
51
CMake/FindICU.cmake
Normal 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
57
CMake/boost_build_slave.py.in
Executable 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
9
CMake/catalog.xml.in
Normal 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
51
CMake/classify.py.in
Executable 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
23
CMake/finish.py.in
Executable 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
26
CMake/info.py.in
Executable 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
110
CMake/marshal.py.in
Executable 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
73
CMake/passthru.py.in
Executable 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
56
CMake/post.py.in
Executable 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)
|
||||
|
||||
82
CMake/run_continuous_slave.py.in
Executable file
82
CMake/run_continuous_slave.py.in
Executable 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
38
CMake/start.py.in
Executable 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
6
CMake/unix_kill.py.in
Executable 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
9
CMake/windows_kill.py.in
Executable 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 )
|
||||
|
||||
Reference in New Issue
Block a user