2
0
mirror of https://github.com/boostorg/build.git synced 2026-02-15 13:02:11 +00:00
Files
build/CMake/BoostCore.cmake
Troy D. Straszheim 1deaaf0b58 get mpi cmake tests working on trunk
[SVN r53156]
2009-05-21 15:36:35 +00:00

1445 lines
60 KiB
CMake

##########################################################################
# Core Functionality for Boost #
##########################################################################
# Copyright (C) 2007-2009 Douglas Gregor <doug.gregor@gmail.com> #
# Copyright (C) 2007-2009 Troy 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 #
##########################################################################
# Important developer macros in this file: #
# #
# boost_library_project: Defines a Boost library project (e.g., #
# Boost.Python). #
# #
# boost_add_library: Builds library binaries for Boost libraries #
# with compiled sources (e.g., boost_filesystem). #
# #
# boost_add_executable: Builds executables. #
##########################################################################
add_custom_target(modularize)
# Defines a Boost library project (e.g., for Boost.Python). Use as:
#
# boost_library_project(libname
# [SRCDIRS srcdir1 srcdir2 ...]
# [TESTDIRS testdir1 testdir2 ...]
# [DEPENDS lib1 lib2 ...]
# [DESCRIPTION description]
# [AUTHORS author1 author2 ...]
# [MAINTAINERS maint1 maint2 ...]
# [MODULARIZED])
#
# where libname is the name of the library (e.g., Python, or
# Filesystem), srcdir1, srcdir2, etc, are subdirectories containing
# library sources (for Boost libraries that build actual library
# binaries), and testdir1, testdir2, etc, are subdirectories
# containing regression tests. DEPENDS lists the names of the other
# Boost libraries that this library depends on. If the dependencies
# are not satisfied (e.g., because the library isn't present or its
# build is turned off), this library won't be built.
#
# DESCRIPTION provides a brief description of the library, which can
# be used to summarize the behavior of the library for a user. AUTHORS
# lists the authors of the library, while MAINTAINERS lists the active
# maintainers. If MAINTAINERS is left empty, it is assumed that the
# authors are still maintaining the library. Both authors and maintainers
# should have their name followed by their current e-mail address in
# angle brackets, with -at- instead of the at sign, e.g.,
# Douglas Gregor <doug.gregor -at- gmail.com>
#
# For libraries that build actual library binaries, this macro adds a
# option BUILD_BOOST_LIBNAME (which defaults to ON). When the option
# is ON, this macro will include the source subdirectories, and
# therefore, will build and install the library binary.
#
# For libraries that have regression tests, and when testing is
# enabled globally by the BUILD_REGRESSION_TESTS option, this macro also
# defines the TEST_BOOST_LIBNAME option (defaults to ON). When ON, the
# generated makefiles/project files will contain regression tests for
# this library.
#
# Example:
# boost_library_project(
# Thread
# SRCDIRS src
# TESTDIRS test
# )
macro(boost_library_project LIBNAME)
parse_arguments(THIS_PROJECT
"SRCDIRS;TESTDIRS;HEADERS;DOCDIRS;DESCRIPTION;AUTHORS;MAINTAINERS"
"MODULARIZED"
${ARGN}
)
# Set THIS_PROJECT_DEPENDS_ALL to the set of all of its
# dependencies, its dependencies' dependencies, etc., transitively.
string(TOUPPER "BOOST_${LIBNAME}_DEPENDS" THIS_PROJECT_DEPENDS)
set(THIS_PROJECT_DEPENDS_ALL ${${THIS_PROJECT_DEPENDS}})
set(ADDED_DEPS TRUE)
while (ADDED_DEPS)
set(ADDED_DEPS FALSE)
foreach(DEP ${THIS_PROJECT_DEPENDS_ALL})
string(TOUPPER "BOOST_${DEP}_DEPENDS" DEP_DEPENDS)
foreach(DEPDEP ${${DEP_DEPENDS}})
list(FIND THIS_PROJECT_DEPENDS_ALL ${DEPDEP} DEPDEP_INDEX)
if (DEPDEP_INDEX EQUAL -1)
list(APPEND THIS_PROJECT_DEPENDS_ALL ${DEPDEP})
set(ADDED_DEPS TRUE)
endif()
endforeach()
endforeach()
endwhile()
set(THIS_PROJECT_OKAY ON)
if(FALSE)
# This really isn't the check we want to do, especially when we
# hit circular dependencies. For now, just enable all libraries to
# be built all the time, until we can implement proper subsetting
# behavior at the CMake level.
set(THIS_PROJECT_FAILED_DEPS "")
foreach(DEP ${THIS_PROJECT_DEPENDS_ALL})
string(TOUPPER "BUILD_BOOST_${DEP}" BOOST_LIB_DEP)
if (NOT ${BOOST_LIB_DEP})
set(THIS_PROJECT_OKAY OFF)
set(THIS_PROJECT_FAILED_DEPS "${THIS_PROJECT_FAILED_DEPS} ${DEP}\n")
endif (NOT ${BOOST_LIB_DEP})
endforeach(DEP)
endif(FALSE)
if (THIS_PROJECT_SRCDIRS)
# This Boost library has source directories, so provide an option
# BUILD_BOOST_LIBNAME that allows one to turn on/off building of
# the library.
if (NOT THIS_PROJECT_OKAY)
if (${BOOST_BUILD_LIB_OPTION})
# The user explicitly turned on this library in a prior
# iteration, but it can no longer be built because one of the
# dependencies was turned off. Force this option off and
# complain about it.
set(${BOOST_BUILD_LIB_OPTION} OFF
CACHE BOOL "Build Boost.${LIBNAME} (prefer make targets, not this, to build individual libs)" FORCE)
message(SEND_ERROR
"Cannot build Boost.${LIBNAME} due to missing library dependencies:\n${THIS_PROJECT_FAILED_DEPS}")
endif (${BOOST_BUILD_LIB_OPTION})
endif (NOT THIS_PROJECT_OKAY)
endif (THIS_PROJECT_SRCDIRS)
if(THIS_PROJECT_OKAY)
string(TOLOWER "${LIBNAME}" libname)
string(TOUPPER "${LIBNAME}" ULIBNAME)
project(${LIBNAME})
if (THIS_PROJECT_MODULARIZED OR THIS_PROJECT_SRCDIRS)
# We only build a component group for modularized libraries or libraries
# that have compiled parts.
if (COMMAND cpack_add_component_group)
# Compute a reasonable description for this library.
if (THIS_PROJECT_DESCRIPTION)
set(THIS_PROJECT_DESCRIPTION "Boost.${LIBNAME}\n\n${THIS_PROJECT_DESCRIPTION}")
if (THIS_PROJECT_AUTHORS)
list(LENGTH THIS_PROJECT_AUTHORS THIS_PROJECT_NUM_AUTHORS)
if (THIS_PROJECT_NUM_AUTHORS EQUAL 1)
set(THIS_PROJECT_DESCRIPTION "${THIS_PROJECT_DESCRIPTION}\n\nAuthor: ")
else()
set(THIS_PROJECT_DESCRIPTION "${THIS_PROJECT_DESCRIPTION}\n\nAuthors: ")
endif()
set(THIS_PROJECT_FIRST_AUTHOR TRUE)
foreach(AUTHOR ${THIS_PROJECT_AUTHORS})
string(REGEX REPLACE " *-at- *" "@" AUTHOR ${AUTHOR})
if (THIS_PROJECT_FIRST_AUTHOR)
set(THIS_PROJECT_FIRST_AUTHOR FALSE)
else()
set(THIS_PROJECT_DESCRIPTION "${THIS_PROJECT_DESCRIPTION}\n ")
endif()
set(THIS_PROJECT_DESCRIPTION "${THIS_PROJECT_DESCRIPTION}${AUTHOR}")
endforeach(AUTHOR)
endif (THIS_PROJECT_AUTHORS)
if (THIS_PROJECT_MAINTAINERS)
list(LENGTH THIS_PROJECT_MAINTAINERS THIS_PROJECT_NUM_MAINTAINERS)
if (THIS_PROJECT_NUM_MAINTAINERS EQUAL 1)
set(THIS_PROJECT_DESCRIPTION "${THIS_PROJECT_DESCRIPTION}\nMaintainer: ")
else()
set(THIS_PROJECT_DESCRIPTION "${THIS_PROJECT_DESCRIPTION}\nMaintainers: ")
endif()
set(THIS_PROJECT_FIRST_MAINTAINER TRUE)
foreach(MAINTAINER ${THIS_PROJECT_MAINTAINERS})
string(REGEX REPLACE " *-at- *" "@" MAINTAINER ${MAINTAINER})
if (THIS_PROJECT_FIRST_MAINTAINER)
set(THIS_PROJECT_FIRST_MAINTAINER FALSE)
else()
set(THIS_PROJECT_DESCRIPTION "${THIS_PROJECT_DESCRIPTION}\n ")
endif()
set(THIS_PROJECT_DESCRIPTION "${THIS_PROJECT_DESCRIPTION}${MAINTAINER}")
endforeach(MAINTAINER)
endif (THIS_PROJECT_MAINTAINERS)
endif (THIS_PROJECT_DESCRIPTION)
# Create a component group for this library
fix_cpack_component_name(CPACK_COMPONENT_GROUP_NAME ${libname})
cpack_add_component_group(${CPACK_COMPONENT_GROUP_NAME}
DISPLAY_NAME "${LIBNAME}"
DESCRIPTION ${THIS_PROJECT_DESCRIPTION})
endif ()
endif ()
if (THIS_PROJECT_MODULARIZED)
# Add this module's include directory
include_directories("${Boost_SOURCE_DIR}/libs/${libname}/include")
#
# Horrible hackery. Make install of headers from modularized directories
# OPTIONAL, which only works on cmake >= 2.7
#
if (${CMAKE_MAJOR_VERSION} GREATER 1 AND ${CMAKE_MINOR_VERSION} GREATER 6)
set(_INSTALL_OPTIONAL "OPTIONAL")
endif()
# Install this module's headers
install(DIRECTORY include/boost
DESTINATION ${BOOST_HEADER_DIR}
${_INSTALL_OPTIONAL}
COMPONENT ${libname}_headers
PATTERN "CVS" EXCLUDE
PATTERN ".svn" EXCLUDE)
if (COMMAND cpack_add_component)
# Determine the header dependencies
set(THIS_PROJECT_HEADER_DEPENDS)
foreach(DEP ${${THIS_PROJECT_DEPENDS}})
string(TOLOWER ${DEP} dep)
if (${dep} STREQUAL "serialization")
# TODO: Ugly, ugly hack until the serialization library is modularized
elseif (${dep} STREQUAL "thread")
else()
list(APPEND THIS_PROJECT_HEADER_DEPENDS ${dep}_headers)
endif()
endforeach(DEP)
# Tell CPack about the headers component
fix_cpack_component_name(CPACK_COMPONENT_GROUP_NAME ${libname})
cpack_add_component(${libname}_headers
DISPLAY_NAME "Header files"
GROUP ${CPACK_COMPONENT_GROUP_NAME}
DEPENDS ${THIS_PROJECT_HEADER_DEPENDS})
endif ()
endif ()
#-- This is here to debug the modularize code
set(modularize_debug FALSE)
if (modularize_debug)
set(modularize_output ${Boost_BINARY_DIR})
set(modularize_libs_dir "modularize")
else (modularize_debug)
set(modularize_output ${Boost_SOURCE_DIR})
set(modularize_libs_dir "libs")
endif(modularize_debug)
# Modularization code
if(THIS_PROJECT_HEADERS)
set(${LIBNAME}-modularize-commands)
foreach(item ${THIS_PROJECT_HEADERS})
if(EXISTS "${Boost_SOURCE_DIR}/boost/${item}")
if(IS_DIRECTORY "${Boost_SOURCE_DIR}/boost/${item}")
list(APPEND ${LIBNAME}-modularize-commands
COMMAND "${CMAKE_COMMAND}" -E copy_directory
"${Boost_SOURCE_DIR}/boost/${item}"
"${modularize_output}/${modularize_libs_dir}/${libname}/include/boost/${item}"
)
if (NOT modularize_debug)
list(APPEND ${LIBNAME}-modularize-commands
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${Boost_SOURCE_DIR}/boost/${item}"
)
endif (NOT modularize_debug)
else(IS_DIRECTORY "${Boost_SOURCE_DIR}/boost/${item}")
list(APPEND ${LIBNAME}-modularize-commands
COMMAND "${CMAKE_COMMAND}" -E copy
"${Boost_SOURCE_DIR}/boost/${item}"
"${modularize_output}/${modularize_libs_dir}/${libname}/include/boost/${item}"
)
if (NOT modularize_debug)
list(APPEND ${LIBNAME}-modularize-commands
COMMAND "${CMAKE_COMMAND}" -E remove "${Boost_SOURCE_DIR}/boost/${item}"
)
endif (NOT modularize_debug)
endif(IS_DIRECTORY "${Boost_SOURCE_DIR}/boost/${item}")
elseif(EXISTS "${Boost_SOURCE_DIR}/${modularize_libs_dir}/${libname}/include/boost/${item}")
# Okay; already modularized
else()
message(SEND_ERROR
"Header or directory boost/${item} does not exist. The HEADERS argument in ${Boost_SOURCE_DIR}/${modularize_libs_dir}/${libname}/CMakeLists.txt should be updated.")
endif()
endforeach(item)
if (${LIBNAME}-modularize-commands)
set(${LIBNAME}-modularize-commands
# COMMAND "${CMAKE_COMMAND}" -E remove_directory "${modularize_output}/libs/${libname}/include"
COMMAND "${CMAKE_COMMAND}" -E make_directory
"${modularize_output}/${modularize_libs_dir}/${libname}/include/boost"
${${LIBNAME}-modularize-commands}
)
if (NOT modularize_debug)
set(${LIBNAME}-modularize-commands
COMMAND "${CMAKE_COMMAND}" -E remove_directory "${modularize_output}/${modularize_libs_dir}/${libname}/include"
${${LIBNAME}-modularize-commands}
)
endif (NOT modularize_debug)
add_custom_target(${LIBNAME}-modularize
${${LIBNAME}-modularize-commands}
COMMENT "Modularizing ${LIBNAME} headers to project-local dir from monolithic boost dir"
)
if(THIS_PROJECT_MODULARIZED)
add_dependencies(modularize ${LIBNAME}-modularize)
endif(THIS_PROJECT_MODULARIZED)
endif()
endif(THIS_PROJECT_HEADERS)
# For each of the modular libraries on which this project depends,
# add the include path for that library.
set(THIS_PROJECT_HAS_HEADER_DEPENDS FALSE)
foreach(DEP ${THIS_PROJECT_DEPENDS_ALL})
include_directories("${modularize_output}/${modularize_libs_dir}/${DEP}/include")
endforeach(DEP)
# TODO: is this still necessary?
if(NOT EXISTS ${CMAKE_BINARY_DIR}/bin/tests)
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/tests)
endif(NOT EXISTS ${CMAKE_BINARY_DIR}/bin/tests)
if(NOT EXISTS ${CMAKE_BINARY_DIR}/bin/tests/${PROJECT_NAME})
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/bin/tests/${PROJECT_NAME})
endif(NOT EXISTS ${CMAKE_BINARY_DIR}/bin/tests/${PROJECT_NAME})
# Include each of the source directories
if(THIS_PROJECT_SRCDIRS)
foreach(SUBDIR ${THIS_PROJECT_SRCDIRS})
add_subdirectory(${SUBDIR})
endforeach(SUBDIR ${THIS_PROJECT_SRCDIRS})
endif()
if(BUILD_REGRESSION_TESTS AND THIS_PROJECT_TESTDIRS)
# Testing is enabled globally and this project has some
# tests. Check whether we should include these tests.
if (BOOST_TEST_LIBRARIES)
set(SAVED_TESTDIRS ${THIS_PROJECT_TESTDIRS})
set(THIS_PROJECT_TESTDIRS)
foreach (TESTLIB ${BOOST_TEST_LIBRARIES})
if (${TESTLIB} STREQUAL ${libname})
# We are allowed to test this library; restore the set of
# test directories for this library.
set(THIS_PROJECT_TESTDIRS ${SAVED_TESTDIRS})
endif()
endforeach ()
endif()
# Create a target <library name>-test, which will run all of
# this library's tests.
if (THIS_PROJECT_TESTDIRS)
add_custom_target(${PROJECT_NAME}-test-drivers)
add_custom_target(${PROJECT_NAME}-test
COMMAND ${CMAKE_CTEST_COMMAND} -R "^${PROJECT_NAME}-*"
MESSAGE "Running tests for Boost.${PROJECT_NAME}...")
add_dependencies(${PROJECT_NAME}-test
${PROJECT_NAME}-test-drivers)
endif ()
# Include the test directories.
foreach(SUBDIR ${THIS_PROJECT_TESTDIRS})
add_subdirectory(${SUBDIR})
endforeach()
endif()
if (BUILD_DOCUMENTATION AND THIS_PROJECT_DOCDIRS)
foreach(SUBDIR ${THIS_PROJECT_DOCDIRS})
add_subdirectory(${SUBDIR})
endforeach(SUBDIR)
endif ()
endif()
endmacro(boost_library_project)
macro(boost_tool_project TOOLNAME)
parse_arguments(THIS_PROJECT
"DESCRIPTION;AUTHORS;MAINTAINERS"
""
${ARGN}
)
set(THIS_PROJECT_IS_TOOL TRUE)
string(TOUPPER ${TOOLNAME} UTOOLNAME)
set(THIS_PROJECT_OKAY ON)
set(THIS_PROJECT_FAILED_DEPS "")
foreach(DEP ${BOOST_${UTOOLNAME}_DEPENDS})
string(TOUPPER "BUILD_BOOST_${DEP}" BOOST_LIB_DEP)
if (NOT ${BOOST_LIB_DEP})
set(THIS_PROJECT_OKAY OFF)
set(THIS_PROJECT_FAILED_DEPS "${THIS_PROJECT_FAILED_DEPS} ${DEP}\n")
endif (NOT ${BOOST_LIB_DEP})
endforeach(DEP)
option(BUILD_${UTOOLNAME} "Build ${TOOLNAME}" ON)
if (NOT THIS_PROJECT_OKAY)
if (BUILD_${UTOOLNAME})
# The user explicitly turned on this tool in a prior
# iteration, but it can no longer be built because one of the
# dependencies was turned off. Force this option off and
# complain about it.
set(BUILD_${UTOOLNAME} OFF CACHE BOOL "Build ${TOOLNAME}" FORCE)
message(SEND_ERROR "Cannot build ${TOOLNAME} due to missing library dependencies:\n${THIS_PROJECT_FAILED_DEPS}")
endif ()
endif (NOT THIS_PROJECT_OKAY)
if(BUILD_${UTOOLNAME} AND THIS_PROJECT_OKAY)
string(TOLOWER "${TOOLNAME}" toolname)
project(${TOOLNAME})
# Add this module's include directory
include_directories("${Boost_SOURCE_DIR}/libs/${toolname}/include")
# For each of the modular libraries on which this project depends,
# add the include path for that library.
foreach(DEP ${BOOST_${UTOOLNAME}_DEPENDS})
string(TOUPPER ${DEP} UDEP)
include_directories("${Boost_SOURCE_DIR}/libs/${DEP}/include")
endforeach(DEP)
endif()
endmacro(boost_tool_project)
#TODO: Finish this documentation
# Defines dependencies of a boost project and testing targets. Use as:
#
# boost_module(libname
# DEPENDS srcdir1 srcdir2 ...
# TEST_DEPENDS testdir1 testdir2 ...
#
# Example:
# boost_library_project(
# Thread
# SRCDIRS src
# TESTDIRS test
# )
macro(boost_module LIBNAME)
parse_arguments(THIS_MODULE
"DEPENDS"
""
${ARGN}
)
# Export BOOST_${LIBNAME}_DEPENDS
string(TOUPPER "BOOST_${LIBNAME}_DEPENDS" THIS_MODULE_LIBNAME_DEPENDS)
set(${THIS_MODULE_LIBNAME_DEPENDS} ${THIS_MODULE_DEPENDS})
#
#message(STATUS "----------------------------------------------------------------")
#message(STATUS "LIBNAME: ${LIBNAME}")
#message(STATUS "THIS_MODULE_DEPENDS: ${THIS_MODULE_DEPENDS}")
#message(STATUS "THIS_MODULE_LIBNAME_DEPENDS: ${THIS_MODULE_LIBNAME_DEPENDS}")
#message(STATUS "${THIS_MODULE_LIBNAME_DEPENDS}: ${${THIS_MODULE_LIBNAME_DEPENDS}}")
#message(STATUS "THIS_MODULE_TEST_DEPENDS: ${THIS_MODULE_TEST_DEPENDS}")
#message(STATUS "THIS_MODULE_LIBNAME_TEST_DEPENDS: ${THIS_MODULE_LIBNAME_TEST_DEPENDS}")
#message(STATUS "${THIS_MODULE_LIBNAME_TEST_DEPENDS}: ${${THIS_MODULE_LIBNAME_TEST_DEPENDS}}")
endmacro(boost_module)
# This macro is an internal utility macro that builds the name of a
# particular variant of a library
#
# boost_library_variant_target_name(feature1 feature2 ...)
#
# where feature1, feature2, etc. are the names of features to be
# included in this variant, e.g., MULTI_THREADED, DEBUG.
#
# This macro sets three macros:
#
# VARIANT_TARGET_NAME: The suffix that should be appended to the
# name of the library target to name this variant of the
# library. For example, this might be "-mt-static" for a static,
# multi-threaded variant. It should be used to name the CMake
# library target, e.g., boost_signals-mt-static.
#
# VARIANT_VERSIONED_NAME: The suffix that will be added to the name
# of the generated library, containing information about the
# particular version of the library and the toolset used to build
# this library. For example, this might be "-gcc41-mt-1_34" for the
# multi-threaded, release variant of the library in Boost 1.34.0 as
# compiled with GCC 4.1. If option BUILD_VERSIONED is OFF, this
# variable is set to the empty string.
#
# VARIANT_DISPLAY_NAME: The display name that describes this
# variant, e.g., "Debug, static, multi-threaded".
#
macro(boost_library_variant_target_name)
set(VARIANT_TARGET_NAME "")
# The versioned name starts with the full Boost toolset
if(BUILD_VERSIONED)
set(VARIANT_VERSIONED_NAME "-${BOOST_TOOLSET}")
else(BUILD_VERSIONED)
set(VARIANT_VERSIONED_NAME "")
endif(BUILD_VERSIONED)
# Add -mt for multi-threaded libraries
list_contains(VARIANT_IS_MT MULTI_THREADED ${ARGN})
if (VARIANT_IS_MT)
set(VARIANT_TARGET_NAME "${VARIANT_TARGET_NAME}-mt")
# If we're creating versioned names, tack on "-mt"
set(VARIANT_VERSIONED_NAME "${VARIANT_VERSIONED_NAME}-mt")
endif (VARIANT_IS_MT)
# Add -static for static libraries, -shared for shared libraries
list_contains(VARIANT_IS_STATIC STATIC ${ARGN})
if (VARIANT_IS_STATIC)
set(VARIANT_TARGET_NAME "${VARIANT_TARGET_NAME}-static")
set(VARIANT_DISPLAY_NAME "Static")
else (VARIANT_IS_STATIC)
set(VARIANT_TARGET_NAME "${VARIANT_TARGET_NAME}-shared")
set(VARIANT_DISPLAY_NAME "Shared")
endif (VARIANT_IS_STATIC)
# Add "multi-threaded" to the display name for multithreaded libraries.
if (VARIANT_IS_MT)
set(VARIANT_DISPLAY_NAME "${VARIANT_DISPLAY_NAME}, multi-threaded")
endif ()
# Compute the ABI tag, which depends on various kinds of options
set(VARIANT_ABI_TAG "")
# Linking statically to the runtime library
list_contains(VARIANT_IS_STATIC_RUNTIME STATIC_RUNTIME ${ARGN})
if (VARIANT_IS_STATIC_RUNTIME)
set(VARIANT_TARGET_NAME "${VARIANT_TARGET_NAME}-staticrt")
set(VARIANT_ABI_TAG "${VARIANT_ABI_TAG}s")
set(VARIANT_DISPLAY_NAME "${VARIANT_DISPLAY_NAME}, static runtime")
endif (VARIANT_IS_STATIC_RUNTIME)
# Using the debug version of the runtime library.
# With Visual C++, this comes automatically with debug
if (MSVC)
list_contains(VARIANT_IS_DEBUG DEBUG ${ARGN})
if (VARIANT_IS_DEBUG)
set(VARIANT_ABI_TAG "${VARIANT_ABI_TAG}g")
endif (VARIANT_IS_DEBUG)
endif (MSVC)
# Add -pydebug for debug builds of Python
list_contains(VARIANT_IS_PYDEBUG PYTHON_DEBUG ${ARGN})
if (VARIANT_IS_PYDEBUG)
set(VARIANT_TARGET_NAME "${VARIANT_TARGET_NAME}-pydebug")
set(VARIANT_ABI_TAG "${VARIANT_ABI_TAG}y")
set(VARIANT_DISPLAY_NAME "${VARIANT_DISPLAY_NAME}, Python debugging")
endif (VARIANT_IS_PYDEBUG)
# TODO: STLport rather than default library
# TODO: STLport's deprecated iostreams
# Add -debug for debug libraries
list_contains(VARIANT_IS_DEBUG DEBUG ${ARGN})
if (VARIANT_IS_DEBUG)
# Only add the actual "-debug" if we're also building release libraries
if (BUILD_RELEASE)
set(VARIANT_TARGET_NAME "${VARIANT_TARGET_NAME}-debug")
endif (BUILD_RELEASE)
set(VARIANT_ABI_TAG "${VARIANT_ABI_TAG}d")
set(VARIANT_DISPLAY_NAME "${VARIANT_DISPLAY_NAME}, debug")
else()
set(VARIANT_DISPLAY_NAME "${VARIANT_DISPLAY_NAME}, release")
endif()
# If there is an ABI tag, append it to the versioned name
if (VARIANT_ABI_TAG)
set(VARIANT_VERSIONED_NAME "${VARIANT_VERSIONED_NAME}-${VARIANT_ABI_TAG}")
endif (VARIANT_ABI_TAG)
if(BUILD_VERSIONED)
# Append the Boost version number to the versioned name
if(BOOST_VERSION_SUBMINOR GREATER 0)
set(VARIANT_VERSIONED_NAME
"${VARIANT_VERSIONED_NAME}-${BOOST_VERSION_MAJOR}_${BOOST_VERSION_MINOR}_${BOOST_VERSION_SUBMINOR}")
else(BOOST_VERSION_SUBMINOR GREATER 0)
set(VARIANT_VERSIONED_NAME
"${VARIANT_VERSIONED_NAME}-${BOOST_VERSION_MAJOR}_${BOOST_VERSION_MINOR}")
endif(BOOST_VERSION_SUBMINOR GREATER 0)
endif(BUILD_VERSIONED)
endmacro(boost_library_variant_target_name)
# This macro is an internal utility macro that updates compilation and
# linking flags based on interactions among the features in a variant.
#
# boost_feature_interactions(prefix
# feature1 feature2 ...)
#
# where "prefix" is the prefix of the compilation and linking flags
# that will be updated (e.g., ${prefix}_COMPILE_FLAGS). feature1,
# feature2, etc. are the names of the features used in this particular
# variant. If the features in this variant conflict, set
# ${prefix}_OKAY to FALSE.
macro(boost_feature_interactions PREFIX)
# Don't build or link against a shared library and a static run-time
list_contains(IS_SHARED SHARED ${ARGN})
list_contains(IS_STATIC_RUNTIME STATIC_RUNTIME ${ARGN})
if (IS_SHARED AND IS_STATIC_RUNTIME)
set(${PREFIX}_OKAY FALSE)
endif (IS_SHARED AND IS_STATIC_RUNTIME)
# With Visual C++, the dynamic runtime is multi-threaded only
if (MSVC)
list_contains(IS_DYNAMIC_RUNTIME DYNAMIC_RUNTIME ${ARGN})
list_contains(IS_SINGLE_THREADED SINGLE_THREADED ${ARGN})
if (IS_DYNAMIC_RUNTIME AND IS_SINGLE_THREADED)
set(${PREFIX}_OKAY FALSE)
endif (IS_DYNAMIC_RUNTIME AND IS_SINGLE_THREADED)
endif (MSVC)
# Visual C++-specific runtime library flags
if(MSVC)
list_contains(IS_STATIC_RUNTIME STATIC_RUNTIME ${ARGN})
list_contains(IS_DEBUG DEBUG ${ARGN})
if(IS_DEBUG)
if(IS_STATIC_RUNTIME)
set(${PREFIX}_COMPILE_FLAGS "/MTd ${${PREFIX}_COMPILE_FLAGS}")
else(IS_STATIC_RUNTIME)
set(${PREFIX}_COMPILE_FLAGS "/MDd ${${PREFIX}_COMPILE_FLAGS}")
endif(IS_STATIC_RUNTIME)
else(IS_DEBUG)
if(IS_STATIC_RUNTIME)
set(${PREFIX}_COMPILE_FLAGS "/MT ${${PREFIX}_COMPILE_FLAGS}")
else(IS_STATIC_RUNTIME)
set(${PREFIX}_COMPILE_FLAGS "/MD ${${PREFIX}_COMPILE_FLAGS}")
endif(IS_STATIC_RUNTIME)
endif(IS_DEBUG)
endif(MSVC)
endmacro(boost_feature_interactions)
# This macro is an internal utility macro that builds a particular
# variant of a boost library.
#
# boost_library_variant(libname
# feature1 feature2 ...)
#
# where libname is the name of the Boost library (e.g.,
# "boost_filesystem") and feature1, feature2, ... are the features
# that will be used in this variant.
#
# This macro will define a new library target based on libname and the
# specific variant name (see boost_library_variant_target_name), which
# depends on the utility target libname. The compilation and linking
# flags for this library are defined by THIS_LIB_COMPILE_FLAGS,
# THIS_LIB_LINK_FLAGS, THIS_LIB_LINK_LIBS, and all of the compile and
# linking flags implied by the features provided.
#
# If any of the features listed conflict with this library, no new
# targets will be built. For example, if the library provides the
# option NO_MULTI_THREADED, and one of the features provided is
# MULTI_THREADED, this macro will essentially be a no-op.
macro(boost_library_variant LIBNAME)
set(THIS_VARIANT_COMPILE_FLAGS "${THIS_LIB_COMPILE_FLAGS}")
set(THIS_VARIANT_LINK_FLAGS "${THIS_LIB_LINK_FLAGS}")
set(THIS_VARIANT_LINK_LIBS ${THIS_LIB_LINK_LIBS})
# Determine if it is okay to build this variant
set(THIS_VARIANT_OKAY TRUE)
foreach(ARG ${ARGN})
# If the library itself stated that we cannot build this variant,
# don't. For example, we're trying to build a shared library
# variant, but the user specified NO_SHARED in the requirements of
# the library.
if (THIS_LIB_NO_${ARG})
set(THIS_VARIANT_OKAY FALSE)
endif (THIS_LIB_NO_${ARG})
# If the user specified that we should not build any variants of
# this kind, don't. For example, if the BUILD_SHARED option is
# off, don't build shared libraries.
if(NOT BUILD_${ARG})
set(THIS_VARIANT_OKAY FALSE)
endif(NOT BUILD_${ARG})
# Accumulate compile and link flags
set(THIS_VARIANT_COMPILE_FLAGS "${THIS_VARIANT_COMPILE_FLAGS} ${THIS_LIB_${ARG}_COMPILE_FLAGS} ${${ARG}_COMPILE_FLAGS}")
set(THIS_VARIANT_LINK_FLAGS "${THIS_VARIANT_LINK_FLAGS} ${THIS_LIB_${ARG}_LINK_FLAGS} ${${ARG}_LINK_FLAGS}")
set(THIS_VARIANT_LINK_LIBS ${THIS_VARIANT_LINK_LIBS} ${THIS_LIB_${ARG}_LINK_LIBS} ${${ARG}_LINK_LIBS})
endforeach(ARG ${ARGN})
# Handle feature interactions
boost_feature_interactions("THIS_VARIANT" ${ARGN})
if (THIS_VARIANT_OKAY)
# Determine the suffix for this library target
boost_library_variant_target_name(${ARGN})
set(VARIANT_LIBNAME "${LIBNAME}${VARIANT_TARGET_NAME}")
# We handle static vs. dynamic libraries differently
list_contains(THIS_LIB_IS_STATIC "STATIC" ${ARGN})
if (THIS_LIB_IS_STATIC)
# On Windows, we need static and shared libraries to have
# different names, so we follow the Boost.Build version 2 style
# and prepend "lib" to the name.
if(WIN32 AND NOT CYGWIN)
set(LIBPREFIX "lib")
else(WIN32 AND NOT CYGWIN)
set(LIBPREFIX "")
endif(WIN32 AND NOT CYGWIN)
# Add the library itself
add_library(${VARIANT_LIBNAME} STATIC ${THIS_LIB_SOURCES})
# Set properties on this library
set_target_properties(${VARIANT_LIBNAME}
PROPERTIES
OUTPUT_NAME "${LIBPREFIX}${LIBNAME}${VARIANT_VERSIONED_NAME}"
CLEAN_DIRECT_OUTPUT 1
COMPILE_FLAGS "${THIS_VARIANT_COMPILE_FLAGS}"
LINK_FLAGS "${THIS_VARIANT_LINK_FLAGS}"
LABELS "${PROJECT_NAME}"
)
elseif (THIS_LIB_MODULE)
# Add a module
add_library(${VARIANT_LIBNAME} MODULE ${THIS_LIB_SOURCES})
# Set properties on this library
set_target_properties(${VARIANT_LIBNAME}
PROPERTIES
OUTPUT_NAME ${LIBNAME}
CLEAN_DIRECT_OUTPUT 1
COMPILE_FLAGS "${THIS_VARIANT_COMPILE_FLAGS}"
LINK_FLAGS "${THIS_VARIANT_LINK_FLAGS}"
LABELS "${PROJECT_NAME}"
PREFIX ""
# SOVERSION "${BOOST_VERSION}"
)
else (THIS_LIB_IS_STATIC)
#TODO: Check the SOVERSION behavior on Linux and Windows
# Add a module
add_library(${VARIANT_LIBNAME} SHARED ${THIS_LIB_SOURCES})
# Set properties on this library
set_target_properties(${VARIANT_LIBNAME}
PROPERTIES
OUTPUT_NAME "${LIBNAME}${VARIANT_VERSIONED_NAME}"
CLEAN_DIRECT_OUTPUT 1
COMPILE_FLAGS "${THIS_VARIANT_COMPILE_FLAGS}"
LINK_FLAGS "${THIS_VARIANT_LINK_FLAGS}"
LABELS "${PROJECT_NAME}"
# SOVERSION "${BOOST_VERSION}"
)
endif (THIS_LIB_IS_STATIC)
# The basic LIBNAME target depends on each of the variants
add_dependencies(${LIBNAME} ${VARIANT_LIBNAME})
export(TARGETS ${VARIANT_LIBNAME} FILE ${CMAKE_BINARY_DIR}/exports/${VARIANT_LIBNAME}.cmake)
# Link against whatever libraries this library depends on
target_link_libraries(${VARIANT_LIBNAME} ${THIS_VARIANT_LINK_LIBS})
foreach(dependency ${THIS_LIB_DEPENDS})
target_link_libraries(${VARIANT_LIBNAME} "${dependency}${VARIANT_TARGET_NAME}")
endforeach(dependency)
if(NOT THIS_LIB_NO_INSTALL)
# Setup installation properties
string(TOLOWER "${PROJECT_NAME}${VARIANT_TARGET_NAME}" LIB_COMPONENT)
string(REPLACE "-" "_" LIB_COMPONENT ${LIB_COMPONENT})
# Installation of this library variant
string(TOLOWER ${PROJECT_NAME} libname)
install(TARGETS ${VARIANT_LIBNAME} DESTINATION lib COMPONENT ${LIB_COMPONENT})
set_property(
TARGET ${VARIANT_LIBNAME}
PROPERTY BOOST_CPACK_COMPONENT
${LIB_COMPONENT})
# Make the library installation component dependent on the library
# installation components of dependent libraries.
set(THIS_LIB_COMPONENT_DEPENDS)
foreach(DEP ${THIS_LIB_DEPENDS})
# We ask the library variant that this library depends on to tell us
# what it's associated installation component is. We depend on that
# installation component.
get_property(DEP_COMPONENT
TARGET "${DEP}${VARIANT_TARGET_NAME}"
PROPERTY BOOST_CPACK_COMPONENT)
if (DEP_COMPONENT)
if (DEP_COMPONENT STREQUAL LIB_COMPONENT)
# Do nothing: we have library dependencies within one
# Boost library
else()
list(APPEND THIS_LIB_COMPONENT_DEPENDS ${DEP_COMPONENT})
endif()
endif()
endforeach(DEP)
if (COMMAND cpack_add_component)
fix_cpack_component_name(CPACK_COMPONENT_GROUP_NAME ${libname})
cpack_add_component(${LIB_COMPONENT}
DISPLAY_NAME "${VARIANT_DISPLAY_NAME}"
GROUP ${CPACK_COMPONENT_GROUP_NAME}
DEPENDS ${THIS_LIB_COMPONENT_DEPENDS})
endif ()
endif(NOT THIS_LIB_NO_INSTALL)
endif ()
endmacro(boost_library_variant)
# Updates the set of default build variants to account for variations
# in the given feature.
#
# boost_add_default_variant(feature-val1 feature-val2 ...)
#
# Each new feature creates a new set of build variants using that
# feature. For example, writing:
#
# boost_add_default_variant(SINGLE_THREADED MULTI_THREADED)
#
# will create single- and multi-threaded variants of every default
# library variant already defined, doubling the number of variants
# that will be built. See the top-level CMakeLists.txt for the set of
# default variants.
#
# Variables affected:
#
# BOOST_DEFAULT_VARIANTS:
# This variable describes all of the variants that will be built
# by default, and will be updated with each invocation of
# boost_add_default_variant. The variable itself is a list, where
# each element in the list contains a colon-separated string
# naming a specific set of features for that variant, e.g.,
# STATIC:DEBUG:SINGLE_THREADED.
#
# BOOST_FEATURES:
# This variable describes all of the feature sets that we know about,
# and will be extended each time ither boost_add_default_variant or
# boost_add_extra_variant is invoked. This macro will contain a list
# of feature sets, each containing the values for a given feature
# separated by colons, e.g., "DEBUG:RELEASE".
#
# BOOST_ADD_ARG_NAMES:
# This variable describes all of the feature-specific arguments
# that can be used for the boost_add_library macro, separated by
# semicolons. For example, given the use of
# boost_add_default_variant above, this variable will contain (at
# least)
#
# SINGLE_THREADED_COMPILE_FLAGS;SINGLE_THREADED_LINK_FLAGS;
# MULTI_THREADED_COMPILE_FLAGS;MULTI_THREADED_LINK_FLAGS
#
# When this variable is used in boost_add_library, it turns these
# names into feature-specific options. For example,
# MULTI_THREADED_COMPILE_FLAGS provides extra compile flags to be
# used only for multi-threaded variants of the library.
#
# BOOST_ADDLIB_OPTION_NAMES:
# Like BOOST_ADD_ARG_NAMES, this variable describes
# feature-specific options to boost_add_library that can be used to
# turn off building of the library when the variant would require
# certain features. For example, the NO_SINGLE_THREADED option
# turns off building of single-threaded variants for a library.
#
# BOOST_ADDEXE_OPTION_NAMES:
# Like BOOST_ADDLIB_OPTION_NAMES, except that that variable
# describes options to boost_add_executable that can be used to
# describe which features are needed to build the executable.
# For example, the MULTI_THREADED option requires that the
# executable be built against multi-threaded libraries and with
# multi-threaded options.
macro(boost_add_default_variant)
# Update BOOST_DEFAULT_VARIANTS
if (BOOST_DEFAULT_VARIANTS)
set(BOOST_DEFAULT_VARIANTS_ORIG ${BOOST_DEFAULT_VARIANTS})
set(BOOST_DEFAULT_VARIANTS)
foreach(VARIANT ${BOOST_DEFAULT_VARIANTS_ORIG})
foreach(FEATURE ${ARGN})
list(APPEND BOOST_DEFAULT_VARIANTS "${VARIANT}:${FEATURE}")
endforeach(FEATURE ${ARGN})
endforeach(VARIANT ${BOOST_DEFAULT_VARIANTS_ORIG})
set(BOOST_DEFAULT_VARIANTS_ORIG)
else (BOOST_DEFAULT_VARIANTS)
set(BOOST_DEFAULT_VARIANTS ${ARGN})
endif (BOOST_DEFAULT_VARIANTS)
# Set Feature flag options used by the boost_library macro and the
# BOOST_FEATURES variable
set(BOOST_DEFVAR_FEATURES)
foreach(FEATURE ${ARGN})
set(BOOST_ADD_ARG_NAMES
"${BOOST_ADD_ARG_NAMES};${FEATURE}_COMPILE_FLAGS;${FEATURE}_LINK_FLAGS;${FEATURE}_LINK_LIBS")
set(BOOST_ADDLIB_OPTION_NAMES "${BOOST_ADDLIB_OPTION_NAMES};NO_${FEATURE}")
set(BOOST_ADDEXE_OPTION_NAMES "${BOOST_ADDEXE_OPTION_NAMES};${FEATURE}")
if (BOOST_DEFVAR_FEATURES)
set(BOOST_DEFVAR_FEATURES "${BOOST_DEFVAR_FEATURES}:${FEATURE}")
else (BOOST_DEFVAR_FEATURES)
set(BOOST_DEFVAR_FEATURES "${FEATURE}")
endif (BOOST_DEFVAR_FEATURES)
endforeach(FEATURE ${ARGN})
list(APPEND BOOST_FEATURES ${BOOST_DEFVAR_FEATURES})
endmacro(boost_add_default_variant)
# Updates the set of "extra" build variants, which may be used to
# generate extra, library-specific variants of libraries.
#
# boost_add_extra_variant(feature-val1 feature-val2 ...)
#
# Each extra viarant makes it possible for libraries to define extra
# variants. For example, writing:
#
# boost_add_extra_variant(PYTHON_NODEBUG PYTHON_DEBUG)
#
# creates a PYTHON_NODEBUG/PYTHON_DEBUG feature pair as an extra
# variant, used by the Boost.Python library, which generates separate
# variants of the Boost.Python library: one variant uses the Python
# debug libraries, the other does not.
#
# The difference between boost_add_default_variant and
# boost_add_extra_variant is that adding a new default variant
# introduces additional variants to *all* Boost libraries, unless
# those variants are explicitly excluded by the library. Adding a new
# extra variant, on the other hand, allows libraries to specifically
# request extra variants using that feature.
#
# Variables affected:
#
# BOOST_FEATURES:
# See boost_add_default_variant.
#
# BOOST_ADD_ARG_NAMES:
# See boost_add_default_variant.
#
# BOOST_ADDLIB_OPTION_NAMES:
# See boost_add_default_variant.
#
# BOOST_ADDEXE_OPTION_NAMES:
# See boost_add_default_variant.
macro(boost_add_extra_variant)
set(BOOST_EXTVAR_FEATURES)
foreach(FEATURE ${ARGN})
set(BOOST_ADD_ARG_NAMES
"${BOOST_ADD_ARG_NAMES};${FEATURE}_COMPILE_FLAGS;${FEATURE}_LINK_FLAGS;${FEATURE}_LINK_LIBS")
set(BOOST_ADDLIB_OPTION_NAMES "${BOOST_ADDLIB_OPTION_NAMES};NO_${FEATURE}")
set(BOOST_ADDEXE_OPTION_NAMES "${BOOST_ADDEXE_OPTION_NAMES};${FEATURE}")
if (BOOST_EXTVAR_FEATURES)
set(BOOST_EXTVAR_FEATURES "${BOOST_EXTVAR_FEATURES}:${FEATURE}")
else (BOOST_EXTVAR_FEATURES)
set(BOOST_EXTVAR_FEATURES "${FEATURE}")
endif (BOOST_EXTVAR_FEATURES)
endforeach(FEATURE ${ARGN})
list(APPEND BOOST_FEATURES ${BOOST_EXTVAR_FEATURES})
endmacro(boost_add_extra_variant)
# Compute the variant that will be used to build this executable or
# module, taking into account both the requested features passed to
# boost_add_executable or boost_add_library and what options the user
# has set.
macro(boost_select_variant NAME PREFIX)
set(${PREFIX}_DEBUG_AND_RELEASE FALSE)
set(SELECT_VARIANT_OKAY TRUE)
set(${PREFIX}_VARIANT)
foreach(FEATURESET_STR ${BOOST_FEATURES})
string(REPLACE ":" ";" FEATURESET ${FEATURESET_STR})
separate_arguments(FEATURESET)
set(${PREFIX}_REQUESTED_FROM_SET FALSE)
foreach (FEATURE ${FEATURESET})
if (${PREFIX}_${FEATURE})
# Make this feature part of the variant
list(APPEND ${PREFIX}_VARIANT ${FEATURE})
set(${PREFIX}_REQUESTED_FROM_SET TRUE)
# The caller has requested this particular feature be used
# when building the executable or module. If we can't satisfy
# that request (because the user has turned off the build
# variants with that feature), then we won't build this
# executable or module.
if (NOT BUILD_${FEATURE})
set(SELECT_VARIANT_OKAY FALSE)
message(STATUS "* ${NAME} is NOT being built because BUILD_${FEATURE} is FALSE")
endif (NOT BUILD_${FEATURE})
endif (${PREFIX}_${FEATURE})
endforeach (FEATURE ${FEATURESET})
if (NOT ${PREFIX}_REQUESTED_FROM_SET)
# The caller did not specify which feature value to use from
# this set, so find the first feature value that actually works.
set(${PREFIX}_FOUND_FEATURE FALSE)
# If this feature set decides between Release and Debug, we
# either query CMAKE_BUILD_TYPE to determine which to use (for
# makefile targets) or handle both variants separately (for IDE
# targets). We only build both variants separately for executable targets.
if (FEATURESET_STR STREQUAL "RELEASE:DEBUG")
if (CMAKE_CONFIGURATION_TYPES)
# IDE target: can we build both debug and release?
if (BUILD_DEBUG AND BUILD_RELEASE)
if (${PREFIX} STREQUAL "THIS_EXE")
# Remember that we're capable of building both configurations
set(${PREFIX}_DEBUG_AND_RELEASE TRUE)
# Don't add RELEASE or DEBUG to the variant (yet)
set(${PREFIX}_FOUND_FEATURE TRUE)
endif ()
endif ()
else (CMAKE_CONFIGURATION_TYPES)
# Makefile target: CMAKE_BUILD_TYPE tells us which variant to build
if (CMAKE_BUILD_TYPE STREQUAL "Release")
# Okay, build the release variant
list(APPEND ${PREFIX}_VARIANT RELEASE)
set(${PREFIX}_FOUND_FEATURE TRUE)
elseif (CMAKE_BUILD_TYPE STREQUAL "Debug")
# Okay, build the debug variant
list(APPEND ${PREFIX}_VARIANT DEBUG)
set(${PREFIX}_FOUND_FEATURE TRUE)
endif (CMAKE_BUILD_TYPE STREQUAL "Release")
endif (CMAKE_CONFIGURATION_TYPES)
endif (FEATURESET_STR STREQUAL "RELEASE:DEBUG")
# Search through all of the features in the set to find one that works
foreach (FEATURE ${FEATURESET})
# We only care about the first feature value we find...
if (NOT ${PREFIX}_FOUND_FEATURE)
# Are we allowed to build this feature?
if (BUILD_${FEATURE})
# Found it: we're done
list(APPEND ${PREFIX}_VARIANT ${FEATURE})
set(${PREFIX}_FOUND_FEATURE TRUE)
endif (BUILD_${FEATURE})
endif (NOT ${PREFIX}_FOUND_FEATURE)
endforeach (FEATURE ${FEATURESET})
if (NOT ${PREFIX}_FOUND_FEATURE)
# All of the features in this set were turned off.
# Just don't build anything.
set(SELECT_VARIANT_OKAY FALSE)
endif (NOT ${PREFIX}_FOUND_FEATURE)
endif (NOT ${PREFIX}_REQUESTED_FROM_SET)
endforeach(FEATURESET_STR ${BOOST_FEATURES})
# Propagate flags from each of the features
if (SELECT_VARIANT_OKAY)
foreach (FEATURE ${${PREFIX}_VARIANT})
# Add all of the flags for this feature
set(${PREFIX}_COMPILE_FLAGS
"${${PREFIX}_COMPILE_FLAGS} ${${PREFIX}_${FEATURE}_COMPILE_FLAGS} ${${FEATURE}_COMPILE_FLAGS}")
set(${PREFIX}_LINK_FLAGS
"${${PREFIX}_LINK_FLAGS} ${${PREFIX}_${FEATURE}_LINK_FLAGS} ${${FEATURE}_LINK_FLAGS}")
if (${PREFIX} STREQUAL "THIS_EXE")
set(${PREFIX}_LINK_FLAGS
"${${PREFIX}_LINK_FLAGS} ${${FEATURE}_EXE_LINK_FLAGS}")
endif()
set(${PREFIX}_LINK_LIBS
${${PREFIX}_LINK_LIBS} ${${PREFIX}_${FEATURE}_LINK_LIBS} ${${FEATURE}_LINK_LIBS})
endforeach (FEATURE ${${PREFIX}_VARIANT})
# Handle feature interactions
boost_feature_interactions("${PREFIX}" ${${PREFIX}_VARIANT})
else ()
set(${PREFIX}_VARIANT)
endif ()
endmacro(boost_select_variant)
# Creates a new Boost library target that generates a compiled library
# (.a, .lib, .dll, .so, etc) from source files. This routine will
# actually build several different variants of the same library, with
# different compilation options, as determined by the set of "default"
# library variants.
#
# boost_add_library(libname
# source1 source2 ...
# [COMPILE_FLAGS compileflags]
# [feature_COMPILE_FLAGS compileflags]
# [LINK_FLAGS linkflags]
# [feature_LINK_FLAGS linkflags]
# [LINK_LIBS linklibs]
# [feature_LINK_LIBS linklibs]
# [DEPENDS libdepend1 libdepend2 ...]
# [MODULE]
# [NO_feature]
# [EXTRA_VARIANTS variant1 variant2 ...]
# [FORCE_VARIANTS variant1])
#
# where libname is the name of Boost library binary (e.g.,
# "boost_regex") and source1, source2, etc. are the source files used
# to build the library, e.g., cregex.cpp.
#
# This macro has a variety of options that affect its behavior. In
# several cases, we use the placeholder "feature" in the option name
# to indicate that there are actually several different kinds of
# options, each referring to a different build feature, e.g., shared
# libraries, multi-threaded, debug build, etc. For a complete listing
# of these features, please refer to the CMakeLists.txt file in the
# root of the Boost distribution, which defines the set of features
# that will be used to build Boost libraries by default.
#
# The options that affect this macro's behavior are:
#
# COMPILE_FLAGS: Provides additional compilation flags that will be
# used when building all variants of the library. For example, one
# might want to add "-DBOOST_SIGNALS_NO_LIB=1" through this option
# (which turns off auto-linking for the Signals library while
# building it).
#
# feature_COMPILE_FLAGS: Provides additional compilation flags that
# will be used only when building variants of the library that
# include the given feature. For example,
# MULTI_THREADED_COMPILE_FLAGS are additional flags that will be
# used when building a multi-threaded variant, while
# SHARED_COMPILE_FLAGS will be used when building a shared library
# (as opposed to a static library).
#
# LINK_FLAGS: Provides additional flags that will be passed to the
# linker when linking each variant of the library. This option
# should not be used to link in additional libraries; see LINK_LIBS
# and DEPENDS.
#
# feature_LINK_FLAGS: Provides additional flags that will be passed
# to the linker when building variants of the library that contain a
# specific feature, e.g., MULTI_THREADED_LINK_FLAGS. This option
# should not be used to link in additional libraries; see
# feature_LINK_LIBS.
#
# LINK_LIBS: Provides additional libraries against which each of the
# library variants will be linked. For example, one might provide
# "expat" as options to LINK_LIBS, to state that each of the library
# variants will link against the expat library binary. Use LINK_LIBS
# for libraries external to Boost; for Boost libraries, use DEPENDS.
#
# feature_LINK_LIBS: Provides additional libraries for specific
# variants of the library to link against. For example,
# MULTI_THREADED_LINK_LIBS provides extra libraries to link into
# multi-threaded variants of the library.
#
# DEPENDS: States that this Boost library depends on and links
# against another Boost library. The arguments to DEPENDS should be
# the unversioned name of the Boost library, such as
# "boost_filesystem". Like LINK_LIBS, this option states that all
# variants of the library being built will link against the stated
# libraries. Unlike LINK_LIBS, however, DEPENDS takes particular
# library variants into account, always linking the variant of one
# Boost library against the same variant of the other Boost
# library. For example, if the boost_mpi_python library DEPENDS on
# boost_python, multi-threaded variants of boost_mpi_python will
# link against multi-threaded variants of boost_python.
#
# MODULE: This option states that, when building a shared library,
# the shared library should be built as a module rather than a
# normal shared library. Modules have special meaning an behavior on
# some platforms, such as Mac OS X.
#
# NOT_feature: States that library variants containing a particular
# feature should not be built. For example, passing
# NOT_SINGLE_THREADED suppresses generation of single-threaded
# variants of this library.
#
# EXTRA_VARIANTS: Specifies that extra variants of this library
# should be built, based on the features listed. Each "variant" is a
# colon-separated list of features. For example, passing
# EXTRA_VARIANTS "PYTHON_NODEBUG:PYTHON_DEBUG"
# will result in the creation of an extra set of library variants,
# some with the PYTHON_NODEBUG feature and some with the
# PYTHON_DEBUG feature.
#
# FORCE_VARIANTS: This will force the build system to ALWAYS build this
# variant of the library not matter what variants are set.
#
# Example:
# boost_add_library(
# boost_thread
# barrier.cpp condition.cpp exceptions.cpp mutex.cpp once.cpp
# recursive_mutex.cpp thread.cpp tss_hooks.cpp tss_dll.cpp tss_pe.cpp
# tss.cpp xtime.cpp
# SHARED_COMPILE_FLAGS "-DBOOST_THREAD_BUILD_DLL=1"
# STATIC_COMPILE_FLAGS "-DBOOST_THREAD_BUILD_LIB=1"
# NOT_SINGLE_THREADED
# )
macro(boost_add_library LIBNAME)
parse_arguments(THIS_LIB
"DEPENDS;COMPILE_FLAGS;LINK_FLAGS;LINK_LIBS;EXTRA_VARIANTS;FORCE_VARIANTS;${BOOST_ADD_ARG_NAMES}"
"MODULE;NO_INSTALL;${BOOST_ADDLIB_OPTION_NAMES}"
${ARGN}
)
set(THIS_LIB_SOURCES ${THIS_LIB_DEFAULT_ARGS})
if (NOT TEST_INSTALLED_TREE)
# A top-level target that refers to all of the variants of the
# library, collectively.
add_custom_target(${LIBNAME})
if (THIS_LIB_EXTRA_VARIANTS)
# Build the set of variants that we will generate for this library
set(THIS_LIB_VARIANTS)
foreach(VARIANT ${BOOST_DEFAULT_VARIANTS})
foreach(EXTRA_VARIANT ${THIS_LIB_EXTRA_VARIANTS})
string(REPLACE ":" ";" FEATURES "${EXTRA_VARIANT}")
separate_arguments(FEATURES)
foreach(FEATURE ${FEATURES})
list(APPEND THIS_LIB_VARIANTS "${VARIANT}:${FEATURE}")
endforeach(FEATURE ${FEATURES})
endforeach(EXTRA_VARIANT ${THIS_LIB_EXTRA_VARIANTS})
endforeach(VARIANT ${BOOST_DEFAULT_VARIANTS})
else (THIS_LIB_EXTRA_VARIANTS)
set(THIS_LIB_VARIANTS ${BOOST_DEFAULT_VARIANTS})
endif (THIS_LIB_EXTRA_VARIANTS)
if (THIS_LIB_FORCE_VARIANTS)
# string(TOUPPER "${LIBNAME}_FORCE_VARIANTS" force_variants)
# set(${force_variants} ${THIS_LIB_FORCE_VARIANTS} CACHE INTERNAL "")
set(BUILD_${THIS_LIB_FORCE_VARIANTS}_PREV ${BUILD_${THIS_LIB_FORCE_VARIANTS}} )
set(BUILD_${THIS_LIB_FORCE_VARIANTS} TRUE)
endif (THIS_LIB_FORCE_VARIANTS)
# Build each of the library variants
foreach(VARIANT_STR ${THIS_LIB_VARIANTS})
string(REPLACE ":" ";" VARIANT ${VARIANT_STR})
separate_arguments(VARIANT)
boost_library_variant(${LIBNAME} ${VARIANT})
endforeach(VARIANT_STR ${THIS_LIB_VARIANTS})
endif (NOT TEST_INSTALLED_TREE)
if (THIS_LIB_FORCE_VARIANTS)
set(BUILD_${THIS_LIB_FORCE_VARIANTS} ${BUILD_${THIS_LIB_FORCE_VARIANTS}_PREV} )
# message(STATUS "* ^^ BUILD_${THIS_LIB_FORCE_VARIANTS} ${BUILD_${THIS_LIB_FORCE_VARIANTS}}")
endif (THIS_LIB_FORCE_VARIANTS)
endmacro(boost_add_library)
# Like boost_add_library, but builds a single library variant
# FIXME: I'm not sure if I like this or not. Document it if it survives.
macro(boost_add_single_library LIBNAME)
parse_arguments(THIS_LIB
"DEPENDS;COMPILE_FLAGS;LINK_FLAGS;LINK_LIBS;${BOOST_ADD_ARG_NAMES}"
"NO_INSTALL;MODULE;${BOOST_ADDEXE_OPTION_NAMES}"
${ARGN}
)
set(THIS_LIB_SOURCES ${THIS_LIB_DEFAULT_ARGS})
if (NOT TEST_INSTALLED_TREE)
boost_select_variant(${LIBNAME} THIS_LIB)
if (THIS_LIB_VARIANT)
add_custom_target(${LIBNAME})
separate_arguments(THIS_LIB_VARIANT)
boost_library_variant(${LIBNAME} ${THIS_LIB_VARIANT})
endif ()
endif (NOT TEST_INSTALLED_TREE)
endmacro(boost_add_single_library)
# Creates a new executable from source files.
#
# boost_add_executable(exename
# source1 source2 ...
# [COMPILE_FLAGS compileflags]
# [feature_COMPILE_FLAGS compileflags]
# [LINK_FLAGS linkflags]
# [feature_LINK_FLAGS linkflags]
# [LINK_LIBS linklibs]
# [feature_LINK_LIBS linklibs]
# [DEPENDS libdepend1 libdepend2 ...]
# [feature]
# [NO_INSTALL])
#
# where exename is the name of the executable (e.g., "wave"). source1,
# source2, etc. are the source files used to build the executable, e.g.,
# cpp.cpp. If no source files are provided, "exename.cpp" will be
# used.
#
# This macro has a variety of options that affect its behavior. In
# several cases, we use the placeholder "feature" in the option name
# to indicate that there are actually several different kinds of
# options, each referring to a different build feature, e.g., shared
# libraries, multi-threaded, debug build, etc. For a complete listing
# of these features, please refer to the CMakeLists.txt file in the
# root of the Boost distribution, which defines the set of features
# that will be used to build Boost libraries by default.
#
# The options that affect this macro's behavior are:
#
# COMPILE_FLAGS: Provides additional compilation flags that will be
# used when building the executable.
#
# feature_COMPILE_FLAGS: Provides additional compilation flags that
# will be used only when building the executable with the given
# feature (e.g., SHARED_COMPILE_FLAGS when we're linking against
# shared libraries). Note that the set of features used to build the
# executable depends both on the arguments given to
# boost_add_executable (see the "feature" argument description,
# below) and on the user's choice of variants to build.
#
# LINK_FLAGS: Provides additional flags that will be passed to the
# linker when linking the executable. This option should not be used
# to link in additional libraries; see LINK_LIBS and DEPENDS.
#
# feature_LINK_FLAGS: Provides additional flags that will be passed
# to the linker when linking the executable with the given feature
# (e.g., MULTI_THREADED_LINK_FLAGS when we're linking a
# multi-threaded executable).
#
# LINK_LIBS: Provides additional libraries against which the
# executable will be linked. For example, one might provide "expat"
# as options to LINK_LIBS, to state that the executable will link
# against the expat library binary. Use LINK_LIBS for libraries
# external to Boost; for Boost libraries, use DEPENDS.
#
# feature_LINK_LIBS: Provides additional libraries to link against
# when linking an executable built with the given feature.
#
# DEPENDS: States that this executable depends on and links against
# a Boostlibrary. The arguments to DEPENDS should be the unversioned
# name of the Boost library, such as "boost_filesystem". Like
# LINK_LIBS, this option states that the executable will link
# against the stated libraries. Unlike LINK_LIBS, however, DEPENDS
# takes particular library variants into account, always linking to
# the appropriate variant of a Boost library. For example, if the
# MULTI_THREADED feature was requested in the call to
# boost_add_executable, DEPENDS will ensure that we only link
# against multi-threaded libraries.
#
# feature: States that the executable should always be built using a
# given feature, e.g., SHARED linking (against its libraries) or
# MULTI_THREADED (for multi-threaded builds). If that feature has
# been turned off by the user, the executable will not build.
#
# NO_INSTALL: Don't install this executable with the rest of Boost.
#
# OUTPUT_NAME: If you want the executable to be generated somewhere
# other than the binary directory, pass the path (including
# directory and file name) via the OUTPUT_NAME parameter.
#
# Example:
# boost_add_executable(wave cpp.cpp
# DEPENDS boost_wave boost_program_options boost_filesystem
# boost_serialization
# )
macro(boost_add_executable EXENAME)
# Note: ARGS is here to support the use of boost_add_executable in
# the testing code.
parse_arguments(THIS_EXE
"DEPENDS;COMPILE_FLAGS;LINK_FLAGS;LINK_LIBS;OUTPUT_NAME;ARGS;${BOOST_ADD_ARG_NAMES}"
"NO_INSTALL;${BOOST_ADDEXE_OPTION_NAMES}"
${ARGN}
)
# Determine the list of sources
if (THIS_EXE_DEFAULT_ARGS)
set(THIS_EXE_SOURCES ${THIS_EXE_DEFAULT_ARGS})
else (THIS_EXE_DEFAULT_ARGS)
set(THIS_EXE_SOURCES ${EXENAME}.cpp)
endif (THIS_EXE_DEFAULT_ARGS)
# Whether we can build both debug and release versions of this
# executable within an IDE (based on the selected configuration
# type).
set(THIS_EXE_DEBUG_AND_RELEASE FALSE)
# Compute the variant that will be used to build this executable,
# taking into account both the requested features passed to
# boost_add_executable and what options the user has set.
boost_select_variant(${EXENAME} THIS_EXE)
set(THIS_EXE_OKAY FALSE)
if (THIS_EXE_VARIANT)
# It's okay to build this executable
set(THIS_EXE_OKAY TRUE)
# Compute the name of the variant targets that we'll be linking
# against. We'll use this to link against the appropriate
# dependencies. For IDE targets where we can build both debug and
# release configurations, create DEBUG_ and RELEASE_ versions of
# the macros.
if (THIS_EXE_DEBUG_AND_RELEASE)
boost_library_variant_target_name(RELEASE ${THIS_EXE_VARIANT})
set(RELEASE_VARIANT_TARGET_NAME "${VARIANT_TARGET_NAME}")
boost_library_variant_target_name(DEBUG ${THIS_EXE_VARIANT})
set(DEBUG_VARIANT_TARGET_NAME "${VARIANT_TARGET_NAME}")
else (THIS_EXE_DEBUG_AND_RELEASE)
boost_library_variant_target_name(${THIS_EXE_VARIANT})
endif (THIS_EXE_DEBUG_AND_RELEASE)
# Compute the actual set of library dependencies, based on the
# variant name we computed above. The RELEASE and DEBUG versions
# only apply when THIS_EXE_DEBUG_AND_RELEASE.
set(THIS_EXE_ACTUAL_DEPENDS)
set(THIS_EXE_RELEASE_ACTUAL_DEPENDS)
set(THIS_EXE_DEBUG_ACTUAL_DEPENDS)
foreach(LIB ${THIS_EXE_DEPENDS})
if (LIB MATCHES ".*-.*")
# The user tried to state exactly which variant to use. Just
# propagate the dependency and hope that s/he was
# right. Eventually, this should at least warn, because it is
# not the "proper" way to do things
list(APPEND THIS_EXE_ACTUAL_DEPENDS ${LIB})
list(APPEND THIS_EXE_RELEASE_ACTUAL_DEPENDS ${LIB})
list(APPEND THIS_EXE_DEBUG_ACTUAL_DEPENDS ${LIB})
else (LIB MATCHES ".*-.*")
# The user has given the name of just the library target,
# e.g., "boost_filesystem". We add on the appropriate variant
# name(s).
list(APPEND THIS_EXE_ACTUAL_DEPENDS "${LIB}${VARIANT_TARGET_NAME}")
list(APPEND THIS_EXE_RELEASE_ACTUAL_DEPENDS "${LIB}${RELEASE_VARIANT_TARGET_NAME}")
list(APPEND THIS_EXE_DEBUG_ACTUAL_DEPENDS "${LIB}${DEBUG_VARIANT_TARGET_NAME}")
endif (LIB MATCHES ".*-.*")
endforeach(LIB ${THIS_EXE_DEPENDS})
# Build the executable
if (THIS_PROJECT_IS_TOOL)
set(THIS_EXE_NAME ${EXENAME})
else()
set(THIS_EXE_NAME ${PROJECT_NAME}-${EXENAME})
endif()
add_executable(${THIS_EXE_NAME} ${THIS_EXE_SOURCES})
# Set the various compilation and linking flags
set_target_properties(${THIS_EXE_NAME}
PROPERTIES
COMPILE_FLAGS "${THIS_EXE_COMPILE_FLAGS}"
LINK_FLAGS "${THIS_EXE_LINK_FLAGS}"
LABELS "${PROJECT_NAME}"
)
# For IDE generators where we can build both debug and release
# configurations, pass the configurations along separately.
if (THIS_EXE_DEBUG_AND_RELEASE)
set_target_properties(${THIS_EXE_NAME}
PROPERTIES
COMPILE_FLAGS_DEBUG "${DEBUG_COMPILE_FLAGS} ${THIS_EXE_COMPILE_FLAGS}"
COMPILE_FLAGS_RELEASE "${RELEASE_COMPILE_FLAGS} ${THIS_EXE_COMPILE_FLAGS}"
LINK_FLAGS_DEBUG "${DEBUG_LINK_FLAGS} ${DEBUG_EXE_LINK_FLAGS} ${THIS_EXE_LINK_FLAGS}"
LINK_FLAGS_RELEASE "${RELEASE_LINK_FLAGS} ${RELEASE_EXE_LINK_FLAGS} ${THIS_EXE_LINK_FLAGS}"
)
endif (THIS_EXE_DEBUG_AND_RELEASE)
# If the user gave an output name, use it.
if(THIS_EXE_OUTPUT_NAME)
set_target_properties(${THIS_EXE_NAME}
PROPERTIES
OUTPUT_NAME ${THIS_EXE_OUTPUT_NAME}
)
endif()
# Link against the various libraries
if (THIS_EXE_DEBUG_AND_RELEASE)
# Configuration-agnostic libraries
target_link_libraries(${THIS_EXE_NAME} ${THIS_EXE_LINK_LIBS})
# Link against libraries for "release" configuration
foreach(LIB ${THIS_EXE_RELEASE_ACTUAL_DEPENDS} ${THIS_EXE_RELEASE_LINK_LIBS})
target_link_libraries(${THIS_EXE_NAME} optimized ${LIB})
endforeach(LIB ${THIS_EXE_RELEASE_ACTUAL_DEPENDS} ${THIS_EXE_RELEASE_LINK_LIBS})
# Link against libraries for "debug" configuration
foreach(LIB ${THIS_EXE_DEBUG_ACTUAL_DEPENDS} ${THIS_EXE_DEBUG_LINK_LIBS})
target_link_libraries(${THIS_EXE_NAME} debug ${LIB})
endforeach(LIB ${THIS_EXE_DEBUG_ACTUAL_DEPENDS} ${THIS_EXE_DEBUG_LINK_LIBS})
else (THIS_EXE_DEBUG_AND_RELEASE)
target_link_libraries(${THIS_EXE_NAME}
${THIS_EXE_ACTUAL_DEPENDS}
${THIS_EXE_LINK_LIBS})
endif (THIS_EXE_DEBUG_AND_RELEASE)
# Install the executable, if not suppressed
if (NOT THIS_EXE_NO_INSTALL)
install(TARGETS ${THIS_EXE_NAME} DESTINATION bin)
endif (NOT THIS_EXE_NO_INSTALL)
endif ()
endmacro(boost_add_executable)