Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -1,3 +1,5 @@ +# See www/CMake.html for instructions on how to build libcxxabi with CMake. + #=============================================================================== # Setup Project #=============================================================================== @@ -16,121 +18,28 @@ ) if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) - project(libcxxabi) - - # Rely on llvm-config. - set(CONFIG_OUTPUT) - if (NOT LLVM_CONFIG_PATH) - find_program(LLVM_CONFIG_PATH "llvm-config") - endif() - if(DEFINED LLVM_PATH) - set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH "Path to llvm/include") - set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree") - set(LLVM_MAIN_SRC_DIR ${LLVM_PATH}) - set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules") - elseif(LLVM_CONFIG_PATH) - message(STATUS "Found LLVM_CONFIG_PATH as ${LLVM_CONFIG_PATH}") - set(CONFIG_COMMAND ${LLVM_CONFIG_PATH} - "--includedir" - "--prefix" - "--src-root") - execute_process( - COMMAND ${CONFIG_COMMAND} - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE CONFIG_OUTPUT - ) - if(NOT HAD_ERROR) - string(REGEX REPLACE - "[ \t]*[\r\n]+[ \t]*" ";" - CONFIG_OUTPUT ${CONFIG_OUTPUT}) - else() - string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") - message(STATUS "${CONFIG_COMMAND_STR}") - message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") - endif() - - list(GET CONFIG_OUTPUT 0 INCLUDE_DIR) - list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT) - list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR) - - set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include") - set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") - set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") - set(LLVM_LIT_PATH "${LLVM_PATH}/utils/lit/lit.py") - - # --cmakedir is supported since llvm r291218 (4.0 release) - execute_process( - COMMAND ${LLVM_CONFIG_PATH} --cmakedir - RESULT_VARIABLE HAD_ERROR - OUTPUT_VARIABLE CONFIG_OUTPUT - ERROR_QUIET) - if(NOT HAD_ERROR) - string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH) - else() - set(LLVM_CMAKE_PATH - "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm") - endif() - else() - message(FATAL_ERROR "llvm-config not found and LLVM_MAIN_SRC_DIR not defined. " - "Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config " - "or -DLLVM_PATH=path/to/llvm-source-root.") - endif() - - if(EXISTS ${LLVM_CMAKE_PATH}) - list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") - include("${LLVM_CMAKE_PATH}/AddLLVM.cmake") - include("${LLVM_CMAKE_PATH}/HandleLLVMOptions.cmake") - else() - message(FATAL_ERROR "Not found: ${LLVM_CMAKE_PATH}") - endif() + project(libcxxabi CXX C) set(PACKAGE_NAME libcxxabi) set(PACKAGE_VERSION 5.0.0svn) set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") set(PACKAGE_BUGREPORT "llvm-bugs@lists.llvm.org") - if (NOT DEFINED LLVM_INCLUDE_TESTS) - set(LLVM_INCLUDE_TESTS ON) - endif() - - if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) - set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) - else() - # Seek installed Lit. - find_program(LLVM_LIT "lit.py" ${LLVM_MAIN_SRC_DIR}/utils/lit - DOC "Path to lit.py") - endif() - - if(LLVM_LIT) - # Define the default arguments to use with 'lit', and an option for the user - # to override. - set(LIT_ARGS_DEFAULT "-sv") - if (MSVC OR XCODE) - set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") - endif() - set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") - - # On Win32 hosts, provide an option to specify the path to the GnuWin32 tools. - if( WIN32 AND NOT CYGWIN ) - set(LLVM_LIT_TOOLS_DIR "" CACHE PATH "Path to GnuWin32 tools") - endif() - else() - set(LLVM_INCLUDE_TESTS OFF) - endif() - - set(LIBCXXABI_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}" CACHE STRING - "Define suffix of library directory name (32/64)") - - set(LIBCXXABI_STANDALONE_BUILD 1) -else() - set(LLVM_MAIN_SRC_DIR "${CMAKE_SOURCE_DIR}" CACHE PATH "Path to LLVM source tree") - set(LLVM_LIT "${CMAKE_SOURCE_DIR}/utils/lit/lit.py") - set(LIBCXXABI_LIBDIR_SUFFIX ${LLVM_LIBDIR_SUFFIX}) + # Find the LLVM sources and simulate LLVM CMake options. + include(HandleOutOfTreeLLVM) endif() +# Require out of source build. +include(MacroEnsureOutOfSourceBuild) +MACRO_ENSURE_OUT_OF_SOURCE_BUILD( + "${PROJECT_NAME} requires an out of source build. Please create a separate + build directory and run 'cmake /path/to/${PROJECT_NAME} [options]' there." + ) + #=============================================================================== # Setup CMake Options #=============================================================================== +include(CMakeDependentOption) include(HandleCompilerRT) # Define options. @@ -247,6 +156,7 @@ set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXXABI_LIBRARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LIBCXXABI_LIBRARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LIBCXXABI_LIBRARY_DIR}) # By default, for non-standalone builds, libcxx and libcxxabi share a library # directory. @@ -264,30 +174,26 @@ message(FATAL_ERROR "LIBCXXABI_BUILD_32_BITS=ON is not supported on this platform.") endif() -#=============================================================================== -# Setup Compiler Flags -#=============================================================================== - -# Get required flags. -macro(append_if list condition var) - if (${condition}) - list(APPEND ${list} ${var}) - endif() -endmacro() - -macro(add_target_flags_if condition var) - if (${condition}) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${var}") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${var}") - list(APPEND LIBCXXABI_COMPILE_FLAGS ${var}) - list(APPEND LIBCXXABI_LINK_FLAGS ${var}) - endif() -endmacro() +# Declare libc++abi configuration variables. +# They are intended for use as follows: +# LIBCXXABI_C_FLAGS: General flags for both the c++ compiler and linker. +# LIBCXXABI_CXX_FLAGS: General flags for both the c++ compiler and linker. +# LIBCXXABI_COMPILE_FLAGS: Compile only flags. +# LIBCXXABI_LINK_FLAGS: Linker only flags. +# LIBCXXABI_LIBRARIES: libraries libc++abi is linked to. set(LIBCXXABI_C_FLAGS "") set(LIBCXXABI_CXX_FLAGS "") set(LIBCXXABI_COMPILE_FLAGS "") set(LIBCXXABI_LINK_FLAGS "") +set(LIBCXXABI_LIBRARIES "") + +# Include macros for adding and removing libc++abi flags. +include(HandleLibcxxabiFlags) + +#=============================================================================== +# Setup Compiler Flags +#=============================================================================== # Configure target flags add_target_flags_if(LIBCXXABI_BUILD_32_BITS "-m32") @@ -325,53 +231,54 @@ add_definitions(-D_LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS) endif() -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WERROR_FLAG -Werror=return-type) +add_compile_flags_if_supported(-Werror=return-type) # Get warning flags -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_W_FLAG -W) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WALL_FLAG -Wall) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WCHAR_SUBSCRIPTS_FLAG -Wchar-subscripts) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WCONVERSION_FLAG -Wconversion) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WMISMATCHED_TAGS_FLAG -Wmismatched-tags) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WMISSING_BRACES_FLAG -Wmissing-braces) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WNEWLINE_EOF_FLAG -Wnewline-eof) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WUNUSED_FUNCTION_FLAG -Wunused-function) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSHADOW_FLAG -Wshadow) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSHORTEN_64_TO_32_FLAG -Wshorten-64-to-32) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSIGN_COMPARE_FLAG -Wsign-compare) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSIGN_CONVERSION_FLAG -Wsign-conversion) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSTRICT_ALIASING_FLAG -Wstrict-aliasing=2) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WSTRICT_OVERFLOW_FLAG -Wstrict-overflow=4) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WUNUSED_PARAMETER_FLAG -Wunused-parameter) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WUNUSED_VARIABLE_FLAG -Wunused-variable) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WWRITE_STRINGS_FLAG -Wwrite-strings) -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WUNDEF_FLAG -Wundef) +add_compile_flags_if_supported(-W) +add_compile_flags_if_supported(-Wall) +add_compile_flags_if_supported(-Wchar-subscripts) +add_compile_flags_if_supported(-Wconversion) +add_compile_flags_if_supported(-Wmismatched-tags) +add_compile_flags_if_supported(-Wmissing-braces) +add_compile_flags_if_supported(-Wnewline-eof) +add_compile_flags_if_supported(-Wunused-function) +add_compile_flags_if_supported(-Wshadow) +add_compile_flags_if_supported(-Wshorten-64-to-32) +add_compile_flags_if_supported(-Wsign-compare) +add_compile_flags_if_supported(-Wsign-conversion) +add_compile_flags_if_supported(-Wstrict-aliasing=2) +add_compile_flags_if_supported(-Wstrict-overflow=4) +add_compile_flags_if_supported(-Wunused-parameter) +add_compile_flags_if_supported(-Wunused-variable) +add_compile_flags_if_supported(-Wwrite-strings) +add_compile_flags_if_supported(-Wundef) if (LIBCXXABI_ENABLE_WERROR) - append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WERROR_FLAG -Werror) - append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WX_FLAG -WX) + add_compile_flags_if_supported(-Werror) + add_compile_flags_if_supported(-WX) else() - append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_WNO_ERROR_FLAG -Wno-error) - append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_NO_WX_FLAG -WX-) + add_compile_flags_if_supported(-Wno-error) + add_compile_flags_if_supported(-WX-) endif() if (LIBCXXABI_ENABLE_PEDANTIC) - append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_PEDANTIC_FLAG -pedantic) + add_compile_flags_if_supported(-pedantic) endif() # Get feature flags. -append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_FSTRICT_ALIASING_FLAG -fstrict-aliasing) +add_compile_flags_if_supported(-fstrict-aliasing) # Exceptions if (LIBCXXABI_ENABLE_EXCEPTIONS) # Catches C++ exceptions only and tells the compiler to assume that extern C # functions never throw a C++ exception. - append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_EHSC_FLAG -EHsc) - append_if(LIBCXXABI_C_FLAGS LIBCXXABI_HAS_FUNWIND_TABLES -funwind-tables) + add_compile_flags_if_supported(-EHsc) + # Do we really need to be run through the C compiler ? + add_c_compile_flags_if_supported(-funwind-tables) else() add_definitions(-D_LIBCXXABI_NO_EXCEPTIONS) - append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_NO_EXCEPTIONS_FLAG -fno-exceptions) - append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_NO_EHS_FLAG -EHs-) - append_if(LIBCXXABI_CXX_FLAGS LIBCXXABI_HAS_NO_EHA_FLAG -EHa-) + add_compile_flags_if_supported(-fno-exceptions) + add_compile_flags_if_supported(-EHs-) + add_compile_flags_if_supported(-EHa-) endif() # Assert Index: cmake/Modules/HandleLibcxxabiFlags.cmake =================================================================== --- /dev/null +++ cmake/Modules/HandleLibcxxabiFlags.cmake @@ -0,0 +1,208 @@ +# HandleLibcxxFlags - A set of macros used to setup the flags used to compile +# and link libc++. These macros add flags to the following CMake variables. +# - LIBCXXABI_COMPILE_FLAGS: flags used to compile libc++ +# - LIBCXXABI_LINK_FLAGS: flags used to link libc++ +# - LIBCXXABI_LIBRARIES: libraries to link libc++ to. + +include(CheckCXXCompilerFlag) + +unset(add_flag_if_supported) + +# Mangle the name of a compiler flag into a valid CMake identifier. +# Ex: --std=c++11 -> STD_EQ_CXX11 +macro(mangle_name str output) + string(STRIP "${str}" strippedStr) + string(REGEX REPLACE "^/" "" strippedStr "${strippedStr}") + string(REGEX REPLACE "^-+" "" strippedStr "${strippedStr}") + string(REGEX REPLACE "-+$" "" strippedStr "${strippedStr}") + string(REPLACE "-" "_" strippedStr "${strippedStr}") + string(REPLACE "=" "_EQ_" strippedStr "${strippedStr}") + string(REPLACE "+" "X" strippedStr "${strippedStr}") + string(TOUPPER "${strippedStr}" ${output}) +endmacro() + +# Remove a list of flags from all CMake variables that affect compile flags. +# This can be used to remove unwanted flags specified on the command line +# or added in other parts of LLVM's cmake configuration. +macro(remove_flags) + foreach(var ${ARGN}) + string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}") + string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}") + string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}") + string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + string(REPLACE "${var}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") + string(REPLACE "${var}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") + string(REPLACE "${var}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}") + string(REPLACE "${var}" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") + string(REPLACE "${var}" "" CMAKE_SHARED_MODULE_FLAGS "${CMAKE_SHARED_MODULE_FLAGS}") + remove_definitions(${var}) + endforeach() +endmacro(remove_flags) + +macro(check_flag_supported flag) + mangle_name("${flag}" flagname) + check_cxx_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") +endmacro() + +# Add a macro definition if condition is true. +macro(define_if condition def) + if (${condition}) + add_definitions(${def}) + endif() +endmacro() + +# Add a macro definition if condition is not true. +macro(define_if_not condition def) + if (NOT ${condition}) + add_definitions(${def}) + endif() +endmacro() + +# Add a macro definition to the __config_site file if the specified condition +# is 'true'. Note that '-D${def}' is not added. Instead it is expected that +# the build include the '__config_site' header. +macro(config_define_if condition def) + if (${condition}) + set(${def} ON) + set(LIBCXXABI_NEEDS_SITE_CONFIG ON) + endif() +endmacro() + +macro(config_define_if_not condition def) + if (NOT ${condition}) + set(${def} ON) + set(LIBCXXABI_NEEDS_SITE_CONFIG ON) + endif() +endmacro() + +macro(config_define value def) + set(${def} ${value}) + set(LIBCXXABI_NEEDS_SITE_CONFIG ON) +endmacro() + +# Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', +# 'LIBCXXABI_COMPILE_FLAGS' and 'LIBCXXABI_LINK_FLAGS'. +macro(add_target_flags) + foreach(value ${ARGN}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${value}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${value}") + list(APPEND LIBCXXABI_COMPILE_FLAGS ${value}) + list(APPEND LIBCXXABI_LINK_FLAGS ${value}) + endforeach() +endmacro() + +# If the specified 'condition' is true then add a list of flags to +# all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXXABI_COMPILE_FLAGS' +# and 'LIBCXXABI_LINK_FLAGS'. +macro(add_target_flags_if condition) + if (${condition}) + add_target_flags(${ARGN}) + endif() +endmacro() + +# Add a specified list of flags to both 'LIBCXXABI_COMPILE_FLAGS' and +# 'LIBCXXABI_LINK_FLAGS'. +macro(add_flags) + foreach(value ${ARGN}) + list(APPEND LIBCXXABI_COMPILE_FLAGS ${value}) + list(APPEND LIBCXXABI_LINK_FLAGS ${value}) + endforeach() +endmacro() + +# If the specified 'condition' is true then add a list of flags to both +# 'LIBCXXABI_COMPILE_FLAGS' and 'LIBCXXABI_LINK_FLAGS'. +macro(add_flags_if condition) + if (${condition}) + add_flags(${ARGN}) + endif() +endmacro() + +# Add each flag in the list to LIBCXXABI_COMPILE_FLAGS and LIBCXXABI_LINK_FLAGS +# if that flag is supported by the current compiler. +macro(add_flags_if_supported) + foreach(flag ${ARGN}) + mangle_name("${flag}" flagname) + check_cxx_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") + add_flags_if(LIBCXXABI_SUPPORTS_${flagname}_FLAG ${flag}) + endforeach() +endmacro() + +# Add a list of flags to 'LIBCXXABI_COMPILE_FLAGS'. +macro(add_compile_flags) + foreach(f ${ARGN}) + list(APPEND LIBCXXABI_COMPILE_FLAGS ${f}) + endforeach() +endmacro() + +# If 'condition' is true then add the specified list of flags to +# 'LIBCXXABI_COMPILE_FLAGS' +macro(add_compile_flags_if condition) + if (${condition}) + add_compile_flags(${ARGN}) + endif() +endmacro() + +# For each specified flag, add that flag to 'LIBCXXABI_COMPILE_FLAGS' if the +# flag is supported by the C++ compiler. +macro(add_compile_flags_if_supported) + foreach(flag ${ARGN}) + mangle_name("${flag}" flagname) + check_cxx_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") + add_compile_flags_if(LIBCXXABI_SUPPORTS_${flagname}_FLAG ${flag}) + endforeach() +endmacro() + +# For each specified flag, add that flag to 'LIBCXXABI_COMPILE_FLAGS' if the +# flag is supported by the C compiler. +macro(add_c_compile_flags_if_supported) + foreach(flag ${ARGN}) + mangle_name("${flag}" flagname) + check_c_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") + add_compile_flags_if(LIBCXXABI_SUPPORTS_${flagname}_FLAG ${flag}) + endforeach() +endmacro() + +# Add a list of flags to 'LIBCXXABI_LINK_FLAGS'. +macro(add_link_flags) + foreach(f ${ARGN}) + list(APPEND LIBCXXABI_LINK_FLAGS ${f}) + endforeach() +endmacro() + +# If 'condition' is true then add the specified list of flags to +# 'LIBCXXABI_LINK_FLAGS' +macro(add_link_flags_if condition) + if (${condition}) + add_link_flags(${ARGN}) + endif() +endmacro() + +# For each specified flag, add that flag to 'LIBCXXABI_LINK_FLAGS' if the +# flag is supported by the C++ compiler. +macro(add_link_flags_if_supported) + foreach(flag ${ARGN}) + mangle_name("${flag}" flagname) + check_cxx_compiler_flag("${flag}" "LIBCXXABI_SUPPORTS_${flagname}_FLAG") + add_link_flags_if(LIBCXXABI_SUPPORTS_${flagname}_FLAG ${flag}) + endforeach() +endmacro() + +# Add a list of libraries or link flags to 'LIBCXXABI_LIBRARIES'. +macro(add_library_flags) + foreach(lib ${ARGN}) + list(APPEND LIBCXXABI_LIBRARIES ${lib}) + endforeach() +endmacro() + +# if 'condition' is true then add the specified list of libraries and flags +# to 'LIBCXXABI_LIBRARIES'. +macro(add_library_flags_if condition) + if(${condition}) + add_library_flags(${ARGN}) + endif() +endmacro() + +# Turn a comma separated CMake list into a space separated string. +macro(split_list listname) + string(REPLACE ";" " " ${listname} "${${listname}}") +endmacro() Index: cmake/Modules/HandleOutOfTreeLLVM.cmake =================================================================== --- /dev/null +++ cmake/Modules/HandleOutOfTreeLLVM.cmake @@ -0,0 +1,130 @@ +macro(find_llvm_parts) +# Rely on llvm-config. + set(CONFIG_OUTPUT) + if(NOT LLVM_CONFIG_PATH) + find_program(LLVM_CONFIG_PATH "llvm-config") + endif() + if(DEFINED LLVM_PATH) + set(LLVM_INCLUDE_DIR ${LLVM_INCLUDE_DIR} CACHE PATH "Path to llvm/include") + set(LLVM_PATH ${LLVM_PATH} CACHE PATH "Path to LLVM source tree") + set(LLVM_MAIN_SRC_DIR ${LLVM_PATH}) + set(LLVM_CMAKE_PATH "${LLVM_PATH}/cmake/modules") + elseif(LLVM_CONFIG_PATH) + message(STATUS "Found LLVM_CONFIG_PATH as ${LLVM_CONFIG_PATH}") + set(LIBCXXABI_USING_INSTALLED_LLVM 1) + set(CONFIG_COMMAND ${LLVM_CONFIG_PATH} + "--includedir" + "--prefix" + "--src-root") + execute_process( + COMMAND ${CONFIG_COMMAND} + RESULT_VARIABLE HAD_ERROR + OUTPUT_VARIABLE CONFIG_OUTPUT + ) + if(NOT HAD_ERROR) + string(REGEX REPLACE + "[ \t]*[\r\n]+[ \t]*" ";" + CONFIG_OUTPUT ${CONFIG_OUTPUT}) + else() + string(REPLACE ";" " " CONFIG_COMMAND_STR "${CONFIG_COMMAND}") + message(STATUS "${CONFIG_COMMAND_STR}") + message(FATAL_ERROR "llvm-config failed with status ${HAD_ERROR}") + endif() + + list(GET CONFIG_OUTPUT 0 INCLUDE_DIR) + list(GET CONFIG_OUTPUT 1 LLVM_OBJ_ROOT) + list(GET CONFIG_OUTPUT 2 MAIN_SRC_DIR) + + set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Path to llvm/include") + set(LLVM_BINARY_DIR ${LLVM_OBJ_ROOT} CACHE PATH "Path to LLVM build tree") + set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree") + + # --cmakedir is supported since llvm r291218 (4.0 release) + execute_process( + COMMAND ${LLVM_CONFIG_PATH} --cmakedir + RESULT_VARIABLE HAD_ERROR + OUTPUT_VARIABLE CONFIG_OUTPUT + ERROR_QUIET) + if(NOT HAD_ERROR) + string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH) + else() + set(LLVM_CMAKE_PATH + "${LLVM_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm") + endif() + else() + set(LLVM_FOUND OFF) + message(WARNING "UNSUPPORTED LIBCXXABI CONFIGURATION DETECTED: " + "llvm-config not found and LLVM_PATH not defined.\n" + "Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config " + "or -DLLVM_PATH=path/to/llvm-source-root.") + return() + endif() + + if (EXISTS "${LLVM_CMAKE_PATH}") + list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") + elseif (EXISTS "${LLVM_MAIN_SRC_DIR}/cmake/modules") + list(APPEND CMAKE_MODULE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules") + else() + set(LLVM_FOUND OFF) + message(WARNING "Neither ${LLVM_CMAKE_PATH} nor ${LLVM_MAIN_SRC_DIR}/cmake/modules found") + return() + endif() + + set(LLVM_FOUND ON) +endmacro(find_llvm_parts) + +macro(configure_out_of_tree_llvm) + message(STATUS "Configuring for standalone build.") + set(LIBCXXABI_STANDALONE_BUILD 1) + + find_llvm_parts() + + # Add LLVM Functions -------------------------------------------------------- + if (LLVM_FOUND AND LIBCXXABI_USING_INSTALLED_LLVM) + include(LLVMConfig) # For TARGET_TRIPLE + else() + if (WIN32) + set(LLVM_ON_UNIX 0) + set(LLVM_ON_WIN32 1) + else() + set(LLVM_ON_UNIX 1) + set(LLVM_ON_WIN32 0) + endif() + endif() + if (LLVM_FOUND) + include(AddLLVM OPTIONAL) + endif() + + # LLVM Options -------------------------------------------------------------- + if (NOT DEFINED LLVM_INCLUDE_TESTS) + set(LLVM_INCLUDE_TESTS ${LLVM_FOUND}) + endif() + if (NOT DEFINED LLVM_INCLUDE_DOCS) + set(LLVM_INCLUDE_DOCS ${LLVM_FOUND}) + endif() + if (NOT DEFINED LLVM_ENABLE_SPHINX) + set(LLVM_ENABLE_SPHINX OFF) + endif() + + # Required LIT Configuration ------------------------------------------------ + # Define the default arguments to use with 'lit', and an option for the user + # to override. + set(LIT_ARGS_DEFAULT "-sv --show-xfail --show-unsupported") + if (MSVC OR XCODE) + set(LIT_ARGS_DEFAULT "${LIT_ARGS_DEFAULT} --no-progress-bar") + endif() + set(LLVM_LIT_ARGS "${LIT_ARGS_DEFAULT}" CACHE STRING "Default options for lit") + + # Required doc configuration + if (LLVM_ENABLE_SPHINX) + find_package(Sphinx REQUIRED) + endif() + + if (LLVM_ON_UNIX AND NOT APPLE) + set(LLVM_HAVE_LINK_VERSION_SCRIPT 1) + else() + set(LLVM_HAVE_LINK_VERSION_SCRIPT 0) + endif() +endmacro(configure_out_of_tree_llvm) + +configure_out_of_tree_llvm() Index: cmake/Modules/MacroEnsureOutOfSourceBuild.cmake =================================================================== --- /dev/null +++ cmake/Modules/MacroEnsureOutOfSourceBuild.cmake @@ -0,0 +1,18 @@ +# MACRO_ENSURE_OUT_OF_SOURCE_BUILD() + +macro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD _errorMessage ) + +string( COMPARE EQUAL "${CMAKE_SOURCE_DIR}" "${CMAKE_BINARY_DIR}" _insource ) +if( _insource ) + message( SEND_ERROR "${_errorMessage}" ) + message( FATAL_ERROR + "In-source builds are not allowed. + CMake would overwrite the makefiles distributed with libcxxabi. + Please create a directory and run cmake from there, passing the path + to this source directory as the last argument. + This process created the file `CMakeCache.txt' and the directory `CMakeFiles'. + Please delete them." + ) +endif( _insource ) + +endmacro( MACRO_ENSURE_OUT_OF_SOURCE_BUILD ) Index: src/CMakeLists.txt =================================================================== --- src/CMakeLists.txt +++ src/CMakeLists.txt @@ -52,36 +52,33 @@ add_definitions(-DHAVE___CXA_THREAD_ATEXIT_IMPL) endif() -# Generate library list -set(libraries ${LIBCXXABI_CXX_ABI_LIBRARIES}) - if (LIBCXXABI_ENABLE_THREADS) - append_if(libraries LIBCXXABI_HAS_PTHREAD_LIB pthread) + add_library_flags_if(LIBCXXABI_HAS_PTHREAD_LIB pthread) endif() -append_if(libraries LIBCXXABI_HAS_C_LIB c) +add_library_flags_if(LIBCXXABI_HAS_C_LIB c) if (LIBCXXABI_USE_LLVM_UNWINDER) # Prefer using the in-tree version of libunwind, either shared or static. If # none are found fall back to using -lunwind. # FIXME: Is it correct to prefer the static version of libunwind? if (NOT LIBCXXABI_ENABLE_STATIC_UNWINDER AND (TARGET unwind_shared OR HAVE_LIBUNWIND)) - list(APPEND libraries unwind_shared) + list(APPEND LIBCXXABI_LIBRARIES unwind_shared) elseif (LIBCXXABI_ENABLE_STATIC_UNWINDER AND (TARGET unwind_static OR HAVE_LIBUNWIND)) - list(APPEND libraries unwind_static) + list(APPEND LIBCXXABI_LIBRARIES unwind_static) else() - list(APPEND libraries unwind) + list(APPEND LIBCXXABI_LIBRARIES unwind) endif() else() - append_if(libraries LIBCXXABI_HAS_GCC_S_LIB gcc_s) + add_library_flags_if(LIBCXXABI_HAS_GCC_S_LIB gcc_s) endif() if (MINGW) # MINGW_LIBRARIES is defined in config-ix.cmake - list(APPEND libraries ${MINGW_LIBRARIES}) + list(APPEND LIBCXXABI_LIBRARIES ${MINGW_LIBRARIES}) endif() # Setup flags. -append_if(LIBCXXABI_COMPILE_FLAGS LIBCXXABI_HAS_FPIC_FLAG -fPIC) -append_if(LIBCXXABI_LINK_FLAGS LIBCXXABI_HAS_NODEFAULTLIBS_FLAG -nodefaultlibs) +add_compile_flags_if_supported(-fPIC) +add_link_flags_if_supported(-nodefaultlibs) set(LIBCXXABI_SHARED_LINK_FLAGS) @@ -101,9 +98,9 @@ endif() endif() -string(REPLACE ";" " " LIBCXXABI_COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}") -string(REPLACE ";" " " LIBCXXABI_LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}") -string(REPLACE ";" " " LIBCXXABI_SHARED_LINK_FLAGS "${LIBCXXABI_SHARED_LINK_FLAGS}") +split_list(LIBCXXABI_COMPILE_FLAGS) +split_list(LIBCXXABI_LINK_FLAGS) +split_list(LIBCXXABI_SHARED_LINK_FLAGS) # FIXME: libc++abi.so will not link when modules are enabled because it depends # on symbols defined in libc++.so which has not yet been built. @@ -124,7 +121,7 @@ # Build the shared library. if (LIBCXXABI_ENABLE_SHARED) add_library(cxxabi_shared SHARED $) - target_link_libraries(cxxabi_shared ${libraries}) + target_link_libraries(cxxabi_shared ${LIBCXXABI_LIBRARIES}) set_target_properties(cxxabi_shared PROPERTIES LINK_FLAGS "${LIBCXXABI_LINK_FLAGS} ${LIBCXXABI_SHARED_LINK_FLAGS}" @@ -138,7 +135,7 @@ # Build the static library. if (LIBCXXABI_ENABLE_STATIC) add_library(cxxabi_static STATIC $) - target_link_libraries(cxxabi_static ${libraries}) + target_link_libraries(cxxabi_static ${LIBCXXABI_LIBRARIES}) set_target_properties(cxxabi_static PROPERTIES LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"