Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -156,6 +156,7 @@ set(LIBCXX_COMPILER ${CMAKE_CXX_COMPILER}) set(LIBCXX_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(LIBCXX_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) +set(LIBCXX_HEADER_DIR ${CMAKE_BINARY_DIR}/include/c++/v1/) set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX}) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LIBCXX_LIBRARY_DIR}) @@ -169,6 +170,7 @@ set(LIBCXX_COMPILE_FLAGS "") set(LIBCXX_LINK_FLAGS "") set(LIBCXX_LIBRARIES "") +set(LIBCXX_NEEDS_SITE_CONFIG OFF) # Configure compiler. include(config-ix) @@ -258,16 +260,8 @@ # Feature flags =============================================================== define_if(MSVC -D_CRT_SECURE_NO_WARNINGS) -define_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE -D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE) -define_if_not(LIBCXX_ENABLE_STDIN -D_LIBCPP_HAS_NO_STDIN) -define_if_not(LIBCXX_ENABLE_STDOUT -D_LIBCPP_HAS_NO_STDOUT) -define_if_not(LIBCXX_ENABLE_THREADS -D_LIBCPP_HAS_NO_THREADS) -define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK -D_LIBCPP_HAS_NO_MONOTONIC_CLOCK) -define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS -D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS) - - -# Sanitizer flags ============================================================= +# Sanitizer flags ============================================================== # Configure for sanitizers. If LIBCXX_BUILT_STANDALONE then we have to do # the flag translation ourselves. Othewise LLVM's CMakeList.txt will handle it. if (LIBCXX_BUILT_STANDALONE) @@ -301,6 +295,21 @@ message(WARNING "LLVM_USE_SANITIZER is not supported on this platform.") endif() endif() + + +# Configuration file flags ===================================================== +config_define_if_not(LIBCXX_ENABLE_GLOBAL_FILESYSTEM_NAMESPACE _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE) +config_define_if_not(LIBCXX_ENABLE_STDIN _LIBCPP_HAS_NO_STDIN) +config_define_if_not(LIBCXX_ENABLE_STDOUT _LIBCPP_HAS_NO_STDOUT) +config_define_if_not(LIBCXX_ENABLE_THREADS _LIBCPP_HAS_NO_THREADS) +config_define_if_not(LIBCXX_ENABLE_MONOTONIC_CLOCK _LIBCPP_HAS_NO_MONOTONIC_CLOCK) +config_define_if_not(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS) + +configure_file( + include/__config_site.in + ${LIBCXX_BINARY_DIR}/__config_site + @ONLY) + #=============================================================================== # Setup Source Code And Tests #=============================================================================== Index: cmake/Modules/CopyLibcxxHeaders.cmake =================================================================== --- /dev/null +++ cmake/Modules/CopyLibcxxHeaders.cmake @@ -0,0 +1,20 @@ +set(LIBCXX_HEADER_PATTERN + PATTERN "*" + PATTERN "CMakeLists.txt" EXCLUDE + PATTERN ".svn" EXCLUDE + PATTERN "__config_site.in" EXCLUDE + ${LIBCXX_SUPPORT_HEADER_PATTERN} + ) + +file(COPY . + DESTINATION "${LIBCXX_HEADER_DIR}" + FILES_MATCHING + ${LIBCXX_HEADER_PATTERN} + ) + +if (LIBCXX_NEEDS_SITE_CONFIG) + file(COPY ${LIBCXX_BINARY_DIR}/__config_site DESTINATION ${LIBCXX_HEADER_DIR}) + file(RENAME ${LIBCXX_HEADER_DIR}/__config_site ${LIBCXX_HEADER_DIR}/__config) + file(READ ${LIBCXX_SOURCE_DIR}/include/__config CONFIG_CONTENTS) + file(APPEND ${LIBCXX_HEADER_DIR}/__config "${CONFIG_CONTENTS}") +endif() Index: cmake/Modules/HandleLibcxxFlags.cmake =================================================================== --- cmake/Modules/HandleLibcxxFlags.cmake +++ cmake/Modules/HandleLibcxxFlags.cmake @@ -49,6 +49,22 @@ endif() endmacro() +macro(config_define_if condition def) + if (${condition}) + add_definitions(-D${def}) + set(${def} ON) + set(LIBCXX_NEEDS_SITE_CONFIG ON) + endif() +endmacro() + +macro(config_define_if_not condition def) + if (NOT ${condition}) + add_definitions(-D${def}) + set(${def} ON) + set(LIBCXX_NEEDS_SITE_CONFIG ON) + endif() +endmacro() + # Add a specified list of flags to both 'LIBCXX_COMPILE_FLAGS' and # 'LIBCXX_LINK_FLAGS'. macro(add_flags) Index: include/CMakeLists.txt =================================================================== --- include/CMakeLists.txt +++ include/CMakeLists.txt @@ -1,18 +1,28 @@ if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS) set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE) endif() + set(LIBCXX_HEADER_PATTERN PATTERN "*" PATTERN "CMakeLists.txt" EXCLUDE PATTERN ".svn" EXCLUDE + PATTERN "__config_site.in" EXCLUDE ${LIBCXX_SUPPORT_HEADER_PATTERN} ) -file(COPY . - DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1" - FILES_MATCHING - ${LIBCXX_HEADER_PATTERN} - ) +# The headers should be copied to the build directory every time libc++ is built. +# Because the CMake file(...) commands only run at configuration time we use +# a cmake script that we can run during every build. +add_custom_target(libcxx-copy-headers ALL + COMMAND + ${CMAKE_COMMAND} + -DLIBCXX_HEADER_DIR=${LIBCXX_HEADER_DIR} + -DLIBCXX_BINARY_DIR=${LIBCXX_BINARY_DIR} + -DLIBCXX_SOURCE_DIR=${LIBCXX_SOURCE_DIR} + -DLIBCXX_NEEDS_SITE_CONFIG=${LIBCXX_NEEDS_SITE_CONFIG} + -P ${LIBCXX_SOURCE_DIR}/cmake/Modules/CopyLibcxxHeaders.cmake + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}) + if (LIBCXX_INSTALL_HEADERS) install(DIRECTORY . Index: include/__config_site.in =================================================================== --- /dev/null +++ include/__config_site.in @@ -0,0 +1,20 @@ +//===----------------------------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is dual licensed under the MIT and the University of Illinois Open +// Source Licenses. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef _LIBCPP_CONFIG_SITE +#define _LIBCPP_CONFIG_SITE + +#cmakedefine _LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE +#cmakedefine _LIBCPP_HAS_NO_STDIN +#cmakedefine _LIBCPP_HAS_NO_STDOUT +#cmakedefine _LIBCPP_HAS_NO_THREADS +#cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK +#cmakedefine _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS + +#endif Index: test/CMakeLists.txt =================================================================== --- test/CMakeLists.txt +++ test/CMakeLists.txt @@ -22,6 +22,10 @@ pythonize_bool(LIBCXX_GENERATE_COVERAGE) pythonize_bool(LIBCXXABI_USE_LLVM_UNWINDER) +if (LIBCXX_NEEDS_SITE_CONFIG) + set(LIBCXX_TEST_HEADERS ${LIBCXX_BINARY_DIR}/include/c++/v1) +endif() + # The tests shouldn't link to any ABI library when it has been linked into # libc++ statically. if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY) Index: test/libcxx/test/config.py =================================================================== --- test/libcxx/test/config.py +++ test/libcxx/test/config.py @@ -391,8 +391,13 @@ support_path = os.path.join(self.libcxx_src_root, 'test/support') self.cxx.compile_flags += ['-I' + support_path] self.cxx.compile_flags += ['-include', os.path.join(support_path, 'nasty_macros.hpp')] - libcxx_headers = self.get_lit_conf( - 'libcxx_headers', os.path.join(self.libcxx_src_root, 'include')) + + libcxx_headers = self.get_lit_conf('libcxx_headers') + if libcxx_headers: + self.lit_config.note('Using libc++ headers in: %s' % libcxx_headers) + else: + libcxx_headers = os.path.join(self.libcxx_src_root, 'include') + if not os.path.isdir(libcxx_headers): self.lit_config.fatal("libcxx_headers='%s' is not a directory." % libcxx_headers) @@ -416,36 +421,28 @@ if not enable_global_filesystem_namespace: self.config.available_features.add( 'libcpp-has-no-global-filesystem-namespace') - self.cxx.compile_flags += [ - '-D_LIBCPP_HAS_NO_GLOBAL_FILESYSTEM_NAMESPACE'] def configure_compile_flags_no_stdin(self): enable_stdin = self.get_lit_bool('enable_stdin', True) if not enable_stdin: self.config.available_features.add('libcpp-has-no-stdin') - self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDIN'] def configure_compile_flags_no_stdout(self): enable_stdout = self.get_lit_bool('enable_stdout', True) if not enable_stdout: self.config.available_features.add('libcpp-has-no-stdout') - self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_STDOUT'] def configure_compile_flags_no_threads(self): - self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_THREADS'] self.config.available_features.add('libcpp-has-no-threads') def configure_compile_flags_no_thread_unsafe_c_functions(self): enable_thread_unsafe_c_functions = self.get_lit_bool( 'enable_thread_unsafe_c_functions', True) if not enable_thread_unsafe_c_functions: - self.cxx.compile_flags += [ - '-D_LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS'] self.config.available_features.add( 'libcpp-has-no-thread-unsafe-c-functions') def configure_compile_flags_no_monotonic_clock(self): - self.cxx.compile_flags += ['-D_LIBCPP_HAS_NO_MONOTONIC_CLOCK'] self.config.available_features.add('libcpp-has-no-monotonic-clock') def configure_link_flags(self): Index: test/lit.site.cfg.in =================================================================== --- test/lit.site.cfg.in +++ test/lit.site.cfg.in @@ -2,6 +2,7 @@ config.cxx_under_test = "@LIBCXX_COMPILER@" config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@" config.libcxx_obj_root = "@LIBCXX_BINARY_DIR@" +config.libcxx_headers = "@LIBCXX_TEST_HEADERS@" config.cxx_library_root = "@LIBCXX_LIBRARY_DIR@" config.enable_exceptions = "@LIBCXX_ENABLE_EXCEPTIONS@" config.enable_rtti = "@LIBCXX_ENABLE_RTTI@"