Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -85,7 +85,7 @@ option(LIBCXX_ENABLE_THREAD_UNSAFE_C_FUNCTIONS "Build libc++ with support for thread-unsafe C functions" ON) option(LIBCXX_ENABLE_MONOTONIC_CLOCK "Build libc++ with support for a monotonic clock. - This option may only be used when LIBCXX_ENABLE_THREADS=OFF." ON) + This option may only be set to OFF when LIBCXX_ENABLE_THREADS=OFF." ON) # Misc options ---------------------------------------------------------------- option(LIBCXX_ENABLE_PEDANTIC "Compile with pedantic enabled." ON) @@ -151,6 +151,7 @@ set(LIBCXX_COMPILE_FLAGS "") set(LIBCXX_LINK_FLAGS "") set(LIBCXX_LIBRARIES "") +set(LIBCXX_NEEDS_SITE_CONFIG OFF) # Configure compiler. include(config-ix) @@ -240,16 +241,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) @@ -283,10 +276,26 @@ 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 #=============================================================================== -include_directories(include) +include_directories(include + "${CMAKE_BINARY_DIR}/include/c++/v1") add_subdirectory(include) add_subdirectory(lib) 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 @@ -5,6 +5,7 @@ PATTERN "*" PATTERN "CMakeLists.txt" EXCLUDE PATTERN ".svn" EXCLUDE + PATTERN "__config_site.in" EXCLUDE ${LIBCXX_SUPPORT_HEADER_PATTERN} ) @@ -14,6 +15,12 @@ ${LIBCXX_HEADER_PATTERN} ) +if (LIBCXX_NEEDS_SITE_CONFIG) + file(RENAME ${LIBCXX_BINARY_DIR}/__config_site ${LIBCXX_BINARY_DIR}/include/c++/v1/__config) + file(READ ${LIBCXX_SOURCE_DIR}/include/__config CONFIG_CONTENTS) + file(APPEND ${LIBCXX_BINARY_DIR}/include/c++/v1/__config "${CONFIG_CONTENTS}") +endif() + if (LIBCXX_INSTALL_HEADERS) install(DIRECTORY . DESTINATION include/c++/v1 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/atomics/libcpp-has-no-threads.fail.cpp =================================================================== --- /dev/null +++ test/libcxx/atomics/libcpp-has-no-threads.fail.cpp @@ -0,0 +1,23 @@ +//===----------------------------------------------------------------------===// +// +// 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. +// +//===----------------------------------------------------------------------===// + +// + +// Test that including fails to compile when _LIBCPP_HAS_NO_THREADS +// is defined. + +#ifndef _LIBCPP_HAS_NO_THREADS +#define _LIBCPP_HAS_NO_THREADS +#endif + +#include + +int main() +{ +} Index: test/libcxx/atomics/libcpp-has-no-threads.pass.cpp =================================================================== --- /dev/null +++ test/libcxx/atomics/libcpp-has-no-threads.pass.cpp @@ -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. +// +//===----------------------------------------------------------------------===// +// XFAIL: libcpp-has-no-threads + +#include <__config> + +#ifdef _LIBCPP_HAS_NO_THREADS +#error This should be XFAIL'd for the purpose of detecting that the LIT feature\ + 'libcpp-has-no-threads' is available iff _LIBCPP_HAS_NO_THREADS is defined +#endif + +int main() +{ +} 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@" Index: test/std/utilities/date.time/tested_elsewhere.pass.cpp =================================================================== --- test/std/utilities/date.time/tested_elsewhere.pass.cpp +++ test/std/utilities/date.time/tested_elsewhere.pass.cpp @@ -30,9 +30,11 @@ static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); +#ifndef _LIBCPP_HAS_NO_THREAD_UNSAFE_C_FUNCTIONS static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); static_assert((std::is_same::value), ""); +#endif static_assert((std::is_same::value), ""); }