Index: libcxx/CMakeLists.txt =================================================================== --- libcxx/CMakeLists.txt +++ libcxx/CMakeLists.txt @@ -88,7 +88,13 @@ option(LIBCXX_ENABLE_ASSERTIONS "Enable assertions independent of build mode." OFF) option(LIBCXX_ENABLE_SHARED "Build libc++ as a shared library." ON) option(LIBCXX_ENABLE_STATIC "Build libc++ as a static library." ON) -option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ON) +set(ENABLE_EXPERIMENTAL_DEFAULT ON) +if (WIN32 AND LIBCXX_ENABLE_SHARED) + # When libc++ is built as a DLL, all headers indicate DLL linkage, while + # libc++experimental always is linked statically. + set(ENABLE_EXPERIMENTAL_DEFAULT OFF) +endif() +option(LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY "Build libc++experimental.a" ${ENABLE_EXPERIMENTAL_DEFAULT}) set(ENABLE_FILESYSTEM_DEFAULT ON) if (WIN32 AND NOT MINGW) # Filesystem is buildable for windows, but it requires __int128 helper @@ -399,6 +405,14 @@ message(FATAL_ERROR "Only one of LIBCXX_ABI_FORCE_ITANIUM and LIBCXX_ABI_FORCE_MICROSOFT can be specified.") endif () +if (WIN32 AND LIBCXX_ENABLE_SHARED AND LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) + message(FATAL_ERROR "LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY can't be enabled" + " when LIBCXX_ENABLE_SHARED also is enabled for Windows." + " The c++experimental library is only built as a" + " static library, while the headers signal dllimport" + " linkage.") +endif() + #=============================================================================== # Configure System #=============================================================================== Index: libcxx/docs/BuildingLibcxx.rst =================================================================== --- libcxx/docs/BuildingLibcxx.rst +++ libcxx/docs/BuildingLibcxx.rst @@ -90,7 +90,6 @@ -T "ClangCL" ^ -DLIBCXX_ENABLE_SHARED=YES ^ -DLIBCXX_ENABLE_STATIC=NO ^ - -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO ^ \path\to\libcxx > cmake --build . @@ -120,7 +119,6 @@ -DCMAKE_BUILD_TYPE=Release ^ -DCMAKE_C_COMPILER=clang-cl ^ -DCMAKE_CXX_COMPILER=clang-cl ^ - -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO ^ path/to/libcxx > ninja cxx > ninja check-cxx Index: libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp =================================================================== --- libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp +++ libcxx/test/libcxx/experimental/memory/memory.resource.adaptor/memory.resource.adaptor.mem/db_deallocate.pass.cpp @@ -14,6 +14,8 @@ // T* polymorphic_allocator::deallocate(T*, size_t size) +// XFAIL: LIBCXX-WINDOWS-FIXME + int AssertCount = 0; #define _LIBCPP_ASSERT(x, m) ((x) ? (void)0 : (void)::AssertCount++) Index: libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp +++ libcxx/test/std/input.output/filesystems/class.path/path.member/path.append.pass.cpp @@ -11,8 +11,6 @@ // These tests require locale for non-char paths // UNSUPPORTED: libcpp-has-no-localization -// XFAIL: LIBCXX-WINDOWS-FIXME - // // class path @@ -197,6 +195,9 @@ // required. // On Windows, the append method is more complex and uses intermediate // path objects, which causes extra allocations. + // In DLL builds on Windows, the overridden operator new won't pick up + // allocations done within the DLL, so the RequireAllocationGuard below + // won't necessarily see allocations in the cases where they're expected. #ifdef _WIN32 bool DisableAllocations = false; #else @@ -208,6 +209,7 @@ { RequireAllocationGuard g; // requires 1 or more allocations occur by default if (DisableAllocations) g.requireExactly(0); + else TEST_ONLY_WIN32_DLL(g.requireAtLeast(0)); LHS /= RHS; } assert(PathEq(LHS, E)); @@ -219,6 +221,7 @@ { RequireAllocationGuard g; if (DisableAllocations) g.requireExactly(0); + else TEST_ONLY_WIN32_DLL(g.requireAtLeast(0)); LHS.append(RHS, REnd); } assert(PathEq(LHS, E)); Index: libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp +++ libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03 -// XFAIL: LIBCXX-WINDOWS-FIXME - // // class path @@ -30,7 +28,9 @@ assert(globalMemCounter.checkOutstandingNewEq(0)); const std::string s("we really really really really really really really " "really really long string so that we allocate"); - assert(globalMemCounter.checkOutstandingNewEq(1)); + // On windows, the operator new from count_new.h can't override the default + // operator for calls within the libc++ DLL. + TEST_NOT_WIN32_DLL(assert(globalMemCounter.checkOutstandingNewEq(1))); const fs::path::string_type ps(s.begin(), s.end()); path p(s); { Index: libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp +++ libcxx/test/std/input.output/filesystems/class.path/path.member/path.concat.pass.cpp @@ -11,8 +11,6 @@ // These tests require locale for non-char paths // UNSUPPORTED: libcpp-has-no-localization -// XFAIL: LIBCXX-WINDOWS-FIXME - // // class path @@ -142,6 +140,10 @@ // code_cvt conversions. // For the path native type, no allocations will be performed because no // conversion is required. + + // In DLL builds on Windows, the overridden operator new won't pick up + // allocations done within the DLL, so the RequireAllocationGuard below + // won't necessarily see allocations in the cases where they're expected. bool DisableAllocations = std::is_same::value; { path LHS(L); PathReserve(LHS, ReserveSize); @@ -149,6 +151,7 @@ { RequireAllocationGuard g; // requires 1 or more allocations occur by default if (DisableAllocations) g.requireExactly(0); + else TEST_ONLY_WIN32_DLL(g.requireAtLeast(0)); LHS += RHS; } assert(LHS == E); @@ -160,6 +163,7 @@ { RequireAllocationGuard g; if (DisableAllocations) g.requireExactly(0); + else TEST_ONLY_WIN32_DLL(g.requireAtLeast(0)); LHS.concat(RHS, REnd); } assert(LHS == E); Index: libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp =================================================================== --- libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp +++ libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp @@ -8,8 +8,6 @@ // UNSUPPORTED: c++03 -// XFAIL: LIBCXX-WINDOWS-FIXME - // // class path @@ -30,7 +28,9 @@ assert(globalMemCounter.checkOutstandingNewEq(0)); const std::string s("we really really really really really really really " "really really long string so that we allocate"); - assert(globalMemCounter.checkOutstandingNewEq(1)); + // On windows, the operator new from count_new.h can't override the default + // operator for calls within the libc++ DLL. + TEST_NOT_WIN32_DLL(assert(globalMemCounter.checkOutstandingNewEq(1))); const fs::path::string_type ps(s.begin(), s.end()); path p(s); { Index: libcxx/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp =================================================================== --- libcxx/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp +++ libcxx/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp @@ -12,8 +12,6 @@ // ~ctype(); -// XFAIL: LIBCXX-WINDOWS-FIXME - #include #include @@ -39,7 +37,9 @@ new std::ctype(new std::ctype::mask[256], true)); assert(globalMemCounter.checkDeleteArrayCalledEq(0)); } - assert(globalMemCounter.checkDeleteArrayCalledEq(1)); + // On windows, the operator new from count_new.h can't override the default + // operator for calls within the libc++ DLL. + TEST_NOT_WIN32_DLL(assert(globalMemCounter.checkDeleteArrayCalledEq(1))); return 0; } Index: libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp =================================================================== --- libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp +++ libcxx/test/std/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp @@ -8,7 +8,8 @@ // // UNSUPPORTED: libcpp-has-no-threads -// XFAIL: LIBCXX-WINDOWS-FIXME +// FIXME: Unclear why this fails in DLL mode. +// XFAIL: windows-dll // Index: libcxx/test/support/test_macros.h =================================================================== --- libcxx/test/support/test_macros.h +++ libcxx/test/support/test_macros.h @@ -378,6 +378,14 @@ #define TEST_NOT_WIN32(...) __VA_ARGS__ #endif +#if defined(_WIN32) && !defined(_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS) +#define TEST_NOT_WIN32_DLL(...) ((void)0) +#define TEST_ONLY_WIN32_DLL(...) __VA_ARGS__ +#else +#define TEST_NOT_WIN32_DLL(...) __VA_ARGS__ +#define TEST_ONLY_WIN32_DLL(...) ((void)0) +#endif + #ifdef _WIN32 #define TEST_WIN_NO_FILESYSTEM_PERMS_NONE #endif Index: libcxx/utils/ci/buildkite-pipeline.yml =================================================================== --- libcxx/utils/ci/buildkite-pipeline.yml +++ libcxx/utils/ci/buildkite-pipeline.yml @@ -18,306 +18,7 @@ # steps: - # - # Light pre-commit tests for things like formatting or when people forget - # to update generated files. - # - - label: "Format" - command: "libcxx/utils/ci/run-buildbot check-format" - artifact_paths: - - "**/clang-format.patch" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - soft_fail: - - exit_status: 1 - - - label: "Generated output" - command: "libcxx/utils/ci/run-buildbot check-generated-output" - artifact_paths: - - "**/generated_output.patch" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - # - # General testing with the default configuration, under all the supported - # Standard modes, with Clang and GCC. This catches most issues upfront. - # The goal of this step is to catch most issues while being very fast. - # - - wait - - - label: "C++03" - command: "libcxx/utils/ci/run-buildbot generic-cxx03" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "C++11" - command: "libcxx/utils/ci/run-buildbot generic-cxx11" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "C++14" - command: "libcxx/utils/ci/run-buildbot generic-cxx14" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "C++17" - command: "libcxx/utils/ci/run-buildbot generic-cxx17" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "C++20" - command: "libcxx/utils/ci/run-buildbot generic-cxx20" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "C++2b" - command: "libcxx/utils/ci/run-buildbot generic-cxx2b" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "GCC/C++20" - command: "libcxx/utils/ci/run-buildbot generic-gcc" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - # - # All other supported configurations of libc++. - # - - wait - - - label: "-fno-exceptions" - command: "libcxx/utils/ci/run-buildbot generic-noexceptions" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Static libraries" - command: "libcxx/utils/ci/run-buildbot generic-static" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "ASAN" - command: "libcxx/utils/ci/run-buildbot generic-asan" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "TSAN" - command: "libcxx/utils/ci/run-buildbot generic-tsan" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "UBSAN" - command: "libcxx/utils/ci/run-buildbot generic-ubsan" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "With LLVM's libunwind" - command: "libcxx/utils/ci/run-buildbot generic-with_llvm_unwinder" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Single-threaded" - command: "libcxx/utils/ci/run-buildbot generic-singlethreaded" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "No debug mode" - command: "libcxx/utils/ci/run-buildbot generic-no-debug" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "No Filesystem" - command: "libcxx/utils/ci/run-buildbot generic-no-filesystem" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "No random device" - command: "libcxx/utils/ci/run-buildbot generic-no-random_device" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "No locale" - command: "libcxx/utils/ci/run-buildbot generic-no-localization" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Benchmarks" - command: "libcxx/utils/ci/run-buildbot benchmarks" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Documentation" - command: "libcxx/utils/ci/run-buildbot documentation" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Legacy standalone build" - command: "libcxx/utils/ci/run-buildbot legacy-standalone" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Unified standalone build" - command: "libcxx/utils/ci/run-buildbot unified-standalone" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Runtimes build" - command: "libcxx/utils/ci/run-buildbot runtimes-build" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Windows" + - label: "Windows (DLL)" command: "bash libcxx/utils/ci/run-buildbot generic-win" artifact_paths: - "**/test-results.xml" @@ -328,131 +29,12 @@ - exit_status: -1 # Agent was lost limit: 2 - - label: "MacOS C++20" - command: "libcxx/utils/ci/run-buildbot generic-cxx20" - artifact_paths: - - "**/test-results.xml" - - "**/*.abilist" - agents: - queue: "libcxx-builders-macos" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - # Build with the configuration we use to generate libc++.dylib on Apple platforms - - label: "Apple system" - command: "libcxx/utils/ci/run-buildbot x86_64-apple-system" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-macos" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Apple system -fno-exceptions" - command: "libcxx/utils/ci/run-buildbot x86_64-apple-system-noexceptions" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-macos" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - # Test back-deployment to older Apple platforms - - label: "Apple back-deployment macosx10.9" - command: "libcxx/utils/ci/run-buildbot x86_64-apple-system-backdeployment-10.9" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-macos10.15" # TODO: For now, we're running the back-deployment tests for 10.9 on 10.15, because we don't have proper 10.9 machines - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Apple back-deployment macosx10.15" - command: "libcxx/utils/ci/run-buildbot x86_64-apple-system-backdeployment-10.15" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-macos10.15" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "AArch64" - command: "libcxx/utils/ci/run-buildbot aarch64" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-linaro-arm" - arch: "aarch64" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "AArch64 -fno-exceptions" - command: "libcxx/utils/ci/run-buildbot aarch64-noexceptions" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-linaro-arm" - arch: "aarch64" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Armv8" - command: "libcxx/utils/ci/run-buildbot armv8" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-linaro-arm" - arch: "armv8l" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Armv8 -fno-exceptions" - command: "libcxx/utils/ci/run-buildbot armv8-noexceptions" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-linaro-arm" - arch: "armv8l" - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Armv7" - command: "libcxx/utils/ci/run-buildbot armv7" - artifact_paths: - - "**/test-results.xml" - agents: - queue: "libcxx-builders-linaro-arm" - arch: "armv8l" # Compiling for v7, running on v8 hardware - retry: - automatic: - - exit_status: -1 # Agent was lost - limit: 2 - - - label: "Armv7 -fno-exceptions" - command: "libcxx/utils/ci/run-buildbot armv7-noexceptions" + - label: "Windows (Static)" + command: "bash libcxx/utils/ci/run-buildbot generic-win" artifact_paths: - "**/test-results.xml" agents: - queue: "libcxx-builders-linaro-arm" - arch: "armv8l" # Compiling for v7, running on v8 hardware + queue: "windows" retry: automatic: - exit_status: -1 # Agent was lost Index: libcxx/utils/ci/run-buildbot =================================================================== --- libcxx/utils/ci/run-buildbot +++ libcxx/utils/ci/run-buildbot @@ -473,7 +473,7 @@ generate-cmake -C "${MONOREPO_ROOT}/libcxx/cmake/caches/Armv7Thumb-noexceptions.cmake" check-cxx-cxxabi ;; -generic-win) +generic-win*) clean # TODO: Clang-cl in MSVC configurations don't have access to compiler_rt # builtins helpers for int128 division. See @@ -489,12 +489,10 @@ # the "clang-cl" driver for compiling). When the CI runner runs # Clang 12, the "-loldnames" option can be dropped. - # TODO: Currently, building with the experimental library breaks running - # tests (the test linking look for the c++experimental library with the - # wrong name, and the statically linked c++experimental can't be linked - # correctly when libc++ visibility attributes indicate dllimport linkage - # anyway), thus just disable the experimental library. Remove this - # setting when cmake and the test driver does the right thing automatically. + CMAKE_FLAGS="" + if [ "${BUILDER}" = "generic-win-static" ]; then + CMAKE_FLAGS="$CMAKE_FLAGS -DLIBCXX_ENABLE_SHARED=NO" + fi echo "--- Generating CMake" cmake -S "${MONOREPO_ROOT}/libcxx" \ @@ -504,11 +502,11 @@ -DCMAKE_C_COMPILER=clang-cl \ -DCMAKE_CXX_COMPILER=clang-cl \ -DLLVM_LIT_ARGS="-sv --show-unsupported --xunit-xml-output test-results.xml" \ - -DLIBCXX_ENABLE_EXPERIMENTAL_LIBRARY=NO \ -DLIBCXX_ENABLE_FILESYSTEM=YES \ -DCMAKE_CXX_FLAGS="-D_LIBCPP_HAS_NO_INT128" \ -DLIBCXX_TEST_COMPILER_FLAGS="-D_LIBCPP_HAS_NO_INT128" \ - -DLIBCXX_TEST_LINKER_FLAGS="-loldnames" + -DLIBCXX_TEST_LINKER_FLAGS="-loldnames" \ + ${CMAKE_FLAGS} echo "+++ Running the libc++ tests" ${NINJA} -vC "${BUILD_DIR}" check-cxx ;;