llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libcxx Author: hu1 (huihui15537226823) <details> <summary>Changes</summary> ## Summary This patch adds OHOS AArch64 support for running the libc++ runtimes test suite, including libc++, libc++abi, and libunwind. The main pieces are: - Add OHOS-specific lit configurations for libc++, libc++abi, and libunwind. - Add an OHOS executor path for running tests on device through HDC. - Add an OHOS QEMU user-mode executor, which is easier to use for local and CI testing when physical OHOS devices are not available. - Configure OHOS libc++ builds to use the `__h` ABI namespace by default through `LIBCXX_ABI_NAMESPACE=__h`. - Add `ohos-qemu` / `ohos-hdc` lit features so tests can distinguish QEMU user-mode from real-device execution. - Mark a small number of tests unsupported under `ohos-qemu` where QEMU user-mode does not match real OHOS device behavior, such as `/proc`, signal unwinding, or very thread-heavy stress tests. These tests remain available for HDC/device testing. ## Motivation This makes it possible to continuously validate OHOS libc++ runtimes support inside the upstream libc++ CI structure. The QEMU path is the recommended default for general CI usage because it does not require dedicated phone/device infrastructure. The HDC path is still supported for real-device validation when an OHOS device is available. ## Sysroot Requirement The OHOS QEMU sysroot is expected to be provided by the local machine or CI agent and passed through `--ohos-qemu-sysroot` or `OHOS_QEMU_SYSROOT`. It is not vendored into the LLVM source tree. ## Local Testing A typical full OHOS AArch64 QEMU test run can be launched with: ```bash cd /home/cdx/hwasan/llvm/llvm-project unset HDC HDC_UTID HDC_TIMEOUT_SECONDS export OHOS_SYSROOT=/home/xxx/sysroot/aarch64-linux-ohos export CC=/home/xxx/llvm/out/llvm23-ohos-toolchain-install/bin/clang export CXX=/home/xxx/llvm/out/llvm23-ohos-toolchain-install/bin/clang++ export OHOS_LIBCXX_ABI_NAMESPACE=__h libcxx/utils/ci/run-buildbot \ --ohos-qemu /usr/bin/qemu-aarch64 \ --ohos-qemu-sysroot /home/xxx/llvm/out/qemu-sysroot-aarch64-linux-ohos \ --build-dir /home/xxx/oh1/builds/llvm-ohos-qemu-full-habi \ ohos-aarch64-full \ 2>&1 | tee /home/xxx/oh1/logs/7.9.log ``` The HDC/device path can also be used by providing `HDC`/device environment variables and running the `ohos-hdc-aarch64-full` builder. ## Notes The QEMU executor is intended to provide a convenient and reproducible CI mode. Some tests are intentionally disabled only for `ohos-qemu` when the failure is caused by QEMU user-mode behavior rather than libc++/libc++abi/libunwind correctness on a real OHOS device. --- Patch is 109.83 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/208390.diff 109 Files Affected: - (modified) cmake/Modules/GetToolchainDirs.cmake (+23-14) - (modified) compiler-rt/cmake/Modules/CompilerRTUtils.cmake (+6-2) - (modified) compiler-rt/cmake/builtin-config-ix.cmake (+1-1) - (modified) compiler-rt/cmake/crt-config-ix.cmake (+1-1) - (modified) compiler-rt/lib/builtins/crtbegin.c (+9) - (modified) compiler-rt/lib/builtins/emutls.c (+4-4) - (modified) libcxx/CMakeLists.txt (+8-2) - (modified) libcxx/cmake/config-ix.cmake (+2) - (modified) libcxx/include/__config (+3-2) - (modified) libcxx/include/__cxx03/__config (+3-2) - (modified) libcxx/include/__cxx03/__locale_dir/locale_base_api.h (+1-1) - (modified) libcxx/include/__locale_dir/locale_base_api.h (+1-1) - (modified) libcxx/src/include/config_elast.h (+2) - (added) libcxx/test/configs/llvm-libc++-ohos.cfg.in (+63) - (modified) libcxx/test/extensions/clang/clang_modules_include.gen.py (+3) - (modified) libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp (+1) - (modified) libcxx/test/selftest/dsl/dsl.sh.py (+5) - (modified) libcxx/test/selftest/stdin-is-piped.sh.cpp (+1) - (modified) libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp (+3) - (modified) libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/refresh.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/replace_filename.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_size.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/file_type_obs.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/hard_link_count.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.obs/last_write_time.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.directory_iterator/directory_iterator.members/ctor.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.path/path.member/path.assign/move.pass.cpp (+1-1) - (modified) libcxx/test/std/input.output/filesystems/class.path/path.member/path.construct/move.pass.cpp (+1-1) - (modified) libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/ctor.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/class.rec.dir.itr/rec.dir.itr.members/increment.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.copy_file/copy_file_procfs.pass.cpp (+2) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.exists/exists.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_block_file/is_block_file.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_char_file/is_character_file.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_directory/is_directory.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_empty/is_empty.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_fifo/is_fifo.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_other/is_other.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_regular_file/is_regular_file.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_socket/is_socket.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.is_symlink/is_symlink.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.last_write_time/last_write_time.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove/remove.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.remove_all/remove_all.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.status/status.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.symlink_status/symlink_status.pass.cpp (+1) - (modified) libcxx/test/std/input.output/filesystems/fs.op.funcs/fs.op.temp_dir_path/temp_directory_path.pass.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.format/ext.manip/get_money.pass.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.format/ext.manip/put_money.pass.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.formatted.print/locale-specific_form.pass.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.format/print.fun/no_file_description.pass.cpp (+3) - (modified) libcxx/test/std/input.output/iostream.format/std.manip/setfill_wchar_max.pass.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.objects/narrow.stream.objects/cerr.sh.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.objects/narrow.stream.objects/cin.sh.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.objects/narrow.stream.objects/clog.sh.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wcerr-imbue.sh.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wcerr.sh.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wcin-imbue.sh.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wcin.sh.cpp (+1) - (modified) libcxx/test/std/input.output/iostream.objects/wide.stream.objects/wclog.sh.cpp (+1) - (modified) libcxx/test/std/input.output/syncstream/osyncstream/thread/several_threads.pass.cpp (+2) - (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array.pass.cpp (+1) - (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.array/sized_delete_array_calls_unsized_delete_array.pass.cpp (+1) - (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete.pass.cpp (+1) - (modified) libcxx/test/std/language.support/support.dynamic/new.delete/new.delete.single/sized_delete_calls_unsized_delete.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/compare.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.collate/locale.collate.byname/transform.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/facet.ctype.special/facet.ctype.char.dtor/dtor.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/is_1.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/is_many.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/scan_is.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/scan_not.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_1.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/tolower_many.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_1.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/toupper_many.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_1.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.ctype/locale.ctype.byname/widen_many.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_en_US.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_long_double_zh_CN.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.monetary/locale.money.get/locale.money.get.members/get_string_en_US.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_en_US.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_long_double_zh_CN.pass.cpp (+1) - (modified) libcxx/test/std/localization/locale.categories/category.monetary/locale.money.put/locale.money.put.members/put_string_en_US.pass.cpp (+1) - (modified) libcxx/test/std/localization/locales/locale/locale.cons/default.pass.cpp (+1) - (modified) libcxx/test/std/re/re.traits/transform.pass.cpp (+1) - (modified) libcxx/test/std/re/re.traits/transform_primary.pass.cpp (+1) - (modified) libcxx/test/std/thread/futures/futures.async/thread_create_failure.pass.cpp (+1) - (modified) libcxx/test/std/thread/thread.jthread/join.deadlock.pass.cpp (+1) - (modified) libcxx/test/std/utilities/format/format.functions/locale-specific_form.pass.cpp (+1) - (modified) libcxx/test/support/count_new.h (+28) - (modified) libcxx/test/support/filesystem_test_helper.h (+3-1) - (modified) libcxx/test/support/test_macros.h (+3-1) - (modified) libcxx/utils/ci/buildkite-pipeline.yml (+15) - (modified) libcxx/utils/ci/run-buildbot (+91) - (added) libcxx/utils/ci/vendor/ohos/hdc_run.py (+472) - (added) libcxx/utils/ci/vendor/ohos/hdc_run_test.py (+115) - (added) libcxx/utils/ci/vendor/ohos/qemu_run.py (+144) - (modified) libcxxabi/CMakeLists.txt (+6-1) - (added) libcxxabi/test/configs/llvm-libc++abi-ohos.cfg.in (+36) - (modified) libcxxabi/test/guard_threaded_test.pass.cpp (+2) - (modified) libunwind/CMakeLists.txt (+6-1) - (modified) libunwind/src/Registers.hpp (+9-6) - (modified) libunwind/test/aarch64_za_unwind.pass.cpp (+7-6) - (modified) libunwind/test/bad_unwind_info.pass.cpp (+2) - (added) libunwind/test/configs/llvm-libunwind-ohos.cfg.in (+61) - (modified) libunwind/test/signal_unwind.pass.cpp (+2) ``````````diff diff --git a/cmake/Modules/GetToolchainDirs.cmake b/cmake/Modules/GetToolchainDirs.cmake index 7568734e3f25d..1e8a3e4e015ca 100644 --- a/cmake/Modules/GetToolchainDirs.cmake +++ b/cmake/Modules/GetToolchainDirs.cmake @@ -79,7 +79,15 @@ function(get_runtimes_target_libdir_common default_target_triple arch variable) string(FIND "${default_target_triple}" "-" dash_index) string(SUBSTRING "${default_target_triple}" "${dash_index}" -1 triple_suffix) string(SUBSTRING "${default_target_triple}" 0 "${dash_index}" triple_cpu) - if(ANDROID AND "${arch}" STREQUAL "i386") + if("${triple_suffix}" MATCHES "linux-ohos") + if("${arch}" STREQUAL "i386") + set(target "i686-linux-ohos") + elseif("${arch}" MATCHES "^arm") + set(target "arm-linux-ohos") + else() + set(target "${arch}-linux-ohos") + endif() + elseif(ANDROID AND "${arch}" STREQUAL "i386") set(target "i686${triple_suffix}") elseif("${arch}" STREQUAL "amd64") set(target "x86_64${triple_suffix}") @@ -125,25 +133,26 @@ function(get_runtimes_target_libdir_common default_target_triple arch variable) set("${variable}" "${target}" PARENT_SCOPE) endfunction() - -# Corresponds to Clang's ToolChain::getRuntimePath(). -function (get_toolchain_target_dirname outvar) - string(FIND "${LLVM_TARGET_TRIPLE}" "-" dash_index) +function(get_runtimes_target_dirname default_target_triple variable) + string(FIND "${default_target_triple}" "-" dash_index) if (dash_index EQUAL "-1") - # This means LLVM_TARGET_TRIPLE is not set and we cannot derive the dirname - # from it. The proper behavior here would be to emit an error since we have - # no target we can build for. However, compiler-rt uses - # COMPILER_RT_DEFAULT_TARGET_TRIPLE instead and ignores LLVM_TARGET_TRIPLE. - # To not break the build when building only compiler-rt, we skip the triple - # subdirectory. set(target "") else () - string(SUBSTRING "${LLVM_TARGET_TRIPLE}" 0 "${dash_index}" triple_cpu) + string(SUBSTRING "${default_target_triple}" 0 "${dash_index}" triple_cpu) set(arch "${triple_cpu}") if("${arch}" MATCHES "^i.86$") set(arch "i386") endif() - get_runtimes_target_libdir_common("${LLVM_TARGET_TRIPLE}" "${arch}" target) - endif () + get_runtimes_target_libdir_common("${default_target_triple}" "${arch}" target) + endif() + set("${variable}" "${target}" PARENT_SCOPE) +endfunction() + + +# Corresponds to Clang's ToolChain::getRuntimePath(). +function (get_toolchain_target_dirname outvar) + # If LLVM_TARGET_TRIPLE is unset, this intentionally returns an empty + # directory to preserve the historical compiler-rt-only behavior. + get_runtimes_target_dirname("${LLVM_TARGET_TRIPLE}" target) set("${outvar}" "${target}" PARENT_SCOPE) endfunction() diff --git a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake index 75216ed704bce..af55b2166de60 100644 --- a/compiler-rt/cmake/Modules/CompilerRTUtils.cmake +++ b/compiler-rt/cmake/Modules/CompilerRTUtils.cmake @@ -491,8 +491,12 @@ endfunction() function(get_compiler_rt_target arch variable) if(COMPILER_RT_DEFAULT_TARGET_ONLY) - # Use exact spelling when building only for the target specified to CMake. - set(target "${COMPILER_RT_DEFAULT_TARGET_TRIPLE}") + if(CMAKE_SYSTEM_NAME STREQUAL "OHOS") + get_runtimes_target_libdir_common("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" "${arch}" target) + else() + # Use exact spelling when building only for the target specified to CMake. + set(target "${COMPILER_RT_DEFAULT_TARGET_TRIPLE}") + endif() else() get_runtimes_target_libdir_common("${COMPILER_RT_DEFAULT_TARGET_TRIPLE}" "${arch}" target) endif() diff --git a/compiler-rt/cmake/builtin-config-ix.cmake b/compiler-rt/cmake/builtin-config-ix.cmake index 528268da729fb..90d9e451ff109 100644 --- a/compiler-rt/cmake/builtin-config-ix.cmake +++ b/compiler-rt/cmake/builtin-config-ix.cmake @@ -297,7 +297,7 @@ else() endforeach() endif() -if(OS_NAME MATCHES "Linux|SerenityOS" AND NOT LLVM_USE_SANITIZER AND NOT +if(OS_NAME MATCHES "Linux|SerenityOS|OHOS" AND NOT LLVM_USE_SANITIZER AND NOT COMPILER_RT_GPU_BUILD) set(COMPILER_RT_HAS_CRT TRUE) else() diff --git a/compiler-rt/cmake/crt-config-ix.cmake b/compiler-rt/cmake/crt-config-ix.cmake index ebc7d671e74ee..64112f1636b09 100644 --- a/compiler-rt/cmake/crt-config-ix.cmake +++ b/compiler-rt/cmake/crt-config-ix.cmake @@ -47,7 +47,7 @@ if(NOT APPLE) message(STATUS "Supported architectures for crt: ${CRT_SUPPORTED_ARCH}") endif() -if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|SerenityOS" AND NOT LLVM_USE_SANITIZER) +if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux|SerenityOS|OHOS" AND NOT LLVM_USE_SANITIZER) set(COMPILER_RT_HAS_CRT TRUE) else() set(COMPILER_RT_HAS_CRT FALSE) diff --git a/compiler-rt/lib/builtins/crtbegin.c b/compiler-rt/lib/builtins/crtbegin.c index 74becdbe5dd0e..381a69fac4664 100644 --- a/compiler-rt/lib/builtins/crtbegin.c +++ b/compiler-rt/lib/builtins/crtbegin.c @@ -36,6 +36,10 @@ extern fp __CTOR_LIST_END__[]; extern void __cxa_finalize(void *) __attribute__((weak)); +#if defined(__OHOS__) +extern void __at_fini() __attribute__((weak)); +#endif + static void __attribute__((used)) __do_init(void) { static _Bool __initialized; if (__builtin_expect(__initialized, 0)) @@ -114,6 +118,11 @@ static void __attribute__((used)) __do_fini(void) { return; __finalized = 1; +#if defined(__OHOS__) + if (__at_fini) + __at_fini(); +#endif + if (__cxa_finalize) __cxa_finalize(__dso_handle); diff --git a/compiler-rt/lib/builtins/emutls.c b/compiler-rt/lib/builtins/emutls.c index a8a5d7c0749a8..2d15d8e249f43 100644 --- a/compiler-rt/lib/builtins/emutls.c +++ b/compiler-rt/lib/builtins/emutls.c @@ -12,7 +12,7 @@ #include "int_lib.h" -#ifdef __BIONIC__ +#if defined(__BIONIC__) || defined(__OHOS__) // There are 4 pthread key cleanup rounds on Bionic. Delay emutls deallocation // to round 2. We need to delay deallocation because: // - Android versions older than M lack __cxa_thread_atexit_impl, so apps @@ -51,7 +51,7 @@ static void emutls_shutdown(emutls_address_array *array); static pthread_mutex_t emutls_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t emutls_pthread_key; -#ifdef __BIONIC__ +#if defined(__BIONIC__) || defined(__OHOS__) static bool emutls_key_created = false; #endif @@ -401,8 +401,8 @@ void *__emutls_get_address(__emutls_control *control) { return array->data[index]; } -#ifdef __BIONIC__ -// Called by Bionic on dlclose to delete the emutls pthread key. +#if defined(__BIONIC__) || defined(__OHOS__) +// Called by Bionic/OHOS on dlclose to delete the emutls pthread key. __attribute__((visibility("hidden"))) void __emutls_unregister_key(void) { if (emutls_key_created) { pthread_key_delete(emutls_pthread_key); diff --git a/libcxx/CMakeLists.txt b/libcxx/CMakeLists.txt index 845240d1b894c..9a1af0ced8965 100644 --- a/libcxx/CMakeLists.txt +++ b/libcxx/CMakeLists.txt @@ -277,7 +277,8 @@ option(LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY # or we don't have any ABI library. if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY OR NOT LIBCXX_ENABLE_SHARED - OR LIBCXX_CXX_ABI STREQUAL "none") + OR LIBCXX_CXX_ABI STREQUAL "none" + OR CMAKE_SYSTEM_NAME STREQUAL "OHOS") set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE OFF) elseif((UNIX OR FUCHSIA) AND NOT APPLE) set(ENABLE_LINKER_SCRIPT_DEFAULT_VALUE ON) @@ -450,7 +451,12 @@ set(LIBCXX_STATIC_OUTPUT_NAME "c++" CACHE STRING "Output name for the static lib # TODO: Use common runtimes infrastructure for output and install paths if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) - set(LIBCXX_TARGET_SUBDIR ${LLVM_DEFAULT_TARGET_TRIPLE}) + if(CMAKE_SYSTEM_NAME STREQUAL "OHOS") + include(GetToolchainDirs) + get_runtimes_target_dirname("${LLVM_DEFAULT_TARGET_TRIPLE}" LIBCXX_TARGET_SUBDIR) + else() + set(LIBCXX_TARGET_SUBDIR ${LLVM_DEFAULT_TARGET_TRIPLE}) + endif() if(LIBCXX_LIBDIR_SUBDIR) string(APPEND LIBCXX_TARGET_SUBDIR /${LIBCXX_LIBDIR_SUBDIR}) endif() diff --git a/libcxx/cmake/config-ix.cmake b/libcxx/cmake/config-ix.cmake index 270d80575adcf..e0e5a3c3094d2 100644 --- a/libcxx/cmake/config-ix.cmake +++ b/libcxx/cmake/config-ix.cmake @@ -126,6 +126,8 @@ elseif(PICOLIBC) set(LIBCXX_HAS_PTHREAD_LIB NO) set(LIBCXX_HAS_RT_LIB NO) set(LIBCXX_HAS_ATOMIC_LIB NO) +elseif(OHOS) + set(LIBCXX_HAS_ATOMIC_LIB NO) else() check_library_exists(pthread pthread_create "" LIBCXX_HAS_PTHREAD_LIB) check_library_exists(rt clock_gettime "" LIBCXX_HAS_RT_LIB) diff --git a/libcxx/include/__config b/libcxx/include/__config index fdd0558fbec6f..c7da0ec54447c 100644 --- a/libcxx/include/__config +++ b/libcxx/include/__config @@ -292,7 +292,8 @@ typedef __char32_t char32_t; defined(__APPLE__) || \ defined(__MVS__) || \ defined(_AIX) || \ - defined(__EMSCRIPTEN__) + defined(__EMSCRIPTEN__) || \ + defined(__OHOS_FAMILY__) // clang-format on # undef _LIBCPP_HAS_THREAD_API_PTHREAD # define _LIBCPP_HAS_THREAD_API_PTHREAD 1 @@ -371,7 +372,7 @@ typedef __char32_t char32_t; # endif # if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \ - _LIBCPP_HAS_MUSL_LIBC || defined(__OpenBSD__) || _LIBCPP_LIBC_LLVM_LIBC + _LIBCPP_HAS_MUSL_LIBC || defined(__OpenBSD__) || _LIBCPP_LIBC_LLVM_LIBC || defined(__OHOS_FAMILY__) # define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE # endif diff --git a/libcxx/include/__cxx03/__config b/libcxx/include/__cxx03/__config index 27c26084da4b1..d9078a4ddf0d0 100644 --- a/libcxx/include/__cxx03/__config +++ b/libcxx/include/__cxx03/__config @@ -680,7 +680,8 @@ typedef __char32_t char32_t; defined(__APPLE__) || \ defined(__MVS__) || \ defined(_AIX) || \ - defined(__EMSCRIPTEN__) + defined(__EMSCRIPTEN__) || \ + defined(__OHOS_FAMILY__) // clang-format on # define _LIBCPP_HAS_THREAD_API_PTHREAD # elif defined(__Fuchsia__) @@ -753,7 +754,7 @@ typedef __char32_t char32_t; # endif # if defined(__BIONIC__) || defined(__NuttX__) || defined(__Fuchsia__) || defined(__wasi__) || \ - defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) + defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OpenBSD__) || defined(__OHOS_FAMILY__) # define _LIBCPP_PROVIDES_DEFAULT_RUNE_TABLE # endif diff --git a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h index 3dbce825bc76c..a107aeeae5da4 100644 --- a/libcxx/include/__cxx03/__locale_dir/locale_base_api.h +++ b/libcxx/include/__cxx03/__locale_dir/locale_base_api.h @@ -23,7 +23,7 @@ # include <__cxx03/__locale_dir/locale_base_api/openbsd.h> #elif defined(__Fuchsia__) # include <__cxx03/__locale_dir/locale_base_api/fuchsia.h> -#elif defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) +#elif defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC) || defined(__OHOS_FAMILY__) # include <__cxx03/__locale_dir/locale_base_api/musl.h> #elif defined(__APPLE__) || defined(__FreeBSD__) # include <__cxx03/xlocale.h> diff --git a/libcxx/include/__locale_dir/locale_base_api.h b/libcxx/include/__locale_dir/locale_base_api.h index e1e60e18fd7c6..7dbbbd0b11654 100644 --- a/libcxx/include/__locale_dir/locale_base_api.h +++ b/libcxx/include/__locale_dir/locale_base_api.h @@ -120,7 +120,7 @@ # include <__locale_dir/support/fuchsia.h> # elif _LIBCPP_LIBC_LLVM_LIBC # include <__locale_dir/support/llvm_libc.h> -# elif defined(__linux__) +# elif defined(__linux__) || defined(__OHOS_FAMILY__) # include <__locale_dir/support/linux.h> # elif _LIBCPP_LIBC_NEWLIB # include <__locale_dir/support/newlib.h> diff --git a/libcxx/src/include/config_elast.h b/libcxx/src/include/config_elast.h index daec2429de8eb..328a77d9934a5 100644 --- a/libcxx/src/include/config_elast.h +++ b/libcxx/src/include/config_elast.h @@ -43,6 +43,8 @@ # define _LIBCPP_ELAST (_sys_nerr - 1) #elif defined(_AIX) # define _LIBCPP_ELAST 127 +#elif defined(__OHOS_FAMILY__) +// No _LIBCPP_ELAST needed on OHOS #else // Warn here so that the person doing the libcxx port has an easier time: # warning ELAST for this platform not yet implemented diff --git a/libcxx/test/configs/llvm-libc++-ohos.cfg.in b/libcxx/test/configs/llvm-libc++-ohos.cfg.in new file mode 100644 index 0000000000000..3be1c267ede2a --- /dev/null +++ b/libcxx/test/configs/llvm-libc++-ohos.cfg.in @@ -0,0 +1,63 @@ +# This testing configuration handles running the test suite against LLVM's +# libc++ using HDC or QEMU on OHOS. + +lit_config.load_config(config, '@CMAKE_CURRENT_BINARY_DIR@/cmake-bridge.cfg') + +config.substitutions.append(('%{flags}', + ('--sysroot @CMAKE_SYSROOT@ ' if '@CMAKE_SYSROOT@' else '') + '-pthread' +)) +config.substitutions.append(('%{compile_flags}', + '-nostdinc++ -I %{target-include-dir} -I %{include-dir} -I %{libcxx-dir}/test/support ' + '-DTEST_HAS_NO_RELIABLE_LIBRARY_INTERNAL_ALLOCATIONS' +)) +config.substitutions.append(('%{link_flags}', + # Link libc++abi/libunwind directly: lld won't resolve libc++'s transitive + # DT_NEEDED entries when building the test executable. + '-nostdlib++ -L %{lib-dir} -l@LIBCXX_SHARED_OUTPUT_NAME@ -lc++abi -lunwind' +)) +config.substitutions.append(('%{exec}', + '%{executor} --execdir %{temp} -- ' +)) + +import os, site +site.addsitedir(os.path.join('@LIBCXX_SOURCE_DIR@', 'utils')) +import libcxx.test.params, libcxx.test.config + +executor_kind = lit_config.params.get( + 'executor_kind', getattr(config, 'executor_kind', 'ohos-hdc') +) +if executor_kind not in ('ohos-hdc', 'ohos-qemu'): + lit_config.fatal(f'unsupported OHOS executor_kind: {executor_kind}') + +config.available_features.add('LIBCXX-OHOS-FIXME') +config.available_features.add(executor_kind) +config.available_features.add('platform-has-nonportable-locales') +config.available_features.add('platform-has-unreliable-new-delete-interposition') +config.available_features.add('pthread-join-self-deadlocks') + +if executor_kind == 'ohos-hdc': + config.available_features.add('executor-has-no-stdin') + config.available_features.add('executor-merges-stderr-into-stdout') + config.available_features.add('executor-runs-as-root') + +libcxx.test.config.configure( + libcxx.test.params.DEFAULT_PARAMETERS, + libcxx.test.features.DEFAULT_FEATURES, + config, + lit_config +) + +# The generic libc++ hardening-mode feature probe executes a target binary via +# %{exec}. On OHOS/HDC that probe can fail for runner reasons even though the +# configured libc++ headers still expose the selected hardening mode. Preserve +# the configured mode so UNSUPPORTED/REQUIRES annotations remain stable. +detected_hardening_features = [ + feature for feature in config.available_features + if feature.startswith('libcpp-hardening-mode=') +] +configured_hardening_mode = '@LIBCXX_HARDENING_MODE@' +if ( + not detected_hardening_features and + configured_hardening_mode in ('none', 'fast', 'extensive', 'debug') +): + config.available_features.add(f'libcpp-hardening-mode={configured_hardening_mode}') diff --git a/libcxx/test/extensions/clang/clang_modules_include.gen.py b/libcxx/test/extensions/clang/clang_modules_include.gen.py index ed058cd908511..88aa51c4dd080 100644 --- a/libcxx/test/extensions/clang/clang_modules_include.gen.py +++ b/libcxx/test/extensions/clang/clang_modules_include.gen.py @@ -24,6 +24,9 @@ # The Android headers don't appear to be compatible with modules yet # UNSUPPORTED: LIBCXX-ANDROID-FIXME +# The OHOS headers don't appear to be compatible with modules yet +# UNSUPPORTED: LIBCXX-OHOS-FIXME + # TODO: Investigate this failure # UNSUPPORTED: LIBCXX-FREEBSD-FIXME diff --git a/libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp b/libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp index 6e59b8256ffe7..a98402b5917b6 100644 --- a/libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp +++ b/libcxx/test/libcxx/localization/locales/locale/locale.types/locale.facet/no_allocation.pass.cpp @@ -12,6 +12,7 @@ // for facets, as it uses __sso_allocator<facet*, N>. It would fail if new // facets have been added (using install()) but N hasn't been adjusted to // account for them. +// UNSUPPORTED: platform-has-unreliable-new-delete-interposition #include <cassert> diff --git a/libcxx/test/selftest/dsl/dsl.sh.py b/libcxx/test/selftest/dsl/dsl.sh.py index f93ccc747d661..fbbacb0c8d979 100644 --- a/libcxx/test/selftest/dsl/dsl.sh.py +++ b/libcxx/test/selftest/dsl/dsl.sh.py @@ -9,6 +9,11 @@ # With picolibc, test_program_stderr_is_not_conflated_with_stdout fails # because stdout & stderr are treated as the same. # XFAIL: LIBCXX-PICOLIBC-FIXME +# +# The OHOS HDC executor currently merges remote stderr into host stdout, and +# OHOS locale probing accepts some intentionally bogus locale names. +# UNSUPPORTED: executor-merges-stderr-into-stdout +# UNSUPPORTED: platform-has-nonportable-locales # Investigate why this is failing with LLVM libc. # XFAIL: LLVM-LIBC-FIXME diff --git a/libcxx/test/selftest/stdin-is-piped.sh.cpp b/libcxx/test/selftest/stdin-is-piped.sh.cpp index ffd10631c6a67..1e1b8d1bd0317 100644 --- a/libcxx/test/selftest/stdin-is-piped.sh.cpp +++ b/libcxx/test/selftest/stdin-is-piped.sh.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// // Make sure that the executor pipes standard input to the test-executable being run. +// UNSUPPORTED: executor-has-no-stdin // RUN: %{build} // RUN: echo "abc" | %{exec} %t.exe diff --git a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp index 43233decf1b34..fd6abca7c4fe1 100644 --- a/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp +++ b/libcxx/test/std/input.output/file.streams/fstreams/filebuf.members/close.pass.cpp @@ -6,6 +6,9 @@ // //===----------------------------------------------------------------------===// +// OHOS qemu-user does not match device fd ownership/signal behavior here. +// UNSUPPORTED: ohos-qemu + // <fstream> // basic_filebuf<charT,traits>* close(); diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp index a1a37012369d4..d1c2316dec112 100644 --- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.cons/path.pass.cpp @@ -8,6 +8,7 @@ // REQUIRES: can-create-symlinks // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED: executor-runs-as-root // <filesystem> diff --git a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp index ba14af1240d4b..d4e23a9a3c6b6 100644 --- a/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp +++ b/libcxx/test/std/input.output/filesystems/class.directory_entry/directory_entry.mods/assign.pass.cpp @@ -8,6 +8,7 @@ // REQUIRES: can-create-symlinks // UNSUPPORTED: c++03, c++11, c++14 +// UNSUPPORTED:... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/208390 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
