Skip to content

[libc][libcxx] Support for building libc++ against LLVM libc #99287

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/cmake/caches/Fuchsia-stage2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ foreach(target armv6m-unknown-eabi;armv7m-unknown-eabi;armv8m.main-unknown-eabi)
set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_LIBC "llvm-libc" CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
Expand Down Expand Up @@ -388,6 +389,7 @@ foreach(target riscv32-unknown-elf)
set(RUNTIMES_${target}_LIBCXX_CXX_ABI none CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_STATIC ON CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_LIBC "llvm-libc" CACHE STRING "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_FILESYSTEM OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_RANDOM_DEVICE OFF CACHE BOOL "")
set(RUNTIMES_${target}_LIBCXX_ENABLE_LOCALIZATION OFF CACHE BOOL "")
Expand Down
3 changes: 3 additions & 0 deletions libc/cmake/modules/CheckCompilerFeatures.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ check_cxx_compiler_flag("-nostdlib++" LIBC_CC_SUPPORTS_NOSTDLIBPP)

# clang-3.0+
check_cxx_compiler_flag("-nostdlibinc" LIBC_CC_SUPPORTS_NOSTDLIBINC)

# clang-3.0+
check_cxx_compiler_flag("-nolibc" LIBC_CC_SUPPORTS_NOLIBC)
3 changes: 3 additions & 0 deletions libc/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,9 @@ get_all_install_header_targets(all_install_header_targets ${TARGET_PUBLIC_HEADER
add_library(libc-headers INTERFACE)
add_dependencies(libc-headers ${all_install_header_targets})
target_include_directories(libc-headers SYSTEM INTERFACE ${LIBC_INCLUDE_DIR})
if(LIBC_CC_SUPPORTS_NOSTDLIBINC)
target_compile_options(libc-headers INTERFACE "-nostdlibinc")
endif()

foreach(target IN LISTS all_install_header_targets)
get_target_property(header_file ${target} HEADER_FILE_PATH)
Expand Down
5 changes: 4 additions & 1 deletion libc/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,10 @@ foreach(archive IN ZIP_LISTS
ARCHIVE_OUTPUT_NAME ${archive_0}
)
if(LLVM_LIBC_FULL_BUILD)
target_link_libraries(${archive_1} PUBLIC libc-headers)
target_link_libraries(${archive_1} INTERFACE libc-headers)
if(LIBC_CC_SUPPORTS_NOLIBC)
target_link_options(${archive_1} INTERFACE "-nolibc")
endif()
if(TARGET libc-startup)
add_dependencies(${archive_1} libc-startup)
endif()
Expand Down
14 changes: 14 additions & 0 deletions libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,15 @@ set(LIBCXX_ABI_DEFINES "" CACHE STRING "A semicolon separated list of ABI macros
set(LIBCXX_EXTRA_SITE_DEFINES "" CACHE STRING "Extra defines to add into __config_site")
option(LIBCXX_USE_COMPILER_RT "Use compiler-rt instead of libgcc" OFF)

# C Library options -----------------------------------------------------------

set(LIBCXX_DEFAULT_C_LIBRARY system)
set(LIBCXX_SUPPORTED_C_LIBRARIES system llvm-libc)
set(LIBCXX_LIBC "${LIBCXX_DEFAULT_C_LIBRARY}" CACHE STRING "Specify C library to use. Supported values are ${LIBCXX_SUPPORTED_C_LIBRARIES}.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
set(LIBCXX_DEFAULT_C_LIBRARY system)
set(LIBCXX_SUPPORTED_C_LIBRARIES system llvm-libc)
set(LIBCXX_LIBC "${LIBCXX_DEFAULT_C_LIBRARY}" CACHE STRING "Specify C library to use. Supported values are ${LIBCXX_SUPPORTED_C_LIBRARIES}.")
set(LIBCXX_SUPPORTED_C_LIBRARIES system llvm-libc)
set(LIBCXX_LIBC "system" CACHE STRING "Specify C library to use. Supported values are ${LIBCXX_SUPPORTED_C_LIBRARIES}.")

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (NOT "${LIBCXX_LIBC}" IN_LIST LIBCXX_SUPPORTED_C_LIBRARIES)
message(FATAL_ERROR "Unsupported C library: '${LIBCXX_CXX_ABI}'. Supported values are ${LIBCXX_SUPPORTED_C_LIBRARIES}.")
endif()

# ABI Library options ---------------------------------------------------------
if (MSVC)
set(LIBCXX_DEFAULT_ABI_LIBRARY "vcruntime")
Expand Down Expand Up @@ -509,6 +518,7 @@ endif()
# Setup Compiler Flags
#===============================================================================

include(HandleLibC) # Setup the C library flags
include(HandleLibCXXABI) # Setup the ABI library flags

# FIXME(EricWF): See the FIXME on LIBCXX_ENABLE_PEDANTIC.
Expand Down Expand Up @@ -784,6 +794,10 @@ config_define_if_not(LIBCXX_ENABLE_WIDE_CHARACTERS _LIBCPP_HAS_NO_WIDE_CHARACTER
config_define_if_not(LIBCXX_ENABLE_TIME_ZONE_DATABASE _LIBCPP_HAS_NO_TIME_ZONE_DATABASE)
config_define_if_not(LIBCXX_ENABLE_VENDOR_AVAILABILITY_ANNOTATIONS _LIBCPP_HAS_NO_VENDOR_AVAILABILITY_ANNOTATIONS)

if (LIBCXX_LIBC STREQUAL "llvm-libc")
config_define(ON _LIBCPP_HAS_LLVM_LIBC)
endif()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not going to block this patch on fixing this, but we don't want to add a new __config_site definition every time we add support for a new library / platform. Instead, we should provide control over the implementation of localization used by the library at the CMake level, or a similar solution to prevent the proliferation of boolean flags.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed these and will address it more correctly in a follow up PR.


if (LIBCXX_ENABLE_ASSERTIONS)
message(DEPRECATION "LIBCXX_ENABLE_ASSERTIONS is deprecated and will be removed in LLVM 20. Please use LIBCXX_HARDENING_MODE instead.")
set(LIBCXX_HARDENING_MODE "extensive")
Expand Down
34 changes: 34 additions & 0 deletions libcxx/cmake/Modules/HandleLibC.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#===============================================================================
# Define targets for linking against the selected C library
#
# After including this file, the following targets are defined:
# - libcxx-libc-headers: An interface target that allows getting access to the
# headers of the selected C library.
# - libcxx-libc-shared: A target representing the selected shared C library.
# - libcxx-libm-shared: A target representing the selected shared C math library.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it not possible to roll this up into the libc target? From the libc++ side, we'd like to have the illusion that libm is nothing but an implementation detail of libc, kind of like -latomic.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

# - libcxx-libc-static: A target representing the selected static C library.
# - libcxx-libm-static: A target representing the selected static C math library.
#===============================================================================

# Link against a system-provided libc
if (LIBCXX_LIBC STREQUAL "system")
add_library(libcxx-libc-headers INTERFACE)

add_library(libcxx-libc-static INTERFACE)
add_library(libcxx-libm-static INTERFACE)

add_library(libcxx-libc-shared INTERFACE)
add_library(libcxx-libm-shared INTERFACE)

# Link against the in-tree LLVM libc
elseif (LIBCXX_LIBC STREQUAL "llvm-libc")
add_library(libcxx-libc-headers INTERFACE)
target_link_libraries(libcxx-libc-headers INTERFACE libc-headers)

add_library(libcxx-libc-static ALIAS libc)
add_library(libcxx-libm-static ALIAS libm)

# TODO: There's no support for building LLVM libc as a shared library yet.
add_library(libcxx-libc-shared INTERFACE)
add_library(libcxx-libm-shared INTERFACE)
endif()
3 changes: 3 additions & 0 deletions libcxx/cmake/config-ix.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,9 @@ if (NOT LIBCXX_USE_COMPILER_RT)
endif()
endif()

check_cxx_compiler_flag(-nostdlibinc CXX_SUPPORTS_NOSTDLIBINC_FLAG)
check_cxx_compiler_flag(-nolibc CXX_SUPPORTS_NOLIBC_FLAG)

# libc++ is using -nostdlib++ at the link step when available,
# otherwise -nodefaultlibs is used. We want all our checks to also
# use one of these options, otherwise we may end up with an inconsistency between
Expand Down
2 changes: 1 addition & 1 deletion libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1042,7 +1042,7 @@ list(APPEND _all_includes "${LIBCXX_GENERATED_INCLUDE_DIR}/libcxx.imp")
add_custom_target(generate-cxx-headers ALL DEPENDS ${_all_includes})

add_library(cxx-headers INTERFACE)
target_link_libraries(cxx-headers INTERFACE libcxx-abi-headers)
target_link_libraries(cxx-headers INTERFACE libcxx-libc-headers libcxx-abi-headers)
add_dependencies(cxx-headers generate-cxx-headers)
# It's important that the arch directory be included first so that its header files
# which interpose on the default include dir be included instead of the default ones.
Expand Down
1 change: 1 addition & 0 deletions libcxx/include/__config_site.in
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#cmakedefine _LIBCPP_HAS_NO_THREADS
#cmakedefine _LIBCPP_HAS_NO_MONOTONIC_CLOCK
#cmakedefine _LIBCPP_HAS_MUSL_LIBC
#cmakedefine _LIBCPP_HAS_LLVM_LIBC
#cmakedefine _LIBCPP_HAS_THREAD_API_PTHREAD
#cmakedefine _LIBCPP_HAS_THREAD_API_EXTERNAL
#cmakedefine _LIBCPP_HAS_THREAD_API_WIN32
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__locale_dir/locale_base_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
# include <__locale_dir/locale_base_api/fuchsia.h>
#elif defined(__wasi__) || defined(_LIBCPP_HAS_MUSL_LIBC)
# include <__locale_dir/locale_base_api/musl.h>
#elif defined(_LIBCPP_HAS_LLVM_LIBC)
# include <__locale_dir/locale_base_api/llvm_libc.h>
#elif defined(__APPLE__) || defined(__FreeBSD__)
# include <xlocale.h>
#endif
Expand Down
17 changes: 17 additions & 0 deletions libcxx/include/__locale_dir/locale_base_api/llvm_libc.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// -*- C++ -*-
//===-----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef _LIBCPP___LOCALE_LOCALE_BASE_API_LLVM_LIBC_H
#define _LIBCPP___LOCALE_LOCALE_BASE_API_LLVM_LIBC_H

#include <__support/xlocale/__nop_locale_mgmt.h>
#include <__support/xlocale/__strtonum_fallback.h>
#include <cstdlib>

#endif // _LIBCPP___LOCALE_LOCALE_BASE_API_LLVM_LIBC_H
5 changes: 3 additions & 2 deletions libcxx/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,8 @@ if (LIBCXX_ENABLE_SHARED)
add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
target_include_directories(cxx_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(cxx_shared PUBLIC cxx-headers
PRIVATE ${LIBCXX_LIBRARIES})
PRIVATE ${LIBCXX_LIBRARIES}
PRIVATE libcxx-libc-shared libcxx-libm-shared)
set_target_properties(cxx_shared
PROPERTIES
COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
Expand Down Expand Up @@ -294,7 +295,7 @@ if (LIBCXX_ENABLE_STATIC)
target_include_directories(cxx_static PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(cxx_static PUBLIC cxx-headers
PRIVATE ${LIBCXX_LIBRARIES}
PRIVATE libcxx-abi-static)
PRIVATE libcxx-libc-static libcxx-libm-static libcxx-abi-static)
set_target_properties(cxx_static
PROPERTIES
COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
Expand Down
Loading