Skip to content

Commit

Permalink
[libc++] Include <__config_site> from <__config>
Browse files Browse the repository at this point in the history
Prior to this patch, we would generate a fancy <__config> header by
concatenating <__config_site> and <__config>. This complexifies the
build system and also increases the difference between what's tested
and what's actually installed.

This patch removes that complexity and instead simply installs <__config_site>
alongside the libc++ headers. <__config_site> is then included by <__config>,
which is much simpler. Doing this also opens the door to having different
<__config_site> headers depending on the target, which was impossible before.

It does change the workflow for testing header-only changes to libc++.
Previously, we would run `lit` against the headers in libcxx/include.
After this patch, we run it against a fake installation root of the
headers (containing a proper <__config_site> header). This makes use
closer to testing what we actually install, which is good, however it
does mean that we have to update that root before testing header changes.
Thus, we now need to run `ninja check-cxx-deps` before running `lit` by
hand.

Differential Revision: https://reviews.llvm.org/D97572
  • Loading branch information
ldionne authored and petrhosek committed Mar 30, 2021
1 parent 3a6365a commit c06a8f9
Show file tree
Hide file tree
Showing 11 changed files with 50 additions and 92 deletions.
8 changes: 5 additions & 3 deletions libcxx/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -403,21 +403,23 @@ endif ()
# Configure System
#===============================================================================

# TODO: Projects that depend on libc++ should use LIBCXX_GENERATED_INCLUDE_DIR
# instead of hard-coding include/c++/v1.
if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR})
set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
set(LIBCXX_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE}/c++)
if(LIBCXX_LIBDIR_SUBDIR)
string(APPEND LIBCXX_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR})
string(APPEND LIBCXX_INSTALL_LIBRARY_DIR /${LIBCXX_LIBDIR_SUBDIR})
endif()
elseif(LLVM_LIBRARY_OUTPUT_INTDIR)
set(LIBCXX_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
set(LIBCXX_HEADER_DIR ${LLVM_BINARY_DIR})
set(LIBCXX_GENERATED_INCLUDE_DIR "${LLVM_BINARY_DIR}/include/c++/v1")
set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX})
else()
set(LIBCXX_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LIBCXX_LIBDIR_SUFFIX})
set(LIBCXX_HEADER_DIR ${CMAKE_BINARY_DIR})
set(LIBCXX_GENERATED_INCLUDE_DIR "${CMAKE_BINARY_DIR}/include/c++/v1")
set(LIBCXX_INSTALL_LIBRARY_DIR lib${LIBCXX_LIBDIR_SUFFIX})
endif()

Expand Down
3 changes: 1 addition & 2 deletions libcxx/benchmarks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ set(CMAKE_FOLDER "${CMAKE_FOLDER}/Benchmarks")
set(BENCHMARK_LIBCXX_COMPILE_FLAGS
-Wno-unused-command-line-argument
-nostdinc++
-isystem ${LIBCXX_SOURCE_DIR}/include
-isystem "${LIBCXX_GENERATED_INCLUDE_DIR}"
-L${LIBCXX_LIBRARY_DIR}
-Wl,-rpath,${LIBCXX_LIBRARY_DIR}
${SANITIZER_FLAGS}
Expand All @@ -20,7 +20,6 @@ if (DEFINED LIBCXX_CXX_ABI_LIBRARY_PATH)
-L${LIBCXX_CXX_ABI_LIBRARY_PATH}
-Wl,-rpath,${LIBCXX_CXX_ABI_LIBRARY_PATH})
endif()
list(APPEND BENCHMARK_LIBCXX_COMPILE_FLAGS -include "${LIBCXX_BINARY_DIR}/__config_site")
split_list(BENCHMARK_LIBCXX_COMPILE_FLAGS)

ExternalProject_Add(google-benchmark-libcxx
Expand Down
16 changes: 8 additions & 8 deletions libcxx/cmake/Modules/HandleLibCXXABI.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ macro(setup_abi_lib abidefines abishared abistatic abifiles abidirs)
COMMENT "Copying C++ ABI header ${fpath}...")
list(APPEND abilib_headers "${dst}")

if (LIBCXX_HEADER_DIR)
set(dst "${LIBCXX_HEADER_DIR}/include/c++/v1/${dstdir}/${fpath}")
add_custom_command(OUTPUT ${dst}
DEPENDS ${src}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
COMMENT "Copying C++ ABI header ${fpath}...")
list(APPEND abilib_headers "${dst}")
endif()
# TODO: libc++ shouldn't be responsible for copying the libc++abi
# headers into the right location.
set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/include/c++/v1/${dstdir}/${fpath}")
add_custom_command(OUTPUT ${dst}
DEPENDS ${src}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
COMMENT "Copying C++ ABI header ${fpath}...")
list(APPEND abilib_headers "${dst}")

if (LIBCXX_INSTALL_HEADERS)
install(FILES "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}"
Expand Down
6 changes: 6 additions & 0 deletions libcxx/docs/TestingLibcxx.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ whether the required libraries have been built, you can use the
$ <build>/bin/llvm-lit -sv libcxx/test/std/depr/depr.c.headers/stdlib_h.pass.cpp # Run a single test
$ <build>/bin/llvm-lit -sv libcxx/test/std/atomics libcxx/test/std/threads # Test std::thread and std::atomic
In the default configuration, the tests are built against headers that form a
fake installation root of libc++. This installation root has to be updated when
changes are made to the headers, so you should re-run the `cxx-test-depends`
target before running the tests manually with `lit` when you make any sort of
change, including to the headers.

Sometimes you'll want to change the way LIT is running the tests. Custom options
can be specified using the `--param=<name>=<val>` flag. The most common option
you'll want to change is the standard dialect (ie -std=c++XX). By default the
Expand Down
79 changes: 21 additions & 58 deletions libcxx/include/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ set(files
__bits
__bsd_locale_defaults.h
__bsd_locale_fallbacks.h
__config
__debug
__errc
__functional_03
Expand Down Expand Up @@ -190,65 +191,28 @@ set(files
wctype.h
)

configure_file("__config_site.in"
"${LIBCXX_BINARY_DIR}/__config_site"
@ONLY)
configure_file("__config_site.in" "${LIBCXX_GENERATED_INCLUDE_DIR}/__config_site" @ONLY)

# Generate a custom __config header. The new header is created
# by prepending __config_site to the current __config header.
add_custom_command(OUTPUT ${LIBCXX_BINARY_DIR}/__generated_config
COMMAND ${Python3_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/utils/cat_files.py
${LIBCXX_BINARY_DIR}/__config_site
${LIBCXX_SOURCE_DIR}/include/__config
-o ${LIBCXX_BINARY_DIR}/__generated_config
DEPENDS ${LIBCXX_SOURCE_DIR}/include/__config
${LIBCXX_BINARY_DIR}/__config_site
)
# Add a target that executes the generation commands.
add_custom_target(cxx-generated-config ALL
DEPENDS ${LIBCXX_BINARY_DIR}/__generated_config)

if(LIBCXX_HEADER_DIR)
set(output_dir ${LIBCXX_HEADER_DIR}/include/c++/v1)

set(out_files)
foreach(f ${files})
set(src ${CMAKE_CURRENT_SOURCE_DIR}/${f})
set(dst ${output_dir}/${f})
add_custom_command(OUTPUT ${dst}
DEPENDS ${src}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
COMMENT "Copying CXX header ${f}")
list(APPEND out_files ${dst})
endforeach()

# Copy the generated header as __config into build directory.
set(src ${LIBCXX_BINARY_DIR}/__generated_config)
set(dst ${output_dir}/__config)
set(_all_includes "${LIBCXX_GENERATED_INCLUDE_DIR}/__config_site")
foreach(f ${files})
set(src "${CMAKE_CURRENT_SOURCE_DIR}/${f}")
set(dst "${LIBCXX_GENERATED_INCLUDE_DIR}/${f}")
add_custom_command(OUTPUT ${dst}
DEPENDS ${src} cxx-generated-config
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
COMMENT "Copying CXX __config")
list(APPEND out_files ${dst})
add_custom_target(generate-cxx-headers ALL DEPENDS ${out_files})
DEPENDS ${src}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
COMMENT "Copying CXX header ${f}")
list(APPEND _all_includes "${dst}")
endforeach()

add_library(cxx-headers INTERFACE)
add_dependencies(cxx-headers generate-cxx-headers ${LIBCXX_CXX_ABI_HEADER_TARGET})
# TODO: Use target_include_directories once we figure out why that breaks the runtimes build
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
target_compile_options(cxx-headers INTERFACE /I "${output_dir}")
else()
target_compile_options(cxx-headers INTERFACE -I "${output_dir}")
endif()
add_custom_target(generate-cxx-headers DEPENDS ${_all_includes})

# Make sure the generated __config_site header is included when we build the library.
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
target_compile_options(cxx-headers INTERFACE /FI "${LIBCXX_BINARY_DIR}/__config_site")
else()
target_compile_options(cxx-headers INTERFACE -include "${LIBCXX_BINARY_DIR}/__config_site")
endif()
add_library(cxx-headers INTERFACE)
add_dependencies(cxx-headers generate-cxx-headers ${LIBCXX_CXX_ABI_HEADER_TARGET})
# TODO: Use target_include_directories once we figure out why that breaks the runtimes build
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_SIMULATE_ID}" STREQUAL "MSVC")
target_compile_options(cxx-headers INTERFACE /I "${LIBCXX_GENERATED_INCLUDE_DIR}")
else()
add_library(cxx-headers INTERFACE)
target_compile_options(cxx-headers INTERFACE -I "${LIBCXX_GENERATED_INCLUDE_DIR}")
endif()

if (LIBCXX_INSTALL_HEADERS)
Expand All @@ -261,16 +225,15 @@ if (LIBCXX_INSTALL_HEADERS)
)
endforeach()

# Install the generated header as __config.
install(FILES ${LIBCXX_BINARY_DIR}/__generated_config
# Install the generated __config_site.
install(FILES ${LIBCXX_GENERATED_INCLUDE_DIR}/__config_site
DESTINATION ${LIBCXX_INSTALL_HEADER_PREFIX}include/c++/v1
PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ
RENAME __config
COMPONENT cxx-headers)

if (NOT CMAKE_CONFIGURATION_TYPES)
add_custom_target(install-cxx-headers
DEPENDS cxx-headers cxx-generated-config
DEPENDS cxx-headers
COMMAND "${CMAKE_COMMAND}"
-DCMAKE_INSTALL_COMPONENT=cxx-headers
-P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
Expand Down
2 changes: 2 additions & 0 deletions libcxx/include/__config
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#ifndef _LIBCPP_CONFIG
#define _LIBCPP_CONFIG

#include <__config_site>

#if defined(_MSC_VER) && !defined(__clang__)
# if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
# define _LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER
Expand Down
1 change: 1 addition & 0 deletions libcxx/test/configs/legacy.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import os
import site

config.cxx_headers = "@LIBCXX_GENERATED_INCLUDE_DIR@"
config.cxx_under_test = "@CMAKE_CXX_COMPILER@"
config.project_obj_root = "@CMAKE_BINARY_DIR@"
config.libcxx_src_root = "@LIBCXX_SOURCE_DIR@"
Expand Down
5 changes: 4 additions & 1 deletion libcxx/utils/ci/run-buildbot
Original file line number Diff line number Diff line change
Expand Up @@ -399,9 +399,12 @@ legacy-standalone)
-DCMAKE_INSTALL_PREFIX="${INSTALL_DIR}" \
-DLLVM_PATH="${MONOREPO_ROOT}/llvm" \
-DLIBCXXABI_LIBCXX_PATH="${MONOREPO_ROOT}/libcxx" \
-DLIBCXXABI_LIBCXX_INCLUDES="${MONOREPO_ROOT}/libcxx/include" \
-DLIBCXXABI_LIBCXX_INCLUDES="${BUILD_DIR}/libcxx/include/c++/v1" \
-DLIBCXXABI_LIBCXX_LIBRARY_PATH="${BUILD_DIR}/libcxx/lib"

echo "+++ Generating libc++ headers"
${NINJA} -vC "${BUILD_DIR}/libcxx" generate-cxx-headers

echo "+++ Building libc++abi"
${NINJA} -vC "${BUILD_DIR}/libcxxabi" cxxabi

Expand Down
19 changes: 2 additions & 17 deletions libcxx/utils/libcxx/test/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,6 @@ def configure_default_compile_flags(self):

def configure_compile_flags_header_includes(self):
support_path = os.path.join(self.libcxx_src_root, 'test', 'support')
self.configure_config_site_header()
if self.cxx_stdlib_under_test != 'libstdc++' and \
not self.target_info.is_windows() and \
not self.target_info.is_zos():
Expand All @@ -352,33 +351,19 @@ def configure_compile_flags_header_includes(self):
'set_windows_crt_report_mode.h')
]
cxx_headers = self.get_lit_conf('cxx_headers')
if cxx_headers == '' or (cxx_headers is None
and self.cxx_stdlib_under_test != 'libc++'):
if cxx_headers is None and self.cxx_stdlib_under_test != 'libc++':
self.lit_config.note('using the system cxx headers')
return
self.cxx.compile_flags += ['-nostdinc++']
if cxx_headers is None:
cxx_headers = os.path.join(self.libcxx_src_root, 'include')
if not os.path.isdir(cxx_headers):
self.lit_config.fatal("cxx_headers='%s' is not a directory."
% cxx_headers)
self.lit_config.fatal("cxx_headers='{}' is not a directory.".format(cxx_headers))
self.cxx.compile_flags += ['-I' + cxx_headers]
if self.libcxx_obj_root is not None:
cxxabi_headers = os.path.join(self.libcxx_obj_root, 'include',
'c++build')
if os.path.isdir(cxxabi_headers):
self.cxx.compile_flags += ['-I' + cxxabi_headers]

def configure_config_site_header(self):
# Check for a possible __config_site in the build directory. We
# use this if it exists.
if self.libcxx_obj_root is None:
return
config_site_header = os.path.join(self.libcxx_obj_root, '__config_site')
if not os.path.isfile(config_site_header):
return
self.cxx.compile_flags += ['-include', config_site_header]

def configure_link_flags(self):
# Configure library path
self.configure_link_flags_cxx_library_path()
Expand Down
1 change: 0 additions & 1 deletion libcxxabi/test/libcxxabi/test/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ def configure_compile_flags(self):
super(Configuration, self).configure_compile_flags()

def configure_compile_flags_header_includes(self):
self.configure_config_site_header()
cxx_headers = self.get_lit_conf('cxx_headers', None) or \
os.path.join(self.libcxxabi_hdr_root, 'include', 'c++', 'v1')
if cxx_headers == '':
Expand Down
2 changes: 0 additions & 2 deletions libunwind/test/libunwind/test/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ def configure_compile_flags(self):
super(Configuration, self).configure_compile_flags()

def configure_compile_flags_header_includes(self):
self.configure_config_site_header()

libunwind_headers = self.get_lit_conf(
'libunwind_headers',
os.path.join(self.libunwind_src_root, 'include'))
Expand Down

0 comments on commit c06a8f9

Please sign in to comment.