From c20c182df362f40e4c4d286c8b6039d5f6973338 Mon Sep 17 00:00:00 2001 From: Petr Hosek Date: Tue, 12 Jun 2018 03:10:02 +0000 Subject: [PATCH] Reland "Use custom command and target to install libc++ headers" Using file(COPY FILE...) has several downsides. Since the file command is only executed at configuration time, any changes to headers made after the initial CMake execution are ignored. This can lead to subtle errors since the just built Clang will be using stale libc++ headers. Furthermore, since the headers are copied prior to executing the build system, this may hide missing dependencies on libc++ from other LLVM components. This changes replaces the use of file(COPY FILE...) command with a custom command and target which addresses all aforementioned issues and matches the implementation already used by other LLVM components that also install headers like Clang builtin headers. Differential Revision: https://reviews.llvm.org/D44773 llvm-svn: 334468 --- libcxx/NOTES.TXT | 1 + libcxx/cmake/Modules/HandleLibCXXABI.cmake | 24 +- libcxx/include/CMakeLists.txt | 252 ++++++++++++++++++--- libcxx/lib/CMakeLists.txt | 6 +- 4 files changed, 243 insertions(+), 40 deletions(-) diff --git a/libcxx/NOTES.TXT b/libcxx/NOTES.TXT index f0597de64ae8..24d245d437cc 100644 --- a/libcxx/NOTES.TXT +++ b/libcxx/NOTES.TXT @@ -26,3 +26,4 @@ to libc++. 1. Add a test under `test/libcxx` that the header defines `_LIBCPP_VERSION`. 2. Update `test/libcxx/double_include.sh.cpp` to include the new header. 3. Create a submodule in `include/module.modulemap` for the new header. +4. Update the include/CMakeLists.txt file to include the new header. diff --git a/libcxx/cmake/Modules/HandleLibCXXABI.cmake b/libcxx/cmake/Modules/HandleLibCXXABI.cmake index 558e11ba2cc1..851ff9ec19ae 100644 --- a/libcxx/cmake/Modules/HandleLibCXXABI.cmake +++ b/libcxx/cmake/Modules/HandleLibCXXABI.cmake @@ -47,12 +47,22 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs) set(found TRUE) get_filename_component(dstdir ${fpath} PATH) get_filename_component(ifile ${fpath} NAME) - file(COPY "${incpath}/${fpath}" - DESTINATION "${LIBCXX_BINARY_INCLUDE_DIR}/${dstdir}" - ) - file(COPY "${incpath}/${fpath}" - DESTINATION "${CMAKE_BINARY_DIR}/include/c++/v1/${dstdir}" - ) + set(src ${incpath}/${fpath}) + + set(dst ${LIBCXX_BINARY_INCLUDE_DIR}/${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}") + + set(dst "${CMAKE_BINARY_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}" DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1/${dstdir} @@ -60,7 +70,6 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs) PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ ) endif() - list(APPEND abilib_headers "${LIBCXX_BINARY_INCLUDE_DIR}/${fpath}") endif() endforeach() if (NOT found) @@ -69,6 +78,7 @@ macro(setup_abi_lib abidefines abilib abifiles abidirs) endforeach() include_directories("${LIBCXX_BINARY_INCLUDE_DIR}") + add_custom_target(cxx-abi-headers ALL DEPENDS ${abilib_headers}) endmacro() diff --git a/libcxx/include/CMakeLists.txt b/libcxx/include/CMakeLists.txt index 4aa19eae6bf7..3aee21742566 100644 --- a/libcxx/include/CMakeLists.txt +++ b/libcxx/include/CMakeLists.txt @@ -1,5 +1,184 @@ -if (NOT LIBCXX_INSTALL_SUPPORT_HEADERS) - set(LIBCXX_SUPPORT_HEADER_PATTERN PATTERN "support" EXCLUDE) +set(files + __bit_reference + __bsd_locale_defaults.h + __bsd_locale_fallbacks.h + __debug + __functional_03 + __functional_base + __functional_base_03 + __hash_table + __libcpp_version + __locale + __mutex_base + __nullptr + __split_buffer + __sso_allocator + __std_stream + __string + __threading_support + __tree + __tuple + __undef_macros + algorithm + any + array + atomic + bitset + cassert + ccomplex + cctype + cerrno + cfenv + cfloat + chrono + cinttypes + ciso646 + climits + clocale + cmath + codecvt + compare + complex + complex.h + condition_variable + csetjmp + csignal + cstdarg + cstdbool + cstddef + cstdint + cstdio + cstdlib + cstring + ctgmath + ctime + ctype.h + cwchar + cwctype + deque + errno.h + exception + experimental/__config + experimental/__memory + experimental/algorithm + experimental/any + experimental/chrono + experimental/coroutine + experimental/deque + experimental/dynarray + experimental/filesystem + experimental/forward_list + experimental/functional + experimental/iterator + experimental/list + experimental/map + experimental/memory_resource + experimental/numeric + experimental/optional + experimental/propagate_const + experimental/ratio + experimental/regex + experimental/set + experimental/simd + experimental/string + experimental/string_view + experimental/system_error + experimental/tuple + experimental/type_traits + experimental/unordered_map + experimental/unordered_set + experimental/utility + experimental/vector + ext/__hash + ext/hash_map + ext/hash_set + float.h + forward_list + fstream + functional + future + initializer_list + inttypes.h + iomanip + ios + iosfwd + iostream + istream + iterator + limits + limits.h + list + locale + locale.h + map + math.h + memory + module.modulemap + mutex + new + numeric + optional + ostream + queue + random + ratio + regex + scoped_allocator + set + setjmp.h + shared_mutex + sstream + stack + stdbool.h + stddef.h + stdexcept + stdint.h + stdio.h + stdlib.h + streambuf + string + string.h + string_view + strstream + system_error + tgmath.h + thread + tuple + type_traits + typeindex + typeinfo + unordered_map + unordered_set + utility + valarray + variant + vector + version + wchar.h + wctype.h + ) + +if(LIBCXX_INSTALL_SUPPORT_HEADERS) + set(files + ${files} + support/android/locale_bionic.h + support/fuchsia/xlocale.h + support/ibm/limits.h + support/ibm/locale_mgmt_aix.h + support/ibm/support.h + support/ibm/xlocale.h + support/musl/xlocale.h + support/newlib/xlocale.h + support/solaris/floatingpoint.h + support/solaris/wchar.h + support/solaris/xlocale.h + support/win32/limits_msvc_win32.h + support/win32/locale_win32.h + support/xlocale/__nop_locale_mgmt.h + support/xlocale/__posix_l_fallback.h + support/xlocale/__strtonum_fallback.h + support/xlocale/xlocale.h + ) endif() if (LIBCXX_NEEDS_SITE_CONFIG) @@ -14,44 +193,56 @@ if (LIBCXX_NEEDS_SITE_CONFIG) ${LIBCXX_BINARY_DIR}/__config_site ) # Add a target that executes the generation commands. - add_custom_target(generate_config_header ALL + add_custom_target(cxx-generated-config ALL DEPENDS ${LIBCXX_BINARY_DIR}/__generated_config) - set(generated_config_deps generate_config_header) + set(generated_config_deps cxx-generated-config) +else() + set(files + ${files} + __config + ) endif() -set(LIBCXX_HEADER_PATTERN - PATTERN "*" - PATTERN "CMakeLists.txt" EXCLUDE - PATTERN ".svn" EXCLUDE - PATTERN "__config_site.in" EXCLUDE - ${LIBCXX_SUPPORT_HEADER_PATTERN} - ) - if(NOT LIBCXX_USING_INSTALLED_LLVM AND LLVM_BINARY_DIR) - file(COPY . - DESTINATION "${LLVM_BINARY_DIR}/include/c++/v1" - FILES_MATCHING - ${LIBCXX_HEADER_PATTERN} - ) + set(output_dir ${LLVM_BINARY_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() if (LIBCXX_NEEDS_SITE_CONFIG) # Copy the generated header as __config into build directory. - add_custom_command( - TARGET generate_config_header POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy - ${LIBCXX_BINARY_DIR}/__generated_config - ${LLVM_BINARY_DIR}/include/c++/v1/__config) + set(src ${LIBCXX_BINARY_DIR}/__generated_config) + set(dst ${output_dir}/__config) + add_custom_command(OUTPUT ${dst} + DEPENDS ${src} ${generated_config_deps} + COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} + COMMENT "Copying CXX __config") + list(APPEND out_files ${dst}) endif() + + add_custom_target(cxx-headers ALL DEPENDS ${out_files} ${LIBCXX_CXX_ABI_LIBRARY_HEADERS}) +else() + add_custom_target(cxx-headers) endif() +set_target_properties(cxx-headers PROPERTIES FOLDER "Misc") if (LIBCXX_INSTALL_HEADERS) - install(DIRECTORY . - DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1 - COMPONENT cxx-headers - FILES_MATCHING - ${LIBCXX_HEADER_PATTERN} - PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ - ) + foreach(file ${files}) + get_filename_component(dir ${file} DIRECTORY) + install(FILES ${file} + DESTINATION ${LIBCXX_INSTALL_PREFIX}include/c++/v1/${dir} + COMPONENT cxx-headers + PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ + ) + endforeach() if (LIBCXX_NEEDS_SITE_CONFIG) # Install the generated header as __config. @@ -63,8 +254,6 @@ if (LIBCXX_INSTALL_HEADERS) endif() if (NOT CMAKE_CONFIGURATION_TYPES) - # this target is just needed as a placeholder for the distribution target - add_custom_target(cxx-headers) add_custom_target(install-cxx-headers DEPENDS cxx-headers ${generated_config_deps} COMMAND "${CMAKE_COMMAND}" @@ -73,7 +262,6 @@ if (LIBCXX_INSTALL_HEADERS) # Stripping is a no-op for headers add_custom_target(install-cxx-headers-stripped DEPENDS install-cxx-headers) - add_custom_target(libcxx-headers) add_custom_target(install-libcxx-headers DEPENDS install-cxx-headers) add_custom_target(install-libcxx-headers-stripped DEPENDS install-cxx-headers-stripped) endif() diff --git a/libcxx/lib/CMakeLists.txt b/libcxx/lib/CMakeLists.txt index 30fdc3075070..b99f5db676d5 100644 --- a/libcxx/lib/CMakeLists.txt +++ b/libcxx/lib/CMakeLists.txt @@ -189,6 +189,9 @@ split_list(LIBCXX_LINK_FLAGS) # Add an object library that contains the compiled source files. add_library(cxx_objects OBJECT ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS}) +if(LIBCXX_CXX_ABI_LIBRARY_HEADERS) + add_dependencies(cxx_objects ${LIBCXX_CXX_ABI_LIBRARY_HEADERS}) +endif() if(WIN32 AND NOT MINGW) target_compile_definitions(cxx_objects PRIVATE @@ -283,7 +286,8 @@ if (LIBCXX_ENABLE_STATIC) endif() # Add a meta-target for both libraries. -add_custom_target(cxx DEPENDS ${LIBCXX_TARGETS} ${generated_config_deps}) +add_custom_target(cxx DEPENDS ${LIBCXX_TARGETS}) +add_dependencies(cxx cxx-headers) if (LIBCXX_ENABLE_EXPERIMENTAL_LIBRARY) file(GLOB LIBCXX_EXPERIMENTAL_SOURCES ../src/experimental/*.cpp)