diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -141,6 +141,22 @@ add_subdirectory(utils/HdrGen) endif() +set(LIBC_TARGET) +set(LIBC_COMPONENT) +set(LIBC_INSTALL_DEPENDS) +set(LIBC_INSTALL_TARGET) +if(LLVM_LIBC_FULL_BUILD) + set(LIBC_TARGET c) + set(LIBC_COMPONENT libc) + set(LIBC_INSTALL_DEPENDS "c;libc-headers") + set(LIBC_INSTALL_TARGET install-libc) +else() + set(LIBC_TARGET llvmlibc) + set(LIBC_COMPONENT llvmlibc) + set(LIBC_INSTALL_DEPENDS llvmlibc) + set(LIBC_INSTALL_TARGET install-llvmlibc) +endif() + add_subdirectory(include) add_subdirectory(config) add_subdirectory(src) @@ -168,3 +184,9 @@ if (LIBC_INCLUDE_DOCS) add_subdirectory(docs) endif() + +add_llvm_install_targets( + ${LIBC_INSTALL_TARGET} + DEPENDS ${LIBC_INSTALL_DEPENDS} + COMPONENT ${LIBC_COMPONENT} +) diff --git a/libc/cmake/modules/LLVMLibCHeaderRules.cmake b/libc/cmake/modules/LLVMLibCHeaderRules.cmake --- a/libc/cmake/modules/LLVMLibCHeaderRules.cmake +++ b/libc/cmake/modules/LLVMLibCHeaderRules.cmake @@ -35,10 +35,25 @@ if(ADD_HEADER_DEPENDS) get_fq_deps_list(fq_deps_list ${ADD_HEADER_DEPENDS}) + # Dependencies of a add_header target can only be another add_header target + # or an add_gen_header target. + foreach(dep IN LISTS fq_deps_list) + get_target_property(header_file ${dep} HEADER_FILE_PATH) + if(NOT header_file) + message(FATAL_ERROR "Invalid dependency '${dep}' for '${fq_target_name}'.") + endif() + endforeach() add_dependencies( ${fq_target_name} ${fq_deps_list} ) endif() + + set_target_properties( + ${fq_target_name} + PROPERTIES + HEADER_FILE_PATH ${dest_file} + DEPS "${fq_deps_list}" + ) endfunction(add_header) # A rule for generated header file targets. @@ -53,7 +68,7 @@ function(add_gen_header target_name) cmake_parse_arguments( "ADD_GEN_HDR" - "" # No optional arguments + "PUBLIC" # No optional arguments "DEF_FILE;GEN_HDR" # Single value arguments "PARAMS;DATA_FILES;DEPENDS" # Multi value arguments ${ARGN} @@ -108,9 +123,24 @@ if(ADD_GEN_HDR_DEPENDS) get_fq_deps_list(fq_deps_list ${ADD_GEN_HDR_DEPENDS}) + # Dependencies of a add_header target can only be another add_gen_header target + # or an add_header target. + foreach(dep IN LISTS fq_deps_list) + get_target_property(header_file ${dep} HEADER_FILE_PATH) + if(NOT header_file) + message(FATAL_ERROR "Invalid dependency '${dep}' for '${fq_target_name}'.") + endif() + endforeach() endif() add_custom_target( ${fq_target_name} DEPENDS ${out_file} ${fq_deps_list} ) + + set_target_properties( + ${fq_target_name} + PROPERTIES + HEADER_FILE_PATH ${out_file} + DEPS "${fq_deps_list}" + ) endfunction(add_gen_header) diff --git a/libc/cmake/modules/LLVMLibCRules.cmake b/libc/cmake/modules/LLVMLibCRules.cmake --- a/libc/cmake/modules/LLVMLibCRules.cmake +++ b/libc/cmake/modules/LLVMLibCRules.cmake @@ -1,6 +1,5 @@ include(LLVMLibCTargetNameUtils) include(LLVMLibCFlagRules) -include(LLVMLibCHeaderRules) include(LLVMLibCObjectRules) include(LLVMLibCLibraryRules) include(LLVMLibCTestRules) diff --git a/libc/include/CMakeLists.txt b/libc/include/CMakeLists.txt --- a/libc/include/CMakeLists.txt +++ b/libc/include/CMakeLists.txt @@ -1,3 +1,6 @@ +set(LIBC_INCLUDE_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) +include(LLVMLibCHeaderRules) + add_subdirectory(llvm-libc-macros) add_subdirectory(llvm-libc-types) @@ -217,3 +220,39 @@ DATA_FILES ../config/${LIBC_TARGET_OS}/syscall_numbers.h.inc ) + +if(NOT LLVM_LIBC_FULLBUILD) + # We don't install headers in non-fullbuild mode. + return() +endif() + +function(get_all_install_header_targets out_var) + set(all_deps ${ARGN}) + foreach(target IN LISTS ARGN) + get_target_property(deps ${target} DEPS) + if(NOT deps) + continue() + endif() + list(APPEND all_deps ${deps}) + get_all_install_header_targets(nested_deps ${deps}) + list(APPEND all_deps ${nested_deps}) + endforeach() + list(REMOVE_DUPLICATES all_deps) + set(${out_var} ${all_deps} PARENT_SCOPE) +endfunction(get_all_install_header_targets) + +get_all_install_header_targets(all_install_header_targets ${TARGET_PUBLIC_HEADERS}) +add_custom_target(libc-headers) +add_dependencies(libc-headers ${all_install_header_targets}) +foreach(target IN LISTS all_install_header_targets) + get_target_property(header_file ${target} HEADER_FILE_PATH) + if(NOT header_file) + message(FATAL_ERROR "Installable header file '${target}' does not have the " + "HEADER_FILE_PATH property set.") + endif() + file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_BINARY_DIR} ${header_file}) + get_filename_component(nested_dir ${relative_path} DIRECTORY) + install(FILES ${header_file} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${nested_dir} + COMPONENT ${LIBC_COMPONENT}) +endforeach() diff --git a/libc/lib/CMakeLists.txt b/libc/lib/CMakeLists.txt --- a/libc/lib/CMakeLists.txt +++ b/libc/lib/CMakeLists.txt @@ -1,5 +1,5 @@ add_entrypoint_library( - llvmlibc + ${LIBC_TARGET} DEPENDS ${TARGET_LLVMLIBC_ENTRYPOINTS} ) @@ -11,13 +11,7 @@ endif() install( - TARGETS llvmlibc + TARGETS ${LIBC_TARGET} ARCHIVE DESTINATION "${LIBC_INSTALL_LIBRARY_DIR}" - COMPONENT llvmlibc -) - -add_llvm_install_targets( - install-llvmlibc - DEPENDS llvmlibc - COMPONENT llvmlibc + COMPONENT ${LIBC_COMPONENT} )