diff --git a/libc/CMakeLists.txt b/libc/CMakeLists.txt --- a/libc/CMakeLists.txt +++ b/libc/CMakeLists.txt @@ -51,22 +51,60 @@ option(LLVM_LIBC_FULL_BUILD "Build and test LLVM libc as if it is the full libc" OFF) option(LLVM_LIBC_ENABLE_LINTING "Enables linting of libc source files" OFF) -if(LLVM_LIBC_ENABLE_LINTING AND (NOT LLVM_LIBC_FULL_BUILD)) - message(FATAL_ERROR "Cannot enable linting when full libc build is not enabled.") + +if(LLVM_LIBC_CLANG_TIDY) + set(LLVM_LIBC_ENABLE_LINTING ON) endif() + if(LLVM_LIBC_ENABLE_LINTING) - if("clang-tools-extra" IN_LIST LLVM_ENABLE_PROJECTS - AND "clang" IN_LIST LLVM_ENABLE_PROJECTS) - add_custom_target(lint-libc) - file(COPY ${LIBC_SOURCE_DIR}/.clang-tidy DESTINATION ${LIBC_BUILD_DIR}) + if(NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang") + set(LLVM_LIBC_ENABLE_LINTING OFF) + message(WARNING "C++ compiler is not clang++, linting with be disabled.") else() - message(FATAL_ERROR " - 'clang' and 'clang-tools-extra' are required in LLVM_ENABLE_PROJECTS to - lint llvm-libc. The linting step performs important checks to help prevent - the introduction of subtle bugs, but it may increase build times. - - To disable linting set LLVM_LIBC_ENABLE_LINTING to OFF - (pass -DLLVM_LIBC_ENABLE_LINTING=OFF to cmake).") + if (NOT LLVM_LIBC_CLANG_TIDY) + find_program(LLVM_LIBC_CLANG_TIDY NAMES clang-tidy) + endif() + + if(LLVM_LIBC_CLANG_TIDY) + # Check clang-tidy major version. + execute_process(COMMAND ${LLVM_LIBC_CLANG_TIDY} "--version" + OUTPUT_VARIABLE CLANG_TIDY_OUTPUT) + string(REGEX MATCH "[0-9]+" CLANG_TIDY_VERSION "${CLANG_TIDY_OUTPUT}") + string(REGEX MATCH "[0-9]+" CLANG_MAJOR_VERSION + "${CMAKE_CXX_COMPILER_VERSION}") + if(CLANG_TIDY_VERSION LESS CLANG_MAJOR_VERSION) + set(LLVM_LIBC_ENABLE_LINTING OFF) + message(WARNING " + 'clang-tidy' (version ${CLANG_TIDY_VERSION}) is older + than 'clang' (version ${CLANG_MAJOR_VERSION}). Linting will + be disabled. + + To set 'clang-tidy' target manually, set it to + LLVM_LIBC_CLANG_TIDY (pass DLLVM_LIBC_CLANG_TIDY= + to cmake).") + endif() + else() + if (LLVM_LIBC_FULL_BUILD + AND "clang-tools-extra" IN_LIST LLVM_ENABLE_PROJECTS + AND "clang" IN_LIST LLVM_ENABLE_PROJECTS) + add_custom_target(lint-libc) + file(COPY ${LIBC_SOURCE_DIR}/.clang-tidy DESTINATION ${LIBC_BUILD_DIR}) + else() + message(FATAL_ERROR " + Linting is enabled but 'clang-tidy' is not found! + + To set 'clang-tidy' target manually, set it to LLVM_LIBC_CLANG_TIDY + (pass DLLVM_LIBC_CLANG_TIDY= to cmake). + + Otherwise, perform a full build with LLVM_LIBC_FULL_BUILD and include + 'clang' and 'clang-tools-extra' in LLVM_ENABLE_PROJECTS. The linting + step performs important checks to help prevent the introduction of + subtle bugs but it may increase build times. + + To disable linting set LLVM_LIBC_ENABLE_LINTING to OFF + (pass -DLLVM_LIBC_ENABLE_LINTING=OFF to cmake).") + endif() + endif() endif() elseif(LLVM_LIBC_FULL_BUILD) message(WARNING " diff --git a/libc/cmake/modules/LLVMLibCObjectRules.cmake b/libc/cmake/modules/LLVMLibCObjectRules.cmake --- a/libc/cmake/modules/LLVMLibCObjectRules.cmake +++ b/libc/cmake/modules/LLVMLibCObjectRules.cmake @@ -222,6 +222,11 @@ ) if(LLVM_LIBC_ENABLE_LINTING) + if(LLVM_LIBC_CLANG_TIDY) + set(CLANG_TIDY_COMMAND ${LLVM_LIBC_CLANG_TIDY}) + else() + set(CLANG_TIDY_COMMAND $) + endif() # We only want a second invocation of clang-tidy to run # restrict-system-libc-headers if the compiler-resource-dir was set in @@ -231,7 +236,7 @@ # We run restrict-system-libc-headers with --system-headers to prevent # transitive inclusion through compler provided headers. set(restrict_system_headers_check_invocation - COMMAND $ --system-headers + COMMAND ${CLANG_TIDY_COMMAND} --system-headers --checks="-*,llvmlibc-restrict-system-libc-headers" # We explicitly set the resource dir here to match the # resource dir of the host compiler. @@ -255,7 +260,7 @@ # X warnings generated. # Until this is fixed upstream, we use -fno-caret-diagnostics to surpress # these. - COMMAND $ + COMMAND ${CLANG_TIDY_COMMAND} "--extra-arg=-fno-caret-diagnostics" --quiet # Path to directory containing compile_commands.json -p ${PROJECT_BINARY_DIR} @@ -275,10 +280,12 @@ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) - add_custom_target(${fq_target_name}.__lint__ - DEPENDS ${lint_timestamp}) - add_dependencies(lint-libc ${fq_target_name}.__lint__) - add_dependencies(${fq_target_name} ${fq_target_name}.__lint__) + if(NOT LLVM_LIBC_CLANG_TIDY) + add_custom_target(${fq_target_name}.__lint__ + DEPENDS ${lint_timestamp}) + add_dependencies(lint-libc ${fq_target_name}.__lint__) + add_dependencies(${fq_target_name} ${fq_target_name}.__lint__) + endif() endif() endfunction(add_entrypoint_object)