diff options
author | JinWang An <jinwang.an@samsung.com> | 2021-08-03 16:30:48 +0900 |
---|---|---|
committer | JinWang An <jinwang.an@samsung.com> | 2021-08-03 16:30:48 +0900 |
commit | 4cb18bd611457fa47f5ade179f97f839c5e25d79 (patch) | |
tree | b833b3f3f5038292db5ae992325e71652c08179e | |
parent | 1d650321e4565184e6f1560a229f9625a85a4daf (diff) | |
download | ccache-4cb18bd611457fa47f5ade179f97f839c5e25d79.tar.gz ccache-4cb18bd611457fa47f5ade179f97f839c5e25d79.tar.bz2 ccache-4cb18bd611457fa47f5ade179f97f839c5e25d79.zip |
Imported Upstream version 4.3upstream/4.3
37 files changed, 401 insertions, 112 deletions
diff --git a/.clang-format b/.clang-format index f40eea4..c5ffe56 100644 --- a/.clang-format +++ b/.clang-format @@ -1,8 +1,9 @@ -# This configuration should work with Clang-Format 6.0 and higher. +# This configuration should work with Clang-Format 10 and higher. --- Language: Cpp BasedOnStyle: LLVM +AllowAllConstructorInitializersOnNextLine: false AllowShortFunctionsOnASingleLine: None AlwaysBreakAfterReturnType: AllDefinitions AlwaysBreakBeforeMultilineStrings: true diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 662f491..07f2904 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -267,11 +267,11 @@ jobs: - name: Clang-Tidy os: ubuntu-18.04 - CC: clang - CXX: clang++ + CC: clang-9 + CXX: clang++-9 RUN_TESTS: none - CMAKE_PARAMS: -DENABLE_CLANG_TIDY=ON - apt_get: libzstd-dev clang-tidy + CMAKE_PARAMS: -DENABLE_CLANG_TIDY=ON -DCLANGTIDY=/usr/bin/clang-tidy-9 + apt_get: libzstd-dev clang-9 clang-tidy-9 steps: - name: Get source @@ -1,6 +1,9 @@ # Typical build directories /build*/ +# Downloaded tools +misc/.clang-format-exe + # Emacs save files *~ @@ -4,6 +4,7 @@ Anders F Björklund <anders.f.bjorklund@gmail.com> <anders@psqr.se> Andrew Boie <andrew.p.boie@intel.com> Arne Hasselbring <arne.hasselbring@googlemail.com> Bernhard Bauer <bauerb@chromium.org> <bauerb@google.com> +Bin Li <bin.li@windriver.com> Chiaki Ishikawa <ishikawa@yk.rim.or.jp> Clemens Rabe <clemens.rabe@gmail.com> <clemens.rabe@clemensrabe.de> Clemens Rabe <clemens.rabe@gmail.com> <crabe@gmx.de> diff --git a/CMakeLists.txt b/CMakeLists.txt index fc2ff66..e186e81 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -133,7 +133,10 @@ target_link_libraries(ccache PRIVATE standard_settings standard_warnings ccache_ # # Documentation # -add_subdirectory(doc) +option(ENABLE_DOCUMENTATION "Enable documentation" ON) +if(ENABLE_DOCUMENTATION) + add_subdirectory(doc) +endif() # # Installation @@ -176,26 +179,16 @@ endif() # # Special formatting targets # -find_program( - CLANG_FORMAT_EXE - NAMES "clang-format" - DOC "Path to clang-format executable.") -mark_as_advanced(CLANG_FORMAT_EXE) # Don't show in CMake UIs - -if(NOT CLANG_FORMAT_EXE) - message(STATUS "clang-format not found") -else() - add_custom_target( - format - COMMAND misc/format-files --all - COMMENT "Formatting code" - USES_TERMINAL - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - - add_custom_target( - check_format - COMMAND misc/format-files --all --check - COMMENT "Checking code formatting" - USES_TERMINAL - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) -endif() +add_custom_target( + format + COMMAND misc/format-files --all + COMMENT "Formatting code" + USES_TERMINAL + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) + +add_custom_target( + check_format + COMMAND misc/format-files --all --check + COMMENT "Checking code formatting" + USES_TERMINAL + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index cb35bc0..ad4b8aa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -56,12 +56,12 @@ little. Source code formatting is defined by `.clang-format` in the root directory. The format is loosely based on [LLVM's code formatting -style](https://llvm.org/docs/CodingStandards.html) with some exceptions. It's -highly recommended to install -[Clang-Format](https://clang.llvm.org/docs/ClangFormat.html) 6.0 or newer and -run `make format` to format changes according to ccache's code style. Or even -better: set up your editor to run Clang-Format automatically when saving. If you -don't run Clang-Format then the ccache authors have to do it for you. +style](https://llvm.org/docs/CodingStandards.html) with some exceptions. Run +`make format` (or `ninja format` if you use Ninja) to format changes according +to ccache's code style. Or even better: set up your editor to run +`<ccache-top-dir>/misc/clang-format` (or any other Clang-Format version 10 +binary) automatically when saving. Newer Clang-Format versions likely also work +fine. Please follow these conventions: diff --git a/cmake/CIBuildType.cmake b/cmake/CIBuildType.cmake index e721614..8246ecc 100644 --- a/cmake/CIBuildType.cmake +++ b/cmake/CIBuildType.cmake @@ -1,18 +1,18 @@ # Add a build type called "CI" which is like RelWithDebInfo but with assertions # enabled, i.e. without passing -DNDEBUG to the compiler. -set(CMAKE_CXX_FLAGS_CI ${CMAKE_CXX_FLAGS_RELWITHDEBINFO} CACHE STRING +set(CMAKE_CXX_FLAGS_CI "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE STRING "Flags used by the C++ compiler during CI builds." FORCE) -set(CMAKE_C_FLAGS_CI ${CMAKE_C_FLAGS_RELWITHDEBINFO} CACHE STRING +set(CMAKE_C_FLAGS_CI "${CMAKE_C_FLAGS_RELWITHDEBINFO}" CACHE STRING "Flags used by the C compiler during CI builds." FORCE) set(CMAKE_EXE_LINKER_FLAGS_CI - ${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO} CACHE STRING + "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}" CACHE STRING "Flags used for linking binaries during CI builds." FORCE) set(CMAKE_SHARED_LINKER_FLAGS_CI - ${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO} CACHE STRING + "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}" CACHE STRING "Flags used by the shared libraries linker during CI builds." FORCE) mark_as_advanced( @@ -25,7 +25,7 @@ set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE}" CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel CI." FORCE) -string(REGEX REPLACE "[/-]DNDEBUG" "" CMAKE_CXX_FLAGS_CI ${CMAKE_CXX_FLAGS_CI}) -string(REGEX REPLACE "[/-]DNDEBUG" "" CMAKE_C_FLAGS_CI ${CMAKE_C_FLAGS_CI}) -string(STRIP ${CMAKE_CXX_FLAGS_CI} CMAKE_CXX_FLAGS_CI) -string(STRIP ${CMAKE_C_FLAGS_CI} CMAKE_C_FLAGS_CI) +string(REGEX REPLACE "[/-]DNDEBUG" "" CMAKE_CXX_FLAGS_CI "${CMAKE_CXX_FLAGS_CI}") +string(REGEX REPLACE "[/-]DNDEBUG" "" CMAKE_C_FLAGS_CI "${CMAKE_C_FLAGS_CI}") +string(STRIP "${CMAKE_CXX_FLAGS_CI}" CMAKE_CXX_FLAGS_CI) +string(STRIP "${CMAKE_C_FLAGS_CI}" CMAKE_C_FLAGS_CI) diff --git a/cmake/CcacheVersion.cmake b/cmake/CcacheVersion.cmake index 2568fd5..c0cbd91 100644 --- a/cmake/CcacheVersion.cmake +++ b/cmake/CcacheVersion.cmake @@ -22,7 +22,7 @@ # CCACHE_VERSION_ORIGIN is set to "archive" in scenario 1 and "git" in scenario # 3. -set(version_info "1a07c09dcbba202572c5ab1bc4b736183a318aa7 HEAD, tag: v4.2.1, origin/master, origin/HEAD, master") +set(version_info "2c13bce2609a02b70c92e84cdd177a6072f44d5e HEAD, tag: v4.3, origin/master, origin/HEAD, master") if(version_info MATCHES "^([0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f])[0-9a-f]* (.*)") # Scenario 1. diff --git a/cmake/GenerateConfigurationFile.cmake b/cmake/GenerateConfigurationFile.cmake index 6e6b604..a460529 100644 --- a/cmake/GenerateConfigurationFile.cmake +++ b/cmake/GenerateConfigurationFile.cmake @@ -44,7 +44,7 @@ foreach(func IN ITEMS ${functions}) endforeach() include(CheckCSourceCompiles) -set(CMAKE_REQUIRED_LINK_OPTIONS -pthread) +set(CMAKE_REQUIRED_FLAGS -pthread) check_c_source_compiles( [=[ #include <pthread.h> @@ -57,7 +57,7 @@ check_c_source_compiles( ]=] HAVE_PTHREAD_MUTEX_ROBUST) check_function_exists(pthread_mutexattr_setpshared HAVE_PTHREAD_MUTEXATTR_SETPSHARED) -set(CMAKE_REQUIRED_LINK_OPTIONS) +set(CMAKE_REQUIRED_FLAGS) include(CheckStructHasMember) check_struct_has_member("struct stat" st_ctim sys/stat.h diff --git a/doc/AUTHORS.adoc b/doc/AUTHORS.adoc index ce44c8c..2a8363a 100644 --- a/doc/AUTHORS.adoc +++ b/doc/AUTHORS.adoc @@ -22,6 +22,7 @@ Ccache is a collective work with contributions from many people, including: * Arne Hasselbring * Azat Khuzhin * Bernhard Bauer +* Bin Li * Björn Jacke * Breno Guimaraes * Chiaki Ishikawa @@ -58,6 +59,7 @@ Ccache is a collective work with contributions from many people, including: * Jon Petrissans * Jørgen P. Tjernø * Josh Soref +* Josh Triplett * Justin Lebar * Ka Ho Ng * Karl Chen @@ -106,6 +108,8 @@ Ccache is a collective work with contributions from many people, including: * Pawel Krysiak * Per Nordlöw * Peter Budai +* Peter Steinberger +* Petr Štetiar * Philippe Proulx * Philipp Storz * Rafael Kitover diff --git a/doc/MANUAL.adoc b/doc/MANUAL.adoc index 2b6f001..25c34c0 100644 --- a/doc/MANUAL.adoc +++ b/doc/MANUAL.adoc @@ -824,6 +824,10 @@ still has to do _some_ preprocessing (like macros). mtime is too new. This sloppiness disables that check. See also _<<_handling_of_newly_created_header_files,Handling of newly created header files>>_. +*ivfsoverlay*:: + Ignore the Clang compiler option *-ivfsoverlay* and its argument. This is + useful if you use Xcode, which uses a virtual file system (VFS) for things + like combining Objective-C and Swift code. *locale*:: Ccache includes the environment variables *LANG*, *LC_ALL*, *LC_CTYPE* and *LC_MESSAGES* in the hash by default since they may affect localization of diff --git a/doc/NEWS.adoc b/doc/NEWS.adoc index 040a68e..7d69bd4 100644 --- a/doc/NEWS.adoc +++ b/doc/NEWS.adoc @@ -1,6 +1,55 @@ Ccache news =========== +Ccache 4.3 +---------- +Release date: 2021-05-09 + +New features +~~~~~~~~~~~~ + +- Ccache now ignores the Clang compiler option `-ivfsoverlay` and its argument + if you opt in to ``ivfsoverlay sloppiness''. This is useful if you use Xcode, + which uses a virtual file system (VFS) for things like combining Objective-C + and Swift code. + +- When using `-P` in combination with `-E`, ccache now reports this as ``called + for preprocessing'' instead of ``unsupported compiler option''. + +- Added support for `-specs file.specs` and `--specs file.specs` without an + equal sign between the arguments. + + +Bug fixes +~~~~~~~~~ + +- "Split dwarf" code paths are now disabled when outputting to `/dev/null`. This + avoids an attempt to delete `/dev/null.dwo`. + +- Made the `stat`/`lstat` wrapper function for Windows treat pending deletes as + missing files. + +- Fixed a bug that made ccache process header files redundantly for some + relative headers when using Clang. + +- The object path in now included in the input hash when using `-fprofile-arcs` + (or `--coverage`) since the object file embeds a `.gcda` path based on the + object file path. + + +Build improvements +~~~~~~~~~~~~~~~~~~ + +- Added an `ENABLE_DOCUMENTATION` build option (default: true) that can be used + to disable the build of documentation. + +- Fixed detection of pthread features. + +- Quote CMake variables expansions to avoid errors when + `${CMAKE_C_FLAGS_RELWITHDEBINFO}` or `${CMAKE_CXX_FLAGS_RELWITHDEBINFO}` + expands to the empty string. + + Ccache 4.2.1 ------------ Release date: 2021-03-27 @@ -8,9 +57,9 @@ Release date: 2021-03-27 Bug fixes ~~~~~~~~~ -- Ccache now only `dup2`s stderr into `$UNCACHED_ERR_FD` for calls to the - preprocessor/compiler. This works around a complex bug in interaction with GNU - Make, LTO linking and the Linux PTY driver. +- Ccache now only duplicates the stderr file descriptor into `$UNCACHED_ERR_FD` + for calls to the preprocessor/compiler. This works around a complex bug in + interaction with GNU Make, LTO linking and the Linux PTY driver. - Fixed detection of color diagnostics usage when using `-Xclang -fcolor-diagnostics` options. diff --git a/misc/clang-format b/misc/clang-format new file mode 100755 index 0000000..b198be2 --- /dev/null +++ b/misc/clang-format @@ -0,0 +1,65 @@ +#!/bin/sh +# +# This script executes clang-format in the following order: +# +# 1. If environment variable CLANG_FORMAT is set, execute $CLANG_FORMAT. +# 2. Otherwise, if <ccache-top-dir>/misc/.clang-format-exe exists, execute that +# program. +# 3. Otherwise, download a statically linked clang-format executable, verify its +# integrity, place it in <ccache-top-dir>/misc/.clang-format-exe and execute +# it. + +set -eu + +if [ -n "${CLANG_FORMAT:-}" ]; then + exec "$CLANG_FORMAT" "$@" +fi + +top_dir="$(dirname "$0")" +clang_format_exe="$top_dir/.clang-format-exe" +clang_format_version=10 +url_prefix="https://github.com/muttleyxd/clang-tools-static-binaries/releases/download/master-22538c65/clang-format-${clang_format_version}_" + +if [ ! -x "$clang_format_exe" ]; then + case "$(uname -s | tr '[:upper:]' '[:lower:]')" in + *mingw*|*cygwin*|*msys*) + url_suffix=windows-amd64.exe + checksum=0b21dfb9041437eebcc44032096e4dfba9ee7b668ee6867ada71ea3541f7b09657ea592a5b1cf659bc9f8072bdc477dfc9da07b3edacb7834b70e68d7a3fc887 + ;; + *darwin*) + url_suffix=macosx-amd64 + checksum=8458753e13d3cbb7949a302beab812bed6d9dd9001c6e9618e5ba2e438233633ae04704a4e150aa2abfbaf103f1df4bc4a77b306012f44b37e543964bd527951 + ;; + *linux*) + url_suffix=linux-amd64 + checksum=3c4aaa90ad83313a1d7b350b30f9ad62578be73241f00f7d6e92838289e0b734fab80dee9dfcbd1546135bdb4e3601cfb2cf6b47360fba0bfc961e5a7cab2015 + ;; + *) + echo "Error: Please set CLANG_FORMAT to clang-format version $clang_format_version" >&2 + exit 1 + ;; + esac + + url="$url_prefix$url_suffix" + + if command -v wget >/dev/null; then + wget -qO "$clang_format_exe.tmp" "$url" + elif command -v curl >/dev/null; then + curl -so "$clang_format_exe.tmp" -L --retry 20 "$url" + else + echo "Error: Neither wget nor curl found" >&2 + exit 1 + fi + + if ! command -v sha512sum >/dev/null; then + echo "Warning: sha512sum not found, not verifying clang-format integrity" >&2 + elif ! echo "$checksum $clang_format_exe.tmp" | sha512sum --status -c; then + echo "Error: Bad checksum of downloaded clang-format" >&2 + exit 1 + fi + + chmod +x "$clang_format_exe.tmp" + mv "$clang_format_exe.tmp" "$clang_format_exe" +fi + +exec "$clang_format_exe" "$@" diff --git a/misc/format-files b/misc/format-files index 111705a..44340b9 100755 --- a/misc/format-files +++ b/misc/format-files @@ -27,7 +27,7 @@ if [ -n "$all" ]; then exec sh "$0" $check $(git ls-files '*.[ch]' '*.[ch]pp' ':!:src/third_party') fi -clang_format=${CLANG_FORMAT:-clang-format} +clang_format="$(dirname "$0")/clang-format" [ -t 1 ] && cf_color="--color=always" || cf_color="" if [ -n "${VERBOSE:-}" ]; then diff --git a/src/Args.hpp b/src/Args.hpp index ae42809..48fb77d 100644 --- a/src/Args.hpp +++ b/src/Args.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Joel Rosdahl and other contributors +// Copyright (C) 2020-2021 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -115,18 +115,14 @@ Args::size() const return m_args.size(); } -// clang-format off inline const std::string& Args::operator[](size_t i) const -// clang-format on { return m_args[i]; } -// clang-format off inline std::string& Args::operator[](size_t i) -// clang-format on { return m_args[i]; } diff --git a/src/CacheEntryWriter.cpp b/src/CacheEntryWriter.cpp index 8f45adf..b936947 100644 --- a/src/CacheEntryWriter.cpp +++ b/src/CacheEntryWriter.cpp @@ -26,10 +26,9 @@ CacheEntryWriter::CacheEntryWriter(FILE* stream, uint64_t payload_size) // clang-format off : m_compressor( - Compressor::create_from_type(compression_type, stream, compression_level) - ) + Compressor::create_from_type(compression_type, stream, compression_level)) +// clang-format on { - // clang-format on uint8_t header_bytes[15]; memcpy(header_bytes, magic, 4); header_bytes[4] = version; diff --git a/src/Config.cpp b/src/Config.cpp index 68dc3f5..9e70923 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -275,6 +275,8 @@ parse_sloppiness(const std::string& value) result |= SLOPPY_LOCALE; } else if (token == "modules") { result |= SLOPPY_MODULES; + } else if (token == "ivfsoverlay") { + result |= SLOPPY_IVFSOVERLAY; } // else: ignore unknown value for forward compatibility start = value.find_first_not_of(", ", end); } @@ -315,6 +317,9 @@ format_sloppiness(uint32_t sloppiness) if (sloppiness & SLOPPY_MODULES) { result += "modules, "; } + if (sloppiness & SLOPPY_IVFSOVERLAY) { + result += "ivfsoverlay, "; + } if (!result.empty()) { // Strip last ", ". result.resize(result.size() - 2); @@ -1,4 +1,4 @@ -// Copyright (C) 2020 Joel Rosdahl and other contributors +// Copyright (C) 2020-2021 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -72,10 +72,8 @@ Fd::get() const return m_fd; } -// clang-format off inline int Fd::operator*() const -// clang-format on { ASSERT(m_fd != -1); return m_fd; diff --git a/src/File.hpp b/src/File.hpp index 6f0dd21..f8f6c0b 100644 --- a/src/File.hpp +++ b/src/File.hpp @@ -1,4 +1,4 @@ -// Copyright (C) 2019-2020 Joel Rosdahl and other contributors +// Copyright (C) 2019-2021 Joel Rosdahl and other contributors // // See doc/AUTHORS.adoc for a complete list of contributors. // @@ -89,10 +89,8 @@ inline File::operator bool() const return m_file; } -// clang-format off inline FILE* File::operator*() const -// clang-format on { return m_file; } diff --git a/src/MiniTrace.cpp b/src/MiniTrace.cpp index bf17397..0516562 100644 --- a/src/MiniTrace.cpp +++ b/src/MiniTrace.cpp @@ -65,7 +65,8 @@ time_seconds() } // namespace MiniTrace::MiniTrace(const ArgsInfo& args_info) - : m_args_info(args_info), m_trace_id(reinterpret_cast<void*>(getpid())) + : m_args_info(args_info), + m_trace_id(reinterpret_cast<void*>(getpid())) { TemporaryFile tmp_file(get_system_tmp_dir() + "/ccache-trace"); m_tmp_trace_file = tmp_file.path; diff --git a/src/Result.cpp b/src/Result.cpp index b20aa62..8408d2a 100644 --- a/src/Result.cpp +++ b/src/Result.cpp @@ -300,7 +300,8 @@ Reader::read_entry(CacheEntryReader& cache_entry_reader, } Writer::Writer(Context& ctx, const std::string& result_path) - : m_ctx(ctx), m_result_path(result_path) + : m_ctx(ctx), + m_result_path(result_path) { } diff --git a/src/ResultRetriever.cpp b/src/ResultRetriever.cpp index 957bbee..0218877 100644 --- a/src/ResultRetriever.cpp +++ b/src/ResultRetriever.cpp @@ -25,7 +25,8 @@ using Result::FileType; ResultRetriever::ResultRetriever(Context& ctx, bool rewrite_dependency_target) - : m_ctx(ctx), m_rewrite_dependency_target(rewrite_dependency_target) + : m_ctx(ctx), + m_rewrite_dependency_target(rewrite_dependency_target) { } diff --git a/src/Sloppiness.hpp b/src/Sloppiness.hpp index bd2078e..62c0508 100644 --- a/src/Sloppiness.hpp +++ b/src/Sloppiness.hpp @@ -38,4 +38,6 @@ enum Sloppiness { SLOPPY_LOCALE = 1 << 8, // Allow caching even if -fmodules is used. SLOPPY_MODULES = 1 << 9, + // Ignore virtual file system (VFS) overlay file. + SLOPPY_IVFSOVERLAY = 1 << 10, }; diff --git a/src/Stat.cpp b/src/Stat.cpp index d491682..244fd6f 100644 --- a/src/Stat.cpp +++ b/src/Stat.cpp @@ -19,6 +19,8 @@ #include "Stat.hpp" #ifdef _WIN32 +# include "Win32Util.hpp" + # include "third_party/win32/winerror_to_errno.h" #endif @@ -124,6 +126,11 @@ win32_stat_impl(const char* path, bool traverse_links, Stat::stat_t* st) } if (handle == INVALID_HANDLE_VALUE) { + if (GetLastError() == ERROR_ACCESS_DENIED + && Win32Util::get_last_ntstatus() == STATUS_DELETE_PENDING) { + // Treat a 'pending delete' as a nonexistent file. + SetLastError(ERROR_FILE_NOT_FOUND); + } return false; } diff --git a/src/Win32Util.cpp b/src/Win32Util.cpp index b259ed0..1a9de6a 100644 --- a/src/Win32Util.cpp +++ b/src/Win32Util.cpp @@ -23,6 +23,26 @@ #include <chrono> #include <thread> +namespace { + +template<typename Proc> +Proc* +get_proc_address(HMODULE module, const char* proc_name) +{ +#if defined __GNUC__ +# pragma GCC diagnostic push +# if __GNUC__ >= 8 +# pragma GCC diagnostic ignored "-Wcast-function-type" +# endif +#endif + return reinterpret_cast<Proc*>(GetProcAddress(module, proc_name)); +#if defined __GNUC__ +# pragma GCC diagnostic pop +#endif +} + +} // namespace + namespace Win32Util { std::string @@ -97,6 +117,14 @@ argv_to_string(const char* const* argv, return result; } +NTSTATUS +get_last_ntstatus() +{ + static auto* get_last_ntstatus_fn = get_proc_address<NTSTATUS NTAPI()>( + GetModuleHandleA("ntdll.dll"), "RtlGetLastNtStatus"); + return get_last_ntstatus_fn(); +} + } // namespace Win32Util // From: https://stackoverflow.com/a/58162122/262458 diff --git a/src/Win32Util.hpp b/src/Win32Util.hpp index d6fc575..0a2f1a1 100644 --- a/src/Win32Util.hpp +++ b/src/Win32Util.hpp @@ -39,4 +39,8 @@ std::string argv_to_string(const char* const* argv, // Return the error message corresponding to `error_code`. std::string error_message(DWORD error_code); +// Returns the last NTSTATUS code. (These can be more specific than the +// corresponding Win32 error code.) +NTSTATUS get_last_ntstatus(); + } // namespace Win32Util diff --git a/src/ZstdCompressor.cpp b/src/ZstdCompressor.cpp index a53cfa2..39f6bb2 100644 --- a/src/ZstdCompressor.cpp +++ b/src/ZstdCompressor.cpp @@ -25,7 +25,8 @@ #include <algorithm> ZstdCompressor::ZstdCompressor(FILE* stream, int8_t compression_level) - : m_stream(stream), m_zstd_stream(ZSTD_createCStream()) + : m_stream(stream), + m_zstd_stream(ZSTD_createCStream()) { if (compression_level == 0) { compression_level = default_compression_level; diff --git a/src/argprocessing.cpp b/src/argprocessing.cpp index e39c4e5..92b929e 100644 --- a/src/argprocessing.cpp +++ b/src/argprocessing.cpp @@ -232,6 +232,15 @@ process_arg(Context& ctx, return nullopt; } + // Ignore clang -ivfsoverlay <arg> to not detect multiple input files. + if (args[i] == "-ivfsoverlay" + && !(config.sloppiness() & SLOPPY_IVFSOVERLAY)) { + LOG_RAW( + "You have to specify \"ivfsoverlay\" sloppiness when using" + " -ivfsoverlay to get hits"); + return Statistic::unsupported_compiler_option; + } + // Special case for -E. if (args[i] == "-E") { return Statistic::called_for_preprocessing; @@ -618,13 +627,19 @@ process_arg(Context& ctx, return nullopt; } + if (args[i] == "-P" || args[i] == "-Wp,-P") { + // Avoid passing -P to the preprocessor since it removes preprocessor + // information we need. + state.compiler_only_args.push_back(args[i]); + LOG("{} used; not compiling preprocessed code", args[i]); + config.set_run_second_cpp(true); + return nullopt; + } + if (Util::starts_with(args[i], "-Wp,")) { - if (args[i] == "-Wp,-P" || args[i].find(",-P,") != std::string::npos + if (args[i].find(",-P,") != std::string::npos || Util::ends_with(args[i], ",-P")) { - // -P removes preprocessor information in such a way that the object file - // from compiling the preprocessed file will not be equal to the object - // file produced when compiling without ccache. - LOG_RAW("Too hard option -Wp,-P detected"); + // -P together with other preprocessor options is just too hard. return Statistic::unsupported_compiler_option; } else if (Util::starts_with(args[i], "-Wp,-MD,") && args[i].find(',', 8) == std::string::npos) { @@ -1107,7 +1122,14 @@ process_args(Context& ctx) } if (args_info.seen_split_dwarf) { - args_info.output_dwo = Util::change_extension(args_info.output_obj, ".dwo"); + if (args_info.output_obj == "/dev/null") { + // Outputting to /dev/null -> compiler won't write a .dwo, so just pretend + // we haven't seen the -gsplit-dwarf option. + args_info.seen_split_dwarf = false; + } else { + args_info.output_dwo = + Util::change_extension(args_info.output_obj, ".dwo"); + } } // Cope with -o /dev/null. diff --git a/src/ccache.cpp b/src/ccache.cpp index 7d39e5b..761b9ab 100644 --- a/src/ccache.cpp +++ b/src/ccache.cpp @@ -205,7 +205,8 @@ private: }; inline Failure::Failure(Statistic statistic, nonstd::optional<int> exit_code) - : m_statistic(statistic), m_exit_code(exit_code) + : m_statistic(statistic), + m_exit_code(exit_code) { } @@ -398,16 +399,16 @@ do_remember_include_file(Context& ctx, return true; } - if (ctx.included_files.find(path) != ctx.included_files.end()) { - // Already known include file. - return true; - } - // Canonicalize path for comparison; Clang uses ./header.h. if (Util::starts_with(path, "./")) { path.erase(0, 2); } + if (ctx.included_files.find(path) != ctx.included_files.end()) { + // Already known include file. + return true; + } + #ifdef _WIN32 { // stat fails on directories on win32. @@ -1425,14 +1426,17 @@ hash_common_info(const Context& ctx, if ((!should_rewrite_dependency_target(ctx.args_info) && ctx.args_info.generating_dependencies) - || ctx.args_info.seen_split_dwarf) { - // The output object file name is part of the .d file, so include the path - // in the hash if generating dependencies. + || ctx.args_info.seen_split_dwarf || ctx.args_info.profile_arcs) { + // If generating dependencies: The output object file name is part of the .d + // file, so include the path in the hash. // - // Object files include a link to the corresponding .dwo file based on the - // target object filename when using -gsplit-dwarf, so hashing the object - // file path will do it, although just hashing the object file base name - // would be enough. + // When using -gsplit-dwarf: Object files include a link to the + // corresponding .dwo file based on the target object filename, so hashing + // the object file path will do it, although just hashing the object file + // base name would be enough. + // + // When using -fprofile-arcs (including implicitly via --coverage): the + // object file contains a .gcda path based on the object file path. hash.hash_delimiter("object file"); hash.hash(ctx.args_info.output_obj); } @@ -1652,8 +1656,20 @@ calculate_result_name(Context& ctx, } if (Util::starts_with(args[i], "-specs=") - || Util::starts_with(args[i], "--specs=")) { - std::string path = args[i].substr(args[i].find('=') + 1); + || Util::starts_with(args[i], "--specs=") + || (args[i] == "-specs" || args[i] == "--specs")) { + std::string path; + size_t eq_pos = args[i].find('='); + if (eq_pos == std::string::npos) { + if (i + 1 >= args.size()) { + LOG("missing argument for \"{}\"", args[i]); + throw Failure(Statistic::bad_compiler_arguments); + } + path = args[i + 1]; + i++; + } else { + path = args[i].substr(eq_pos + 1); + } auto st = Stat::stat(path, Stat::OnError::log); if (st) { // If given an explicit specs file, then hash that file, but don't diff --git a/src/compopt.cpp b/src/compopt.cpp index d69f74a..3ed4f5b 100644 --- a/src/compopt.cpp +++ b/src/compopt.cpp @@ -62,6 +62,7 @@ const CompOpt compopts[] = { {"--save-temps=cwd", TOO_HARD}, {"--save-temps=obj", TOO_HARD}, {"--serialize-diagnostics", TAKES_ARG | TAKES_PATH}, + {"--specs", TAKES_ARG}, {"-A", TAKES_ARG}, {"-B", TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-D", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG}, @@ -76,7 +77,6 @@ const CompOpt compopts[] = { {"-MM", TOO_HARD}, {"-MQ", TAKES_ARG}, {"-MT", TAKES_ARG}, - {"-P", TOO_HARD}, {"-U", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG}, {"-V", TAKES_ARG}, {"-Wa,", TAKES_CONCAT_ARG | AFFECTS_COMP}, @@ -116,6 +116,7 @@ const CompOpt compopts[] = { {"-iquote", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-isysroot", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-isystem", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, + {"-ivfsoverlay", TAKES_ARG}, {"-iwithprefix", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, {"-iwithprefixbefore", AFFECTS_CPP | TAKES_ARG | TAKES_CONCAT_ARG | TAKES_PATH}, @@ -132,6 +133,7 @@ const CompOpt compopts[] = { {"-save-temps", TOO_HARD}, {"-save-temps=cwd", TOO_HARD}, {"-save-temps=obj", TOO_HARD}, + {"-specs", TAKES_ARG}, {"-stdlib=", AFFECTS_CPP | TAKES_CONCAT_ARG}, {"-trigraphs", AFFECTS_CPP}, {"-u", TAKES_ARG | TAKES_CONCAT_ARG}, diff --git a/src/system.hpp b/src/system.hpp index 6115c5b..fa4bbf3 100644 --- a/src/system.hpp +++ b/src/system.hpp @@ -158,7 +158,10 @@ const mode_t S_IWUSR = mode_t(_S_IWRITE); # include <io.h> # include <process.h> # define NOMINMAX 1 +# define WIN32_NO_STATUS # include <windows.h> +# undef WIN32_NO_STATUS +# include <ntstatus.h> # define mkdir(a, b) _mkdir(a) # define execv(a, b) \ do_not_call_execv_on_windows // to protect against incidental use of MinGW diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index c33befd..ae0df8e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -47,6 +47,7 @@ addtest(fileclone) addtest(hardlink) addtest(inode_cache) addtest(input_charset) +addtest(ivfsoverlay) addtest(masquerading) addtest(modules) addtest(multi_arch) diff --git a/test/suites/base.bash b/test/suites/base.bash index 9629a06..37b7755 100644 --- a/test/suites/base.bash +++ b/test/suites/base.bash @@ -1224,43 +1224,59 @@ EOF expect_stat 'files in cache' 0 # ------------------------------------------------------------------------- - TEST "-P" + TEST "-P -c" - # Check that -P disables ccache. (-P removes preprocessor information in - # such a way that the object file from compiling the preprocessed file will - # not be equal to the object file produced when compiling without ccache.) + $CCACHE_COMPILE -P -c test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 0 + expect_stat 'cache miss' 1 - $CCACHE_COMPILE -c -P test1.c + $CCACHE_COMPILE -P -c test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "-P -E" + + $CCACHE_COMPILE -P -E test1.c expect_stat 'cache hit (direct)' 0 expect_stat 'cache hit (preprocessed)' 0 expect_stat 'cache miss' 0 - expect_stat 'unsupported compiler option' 1 + expect_stat 'called for preprocessing' 1 # ------------------------------------------------------------------------- TEST "-Wp,-P" - # Check that -Wp,-P disables ccache. (-P removes preprocessor information - # in such a way that the object file from compiling the preprocessed file - # will not be equal to the object file produced when compiling without - # ccache.) - $CCACHE_COMPILE -c -Wp,-P test1.c expect_stat 'cache hit (direct)' 0 expect_stat 'cache hit (preprocessed)' 0 - expect_stat 'cache miss' 0 - expect_stat 'unsupported compiler option' 1 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -c -Wp,-P test1.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache hit (preprocessed)' 1 + expect_stat 'cache miss' 1 + + # ------------------------------------------------------------------------- + TEST "-Wp,-P,-DFOO" + + # Check that -P disables ccache when used in combination with other -Wp, + # options. (-P removes preprocessor information in such a way that the + # object file from compiling the preprocessed file will not be equal to the + # object file produced when compiling without ccache.) $CCACHE_COMPILE -c -Wp,-P,-DFOO test1.c expect_stat 'cache hit (direct)' 0 expect_stat 'cache hit (preprocessed)' 0 expect_stat 'cache miss' 0 - expect_stat 'unsupported compiler option' 2 + expect_stat 'unsupported compiler option' 1 $CCACHE_COMPILE -c -Wp,-DFOO,-P test1.c expect_stat 'cache hit (direct)' 0 expect_stat 'cache hit (preprocessed)' 0 expect_stat 'cache miss' 0 - expect_stat 'unsupported compiler option' 3 + expect_stat 'unsupported compiler option' 2 # ------------------------------------------------------------------------- TEST "-Wp,-D" diff --git a/test/suites/ivfsoverlay.bash b/test/suites/ivfsoverlay.bash new file mode 100644 index 0000000..ca88221 --- /dev/null +++ b/test/suites/ivfsoverlay.bash @@ -0,0 +1,44 @@ +SUITE_ivfsoverlay_PROBE() { + if ! $COMPILER_TYPE_CLANG; then + echo "-ivfsoverlay not supported by compiler" + else + touch test.c + cat <<EOF >test.yaml +{"case-sensitive":"false","roots":[],"version":0} +EOF + $COMPILER -ivfsoverlay test.yaml test.c -S || echo "compiler does not support -ivfsoverlay" + fi +} + +SUITE_ivfsoverlay_SETUP() { + unset CCACHE_NODIRECT + + cat <<EOF >test.yaml +{"case-sensitive":"false","roots":[],"version":0} +EOF + cat <<EOF >test.c +// test.c +int test; +EOF +} + +SUITE_ivfsoverlay() { + # ------------------------------------------------------------------------- + TEST "without sloppy ivfsoverlay" + + $CCACHE_COMPILE -ivfsoverlay test.yaml -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache miss' 0 + expect_stat 'unsupported compiler option' 1 + + # ------------------------------------------------------------------------- + TEST "with sloppy ivfsoverlay" + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS ivfsoverlay" $CCACHE_COMPILE -ivfsoverlay test.yaml -c test.c + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache miss' 1 + + CCACHE_SLOPPINESS="$DEFAULT_SLOPPINESS ivfsoverlay" $CCACHE_COMPILE -ivfsoverlay test.yaml -c test.c + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache miss' 1 +} diff --git a/test/suites/profiling.bash b/test/suites/profiling.bash index b7abaa2..dbe36d4 100644 --- a/test/suites/profiling.bash +++ b/test/suites/profiling.bash @@ -128,6 +128,29 @@ SUITE_profiling() { rm "$gcno_name" done done + + # ------------------------------------------------------------------------- + TEST "-fprofile-arcs for different object file paths" + + mkdir obj1 obj2 + + $CCACHE_COMPILE -fprofile-arcs -c test.c -o obj1/test.o + expect_stat 'cache hit (direct)' 0 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -fprofile-arcs -c test.c -o obj1/test.o + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache miss' 1 + + $CCACHE_COMPILE -fprofile-arcs -c test.c -o obj2/test.o + expect_different_content obj1/test.o obj2/test.o # different paths to .gcda file + expect_stat 'cache hit (direct)' 1 + expect_stat 'cache miss' 2 + + $CCACHE_COMPILE -fprofile-arcs -c test.c -o obj2/test.o + expect_different_content obj1/test.o obj2/test.o # different paths to .gcda file + expect_stat 'cache hit (direct)' 2 + expect_stat 'cache miss' 2 } merge_profiling_data() { diff --git a/unittest/test_Config.cpp b/unittest/test_Config.cpp index fad4ff4..e509c9c 100644 --- a/unittest/test_Config.cpp +++ b/unittest/test_Config.cpp @@ -128,7 +128,7 @@ TEST_CASE("Config::update_from_file") "run_second_cpp = false\n" "sloppiness = time_macros ,include_file_mtime" " include_file_ctime,file_stat_matches,file_stat_matches_ctime,pch_defines" - " , no_system_headers,system_headers,clang_index_store\n" + " , no_system_headers,system_headers,clang_index_store,ivfsoverlay\n" "stats = false\n" "temporary_dir = ${USER}_foo\n" "umask = 777"); // Note: no newline. @@ -169,7 +169,8 @@ TEST_CASE("Config::update_from_file") == (SLOPPY_INCLUDE_FILE_MTIME | SLOPPY_INCLUDE_FILE_CTIME | SLOPPY_TIME_MACROS | SLOPPY_FILE_STAT_MATCHES | SLOPPY_FILE_STAT_MATCHES_CTIME | SLOPPY_SYSTEM_HEADERS - | SLOPPY_PCH_DEFINES | SLOPPY_CLANG_INDEX_STORE)); + | SLOPPY_PCH_DEFINES | SLOPPY_CLANG_INDEX_STORE + | SLOPPY_IVFSOVERLAY)); CHECK_FALSE(config.stats()); CHECK(config.temporary_dir() == FMT("{}_foo", user)); CHECK(config.umask() == 0777); @@ -402,7 +403,7 @@ TEST_CASE("Config::visit_items") "run_second_cpp = false\n" "sloppiness = include_file_mtime, include_file_ctime, time_macros," " file_stat_matches, file_stat_matches_ctime, pch_defines, system_headers," - " clang_index_store\n" + " clang_index_store, ivfsoverlay\n" "stats = false\n" "temporary_dir = td\n" "umask = 022\n"); @@ -459,7 +460,7 @@ TEST_CASE("Config::visit_items") "(test.conf) run_second_cpp = false", "(test.conf) sloppiness = include_file_mtime, include_file_ctime," " time_macros, pch_defines, file_stat_matches, file_stat_matches_ctime," - " system_headers, clang_index_store", + " system_headers, clang_index_store, ivfsoverlay", "(test.conf) stats = false", "(test.conf) temporary_dir = td", "(test.conf) umask = 022", diff --git a/unittest/test_Stat.cpp b/unittest/test_Stat.cpp index 6f8baa6..e5b6eeb 100644 --- a/unittest/test_Stat.cpp +++ b/unittest/test_Stat.cpp @@ -579,7 +579,7 @@ TEST_CASE("Win32 Pending Delete" * doctest::skip(running_under_wine())) // will persist until the handle is closed. Until the file is closed, new // handles cannot be created to the file; attempts to do so fail with // ERROR_ACCESS_DENIED/STATUS_DELETE_PENDING. Our stat implementation maps - // these to EACCES. (Should this be ENOENT?) + // these to ENOENT. FILE_DISPOSITION_INFO info{}; info.DeleteFile = TRUE; REQUIRE_MESSAGE(SetFileInformationByHandle( @@ -590,14 +590,14 @@ TEST_CASE("Win32 Pending Delete" * doctest::skip(running_under_wine())) { auto st = Stat::stat("file"); CHECK(!st); - CHECK(st.error_number() == EACCES); + CHECK(st.error_number() == ENOENT); } SUBCASE("lstat file pending delete") { auto st = Stat::lstat("file"); CHECK(!st); - CHECK(st.error_number() == EACCES); + CHECK(st.error_number() == ENOENT); } } |