From c21ee87eea24eadaf4acd3eb58c837bad223018d Mon Sep 17 00:00:00 2001 From: Mike Gelfand Date: Tue, 16 Jul 2024 22:13:29 +0100 Subject: [PATCH] Add CI configuration for clang-tidy on Windows (#6997) * Add CI configuration for clang-tidy on Windows * Fix issues reported by clang-tidy on Windows * Workaround clang-tidy defects on Windows * Fix C-style casts (which clang-tidy didn't report) --- .github/actions/prepare-deps-win32/action.yml | 61 ++++++ .github/workflows/actions.yml | 80 ++++---- libtransmission/error-types.h | 26 ++- libtransmission/file-capacity.cc | 10 +- libtransmission/file-win32.cc | 178 ++++++++---------- libtransmission/open-files.cc | 4 +- libtransmission/peer-mgr-active-requests.cc | 4 +- libtransmission/peer-msgs.cc | 14 +- libtransmission/platform.cc | 2 +- libtransmission/session-id.cc | 2 +- libtransmission/session-thread.cc | 9 + libtransmission/session-thread.h | 1 - libtransmission/subprocess-win32.cc | 18 +- libtransmission/tr-dht.cc | 1 + libtransmission/utils.cc | 21 ++- libtransmission/watchdir-win32.cc | 74 +++++--- libtransmission/watchdir.cc | 2 +- libtransmission/web.cc | 6 +- release/windows/main.ps1 | 36 ++-- 19 files changed, 331 insertions(+), 218 deletions(-) create mode 100644 .github/actions/prepare-deps-win32/action.yml diff --git a/.github/actions/prepare-deps-win32/action.yml b/.github/actions/prepare-deps-win32/action.yml new file mode 100644 index 000000000..fa1d690ce --- /dev/null +++ b/.github/actions/prepare-deps-win32/action.yml @@ -0,0 +1,61 @@ +name: Prepare Win32 build dependencies +inputs: + arch: + description: Architecture (x86, x64) + required: true + type: + description: Type (CoreDeps, Deps) + required: true +runs: + using: composite + steps: + - name: Get Build Tools + shell: pwsh + run: | + $DepsPrefix = (Join-Path (Get-Item .).Root.Name "${{ inputs.arch }}-prefix") + "DEPS_PREFIX=${DepsPrefix}" | Out-File $Env:GITHUB_ENV -Append + (Join-Path $DepsPrefix bin) | Out-File $Env:GITHUB_PATH -Append + + choco install ` + jom ` + nasm ` + nodejs + & "C:\Program Files\OpenSSL\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- | Out-Host + (Join-Path $Env:ProgramFiles NASM) | Out-File $Env:GITHUB_PATH -Append + (Join-Path (Get-Item -Path "${Env:ProgramFiles(x86)}\WiX Toolset v3.*")[0].FullName bin) | Out-File $Env:GITHUB_PATH -Append + + Install-Module -Name Pscx -RequiredVersion 4.0.0-beta4 -AllowPrerelease -Force + - name: Get Cache Key + id: cache-key + shell: pwsh + run: | + try { + $DepsHash = & (Join-Path . src release windows main.ps1) -Mode DepsHash -BuildArch ${{ inputs.arch }} -BuildPart ${{ inputs.type }} + "hash=${DepsHash}" | Out-File $Env:GITHUB_OUTPUT -Append + } catch { + Write-Error ("{1}{0}{2}{0}{3}" -f [Environment]::NewLine, $_.ToString(), $_.InvocationInfo.PositionMessage, $_.ScriptStackTrace) -ErrorAction Continue + exit 1 + } + - name: Restore Cache + uses: actions/cache/restore@v4 + id: restore-cache + with: + path: ${{ env.DEPS_PREFIX }} + key: ${{ github.job }}-${{ inputs.arch }}-${{ steps.cache-key.outputs.hash }} + - name: Build Dependencies + if: steps.restore-cache.outputs.cache-hit != 'true' + shell: pwsh + run: | + try { + & (Join-Path . src release windows main.ps1) -Mode Build -BuildArch ${{ inputs.arch }} -BuildPart ${{ inputs.type }} + } catch { + Write-Error ("{1}{0}{2}{0}{3}" -f [Environment]::NewLine, $_.ToString(), $_.InvocationInfo.PositionMessage, $_.ScriptStackTrace) -ErrorAction Continue + exit 1 + } + - name: Save Cache + if: steps.restore-cache.outputs.cache-hit != 'true' + uses: actions/cache/save@v4 + id: cache + with: + path: ${{ env.DEPS_PREFIX }} + key: ${{ github.job }}-${{ inputs.arch }}-${{ steps.cache-key.outputs.hash }} diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index add09fa2f..10763883e 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -272,6 +272,43 @@ jobs: run: | if grep 'warning:' makelog; then exit 1; fi + clang-tidy-libtransmission-win32: + runs-on: windows-2022 + needs: [ what-to-make ] + if: ${{ needs.what-to-make.outputs.test-style == 'true' }} + steps: + - name: Show Configuration + run: | + echo '${{ toJSON(needs) }}' + echo '${{ toJSON(runner) }}' + - name: Get Source + uses: actions/checkout@v4 + with: + submodules: recursive + path: src + - name: Prepare Build Deps + uses: ./src/.github/actions/prepare-deps-win32 + with: + arch: x64 + type: CoreDeps + - name: Configure + run: | + Import-VisualStudioVars -VisualStudioVersion 2022 -Architecture x64 + cmake ` + -S src ` + -B obj ` + -G Ninja ` + -DCMAKE_BUILD_TYPE=Debug ` + -DCMAKE_PREFIX_PATH="${Env:DEPS_PREFIX}" ` + -DRUN_CLANG_TIDY=ON + - name: Make + run: | + Import-VisualStudioVars -VisualStudioVersion 2022 -Architecture x64 + cmake --build obj --config Debug --target transmission.lib 2>&1 | tee makelog + - name: Test for warnings + run: | + if (Select-String -Path makelog -Pattern 'warning:') { exit 1 } + macos-14-arm64: runs-on: macos-14 needs: [ what-to-make ] @@ -458,51 +495,16 @@ jobs: run: | echo '${{ toJSON(needs) }}' echo '${{ toJSON(runner) }}' - - name: Get Build Tools - run: | - $DepsPrefix = (Join-Path (Get-Item .).Root.Name "${{ matrix.arch }}-prefix") - "DEPS_PREFIX=${DepsPrefix}" | Out-File $Env:GITHUB_ENV -Append - (Join-Path $DepsPrefix bin) | Out-File $Env:GITHUB_PATH -Append - - choco install ` - jom ` - nasm ` - nodejs - & "C:\Program Files\OpenSSL\unins000.exe" /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /SP- | Out-Host - (Join-Path $Env:ProgramFiles NASM) | Out-File $Env:GITHUB_PATH -Append - (Join-Path (Get-Item -Path "${Env:ProgramFiles(x86)}\WiX Toolset v3.*")[0].FullName bin) | Out-File $Env:GITHUB_PATH -Append - - Install-Module -Name Pscx -RequiredVersion 4.0.0-beta4 -AllowPrerelease -Force - name: Get Source uses: actions/checkout@v4 with: path: src submodules: recursive - - name: Get Cache Key - id: cache-key - run: | - try { - $DepsHash = & (Join-Path . src release windows main.ps1) -Mode DepsHash -BuildArch ${{ matrix.arch }} - "hash=${DepsHash}" | Out-File $Env:GITHUB_OUTPUT -Append - } catch { - Write-Error ("{1}{0}{2}{0}{3}" -f [Environment]::NewLine, $_.ToString(), $_.InvocationInfo.PositionMessage, $_.ScriptStackTrace) -ErrorAction Continue - exit 1 - } - - name: Get Cache - uses: actions/cache@v4 - id: cache + - name: Prepare Build Deps + uses: ./src/.github/actions/prepare-deps-win32 with: - path: ${{ env.DEPS_PREFIX }} - key: ${{ github.job }}-${{ matrix.arch }}-${{ steps.cache-key.outputs.hash }} - - name: Build Dependencies - if: steps.cache.outputs.cache-hit != 'true' - run: | - try { - & (Join-Path . src release windows main.ps1) -Mode Build -BuildArch ${{ matrix.arch }} -BuildPart Deps - } catch { - Write-Error ("{1}{0}{2}{0}{3}" -f [Environment]::NewLine, $_.ToString(), $_.InvocationInfo.PositionMessage, $_.ScriptStackTrace) -ErrorAction Continue - exit 1 - } + arch: ${{ matrix.arch }} + type: Deps - name: Configure run: | Import-VisualStudioVars -VisualStudioVersion 2022 -Architecture ${{ matrix.arch }} diff --git a/libtransmission/error-types.h b/libtransmission/error-types.h index 0bc3fb69c..438c733e8 100644 --- a/libtransmission/error-types.h +++ b/libtransmission/error-types.h @@ -14,20 +14,32 @@ #define ERROR_DIRECTORY_NOT_SUPPORTED 336 #endif -#define TR_ERROR_IS_ENOENT(code) ((code) == ERROR_FILE_NOT_FOUND || (code) == ERROR_PATH_NOT_FOUND) -#define TR_ERROR_IS_ENOSPC(code) ((code) == ERROR_DISK_FULL) - #define TR_ERROR_EINVAL ERROR_INVALID_PARAMETER #define TR_ERROR_EISDIR ERROR_DIRECTORY_NOT_SUPPORTED #else /* _WIN32 */ -#include - -#define TR_ERROR_IS_ENOENT(code) ((code) == ENOENT) -#define TR_ERROR_IS_ENOSPC(code) ((code) == ENOSPC) +#include #define TR_ERROR_EINVAL EINVAL #define TR_ERROR_EISDIR EISDIR #endif /* _WIN32 */ + +constexpr inline bool tr_error_is_enoent(int code) noexcept +{ +#ifdef _WIN32 + return code == ERROR_FILE_NOT_FOUND || code == ERROR_PATH_NOT_FOUND; +#else + return code == ENOENT; +#endif +} + +constexpr inline bool tr_error_is_enospc(int code) noexcept +{ +#ifdef _WIN32 + return code == ERROR_DISK_FULL; +#else + return code == ENOSPC; +#endif +} diff --git a/libtransmission/file-capacity.cc b/libtransmission/file-capacity.cc index 2afdbfcf2..0bbc20ed8 100644 --- a/libtransmission/file-capacity.cc +++ b/libtransmission/file-capacity.cc @@ -452,13 +452,13 @@ extern "C" if (auto const wide_path = tr_win32_utf8_to_native(path); !std::empty(wide_path)) { - ULARGE_INTEGER freeBytesAvailable; - ULARGE_INTEGER totalBytesAvailable; + ULARGE_INTEGER free_bytes_available; + ULARGE_INTEGER total_bytes_available; - if (GetDiskFreeSpaceExW(wide_path.c_str(), &freeBytesAvailable, &totalBytesAvailable, nullptr)) + if (GetDiskFreeSpaceExW(wide_path.c_str(), &free_bytes_available, &total_bytes_available, nullptr) != 0) { - ret.free = freeBytesAvailable.QuadPart; - ret.total = totalBytesAvailable.QuadPart; + ret.free = free_bytes_available.QuadPart; + ret.total = total_bytes_available.QuadPart; } } diff --git a/libtransmission/file-win32.cc b/libtransmission/file-win32.cc index e1286c113..45a89ed82 100644 --- a/libtransmission/file-win32.cc +++ b/libtransmission/file-win32.cc @@ -27,14 +27,6 @@ using namespace std::literals; -#ifndef MAXSIZE_T -#define MAXSIZE_T ((SIZE_T) ~((SIZE_T)0)) -#endif - -/* MSDN (http://msdn.microsoft.com/en-us/library/2k2xf226.aspx) only mentions - "i64" suffix for C code, but no warning is issued */ -#define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL - struct tr_sys_dir_win32 { std::wstring pattern; @@ -45,6 +37,8 @@ struct tr_sys_dir_win32 namespace { +auto constexpr DeltaEpochInMicrosecs = UINT64_C(11644473600000000); + auto constexpr NativeLocalPathPrefix = L"\\\\?\\"sv; auto constexpr NativeUncPathPrefix = L"\\\\?\\UNC\\"sv; @@ -72,11 +66,16 @@ constexpr time_t filetime_to_unix_time(FILETIME const& t) tmp <<= 32; tmp |= t.dwLowDateTime; tmp /= 10; /* to microseconds */ - tmp -= DELTA_EPOCH_IN_MICROSECS; + tmp -= DeltaEpochInMicrosecs; return tmp / 1000000UL; } +constexpr bool to_bool(BOOL value) noexcept +{ + return value != FALSE; +} + constexpr auto stat_to_sys_path_info(DWORD attributes, DWORD size_low, DWORD size_high, FILETIME const& mtime) { auto info = tr_sys_path_info{}; @@ -103,7 +102,7 @@ constexpr auto stat_to_sys_path_info(DWORD attributes, DWORD size_low, DWORD siz return info; } -auto constexpr Slashes = "\\/"sv; +auto constexpr Slashes = R"(\/)"sv; constexpr bool is_slash(char c) { @@ -119,27 +118,22 @@ bool is_valid_path(std::string_view path) { if (is_unc_path(path)) { - if (path[2] != '\0' && !isalnum(path[2])) + if (path[2] != '\0' && isalnum(path[2]) == 0) { return false; } } - else + else if (auto const pos = path.find(':'); pos != std::string_view::npos) { - auto pos = path.find(':'); - - if (pos != path.npos) + if (pos != 1 || isalpha(path[0]) == 0) { - if (pos != 1 || !isalpha(path[0])) - { - return false; - } - - path.remove_prefix(2); + return false; } + + path.remove_prefix(2); } - return path.find_first_of("<>:\"|?*"sv) == path.npos; + return path.find_first_of(R"(<>:"|?*)"sv) == std::string_view::npos; } auto path_to_fixed_native_path(std::string_view path) @@ -200,7 +194,7 @@ std::string native_path_to_path(std::wstring_view wide_path) { wide_path.remove_prefix(std::size(NativeUncPathPrefix)); auto path = tr_win32_native_to_utf8(wide_path); - path.insert(0, "\\\\"sv); + path.insert(0, R"(\\)"sv); return path; } @@ -239,7 +233,7 @@ tr_sys_file_t open_file(std::string_view path, DWORD access, DWORD disposition, bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay_if_exists, tr_error* error) { - bool ret; + bool ret = false; DWORD error_code = ERROR_SUCCESS; auto const wide_path = path_to_native_path(path); @@ -256,7 +250,7 @@ bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay } else { - ret = CreateDirectoryW(wide_path.c_str(), nullptr); + ret = to_bool(CreateDirectoryW(wide_path.c_str(), nullptr)); if (!ret) { @@ -282,14 +276,10 @@ bool create_dir(std::string_view path, int flags, int /*permissions*/, bool okay return ret; } -void create_temp_path( - char* path_template, - void (*callback)(char const* path, void* param, tr_error* error), - void* callback_param, - tr_error* error) +template +void create_temp_path(char* path_template, CallbackT&& callback, tr_error* error) { TR_ASSERT(path_template != nullptr); - TR_ASSERT(callback != nullptr); auto path = std::string{ path_template }; auto path_size = std::size(path); @@ -313,7 +303,7 @@ void create_temp_path( local_error = {}; - (*callback)(path.c_str(), callback_param, &local_error); + callback(path.c_str(), &local_error); if (!local_error) { @@ -336,7 +326,7 @@ std::optional tr_sys_file_get_info_(tr_sys_file_t handle, tr_e TR_ASSERT(handle != TR_BAD_SYS_FILE); auto attributes = BY_HANDLE_FILE_INFORMATION{}; - if (GetFileInformationByHandle(handle, &attributes)) + if (to_bool(GetFileInformationByHandle(handle, &attributes))) { return stat_to_sys_path_info( attributes.dwFileAttributes, @@ -367,7 +357,7 @@ std::optional get_file_info(char const* path, tr_err // TODO: Use GetFileInformationByHandleEx on >= Server 2012 auto info = BY_HANDLE_FILE_INFORMATION{}; - if (!GetFileInformationByHandle(handle, &info)) + if (!to_bool(GetFileInformationByHandle(handle, &info))) { set_system_error_if_file_found(error, GetLastError()); CloseHandle(handle); @@ -378,23 +368,6 @@ std::optional get_file_info(char const* path, tr_err return info; } -void file_open_temp_callback(char const* path, void* param, tr_error* error) -{ - auto* const result = static_cast(param); - - TR_ASSERT(result != nullptr); - - *result = open_file(path, GENERIC_READ | GENERIC_WRITE, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, error); -} - -void dir_create_temp_callback(char const* path, void* param, tr_error* error) -{ - auto* const result = static_cast(param); - - TR_ASSERT(result != nullptr); - - *result = create_dir(path, 0, 0, false, error); -} } // namespace bool tr_sys_path_exists(char const* path, tr_error* error) @@ -406,7 +379,7 @@ bool tr_sys_path_exists(char const* path, tr_error* error) if (auto const wide_path = path_to_native_path(path); !std::empty(wide_path)) { - DWORD attributes = GetFileAttributesW(wide_path.c_str()); + DWORD const attributes = GetFileAttributesW(wide_path.c_str()); if (attributes != INVALID_FILE_ATTRIBUTES) { @@ -444,7 +417,7 @@ std::optional tr_sys_path_get_info(std::string_view path, int else if ((flags & TR_SYS_PATH_NO_FOLLOW) != 0) { auto attributes = WIN32_FILE_ATTRIBUTE_DATA{}; - if (GetFileAttributesExW(wide_path.c_str(), GetFileExInfoStandard, &attributes)) + if (to_bool(GetFileAttributesExW(wide_path.c_str(), GetFileExInfoStandard, &attributes))) { return stat_to_sys_path_info( attributes.dwFileAttributes, @@ -475,13 +448,13 @@ bool tr_sys_path_is_relative(std::string_view path) } /* Local path: `X:` */ - if (std::size(path) == 2 && isalpha(path[0]) && path[1] == ':') + if (std::size(path) == 2 && isalpha(path[0]) != 0 && path[1] == ':') { return false; } /* Local path: `X:\...`. */ - if (std::size(path) > 2 && isalpha(path[0]) && path[1] == ':' && is_slash(path[2])) + if (std::size(path) > 2 && isalpha(path[0]) != 0 && path[1] == ':' && is_slash(path[2])) { return false; } @@ -584,15 +557,18 @@ std::string_view tr_sys_path_basename(std::string_view path, tr_error* error) return !std::empty(path) ? path : "/"sv; } -[[nodiscard]] static bool isWindowsDeviceRoot(char ch) noexcept +namespace +{ +[[nodiscard]] bool isWindowsDeviceRoot(char ch) noexcept { return isalpha(static_cast(ch)) != 0; } -[[nodiscard]] static constexpr bool isPathSeparator(char ch) noexcept +[[nodiscard]] constexpr bool isPathSeparator(char ch) noexcept { return ch == '/' || ch == '\\'; } +} // namespace // This function is adapted from Node.js's path.win32.dirname() function, // which is copyrighted by Joyent, Inc. and other Node contributors @@ -674,7 +650,7 @@ std::string_view tr_sys_path_dirname(std::string_view path) } auto end = std::string_view::npos; - auto matched_slash = bool{ true }; + auto matched_slash = true; for (std::string_view::size_type i = len - 1; i >= offset; --i) { if (isPathSeparator(path[i])) @@ -720,25 +696,19 @@ bool tr_sys_path_rename(char const* src_path, char const* dst_path, tr_error* er if (!std::empty(wide_src_path) && !std::empty(wide_dst_path)) { DWORD flags = MOVEFILE_REPLACE_EXISTING; - DWORD attributes; - attributes = GetFileAttributesW(wide_src_path.c_str()); - - if (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) + if (auto const src_attributes = GetFileAttributesW(wide_src_path.c_str()); + src_attributes != INVALID_FILE_ATTRIBUTES && (src_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { flags = 0; } - else + else if (auto const dst_attributes = GetFileAttributesW(wide_dst_path.c_str()); + dst_attributes != INVALID_FILE_ATTRIBUTES && (dst_attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { - attributes = GetFileAttributesW(wide_dst_path.c_str()); - - if (attributes != INVALID_FILE_ATTRIBUTES && (attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) - { - flags = 0; - } + flags = 0; } - ret = MoveFileExW(wide_src_path.c_str(), wide_dst_path.c_str(), flags); + ret = to_bool(MoveFileExW(wide_src_path.c_str(), wide_dst_path.c_str(), flags)); } if (!ret) @@ -764,7 +734,7 @@ bool tr_sys_path_copy(char const* src_path, char const* dst_path, tr_error* erro auto cancel = BOOL{ FALSE }; DWORD const flags = COPY_FILE_ALLOW_DECRYPTED_DESTINATION | COPY_FILE_FAIL_IF_EXISTS; - if (CopyFileExW(wide_src_path.c_str(), wide_dst_path.c_str(), nullptr, nullptr, &cancel, flags) == 0) + if (!to_bool(CopyFileExW(wide_src_path.c_str(), wide_dst_path.c_str(), nullptr, nullptr, &cancel, flags))) { set_system_error(error, GetLastError()); return false; @@ -787,11 +757,11 @@ bool tr_sys_path_remove(char const* path, tr_error* error) { if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0) { - ret = RemoveDirectoryW(wide_path.c_str()); + ret = to_bool(RemoveDirectoryW(wide_path.c_str())); } else { - ret = DeleteFileW(wide_path.c_str()); + ret = to_bool(DeleteFileW(wide_path.c_str())); } } } @@ -824,11 +794,9 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/, TR_ASSERT(path != nullptr); TR_ASSERT((flags & (TR_SYS_FILE_READ | TR_SYS_FILE_WRITE)) != 0); - tr_sys_file_t ret; DWORD native_access = 0; DWORD native_disposition = OPEN_EXISTING; DWORD native_flags = FILE_ATTRIBUTE_NORMAL; - bool success; if ((flags & TR_SYS_FILE_READ) != 0) { @@ -854,9 +822,8 @@ tr_sys_file_t tr_sys_file_open(char const* path, int flags, int /*permissions*/, native_flags |= FILE_FLAG_SEQUENTIAL_SCAN; } - ret = open_file(path, native_access, native_disposition, native_flags, error); - - success = ret != TR_BAD_SYS_FILE; + auto ret = open_file(path, native_access, native_disposition, native_flags, error); + auto success = ret != TR_BAD_SYS_FILE; if (success && (flags & TR_SYS_FILE_APPEND) != 0) { @@ -880,7 +847,11 @@ tr_sys_file_t tr_sys_file_open_temp(char* path_template, tr_error* error) tr_sys_file_t ret = TR_BAD_SYS_FILE; - create_temp_path(path_template, file_open_temp_callback, &ret, error); + create_temp_path( + path_template, + [&ret](char const* path, tr_error* error) + { ret = open_file(path, GENERIC_READ | GENERIC_WRITE, CREATE_NEW, FILE_ATTRIBUTE_TEMPORARY, error); }, + error); return ret; } @@ -889,7 +860,7 @@ bool tr_sys_file_close(tr_sys_file_t handle, tr_error* error) { TR_ASSERT(handle != TR_BAD_SYS_FILE); - bool ret = CloseHandle(handle); + bool const ret = to_bool(CloseHandle(handle)); if (!ret) { @@ -911,9 +882,9 @@ bool tr_sys_file_read(tr_sys_file_t handle, void* buffer, uint64_t size, uint64_ } bool ret = false; - DWORD my_bytes_read; + DWORD my_bytes_read = 0; - if (ReadFile(handle, buffer, (DWORD)size, &my_bytes_read, nullptr)) + if (to_bool(ReadFile(handle, buffer, static_cast(size), &my_bytes_read, nullptr))) { if (bytes_read != nullptr) { @@ -948,15 +919,14 @@ bool tr_sys_file_read_at( } bool ret = false; - OVERLAPPED overlapped; - DWORD my_bytes_read; + auto overlapped = OVERLAPPED{}; + DWORD my_bytes_read = 0; - overlapped.Offset = (DWORD)offset; - offset >>= 32; - overlapped.OffsetHigh = (DWORD)offset; + overlapped.Offset = static_cast(offset); + overlapped.OffsetHigh = static_cast(offset >> 32); overlapped.hEvent = nullptr; - if (ReadFile(handle, buffer, (DWORD)size, &my_bytes_read, &overlapped)) + if (to_bool(ReadFile(handle, buffer, static_cast(size), &my_bytes_read, &overlapped))) { if (bytes_read != nullptr) { @@ -985,9 +955,9 @@ bool tr_sys_file_write(tr_sys_file_t handle, void const* buffer, uint64_t size, } bool ret = false; - DWORD my_bytes_written; + DWORD my_bytes_written = 0; - if (WriteFile(handle, buffer, (DWORD)size, &my_bytes_written, nullptr)) + if (to_bool(WriteFile(handle, buffer, static_cast(size), &my_bytes_written, nullptr))) { if (bytes_written != nullptr) { @@ -1022,15 +992,14 @@ bool tr_sys_file_write_at( } bool ret = false; - OVERLAPPED overlapped; - DWORD my_bytes_written; + auto overlapped = OVERLAPPED{}; + DWORD my_bytes_written = 0; - overlapped.Offset = (DWORD)offset; - offset >>= 32; - overlapped.OffsetHigh = (DWORD)offset; + overlapped.Offset = static_cast(offset); + overlapped.OffsetHigh = static_cast(offset >> 32); overlapped.hEvent = nullptr; - if (WriteFile(handle, buffer, (DWORD)size, &my_bytes_written, &overlapped)) + if (to_bool(WriteFile(handle, buffer, static_cast(size), &my_bytes_written, &overlapped))) { if (bytes_written != nullptr) { @@ -1054,7 +1023,7 @@ bool tr_sys_file_truncate(tr_sys_file_t handle, uint64_t size, tr_error* error) FILE_END_OF_FILE_INFO info; info.EndOfFile.QuadPart = size; - bool ret = SetFileInformationByHandle(handle, FileEndOfFileInfo, &info, sizeof(info)); + bool const ret = to_bool(SetFileInformationByHandle(handle, FileEndOfFileInfo, &info, sizeof(info))); if (!ret) { @@ -1070,9 +1039,9 @@ bool tr_sys_file_preallocate(tr_sys_file_t handle, uint64_t size, int flags, tr_ if ((flags & TR_SYS_FILE_PREALLOC_SPARSE) != 0) { - DWORD tmp; + DWORD tmp = 0; - if (!DeviceIoControl(handle, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &tmp, nullptr)) + if (!to_bool(DeviceIoControl(handle, FSCTL_SET_SPARSE, nullptr, 0, nullptr, 0, &tmp, nullptr))) { set_system_error(error, GetLastError()); return false; @@ -1089,7 +1058,7 @@ bool tr_sys_file_lock(tr_sys_file_t handle, int operation, tr_error* error) TR_ASSERT( !!(operation & TR_SYS_FILE_LOCK_SH) + !!(operation & TR_SYS_FILE_LOCK_EX) + !!(operation & TR_SYS_FILE_LOCK_UN) == 1); - bool ret; + bool ret = false; auto overlapped = OVERLAPPED{}; if ((operation & TR_SYS_FILE_LOCK_UN) == 0) @@ -1150,7 +1119,10 @@ bool tr_sys_dir_create_temp(char* path_template, tr_error* error) bool ret = false; - create_temp_path(path_template, dir_create_temp_callback, &ret, error); + create_temp_path( + path_template, + [&ret](char const* path, tr_error* error) { ret = create_dir(path, 0, 0, false, error); }, + error); return ret; } @@ -1195,7 +1167,7 @@ char const* tr_sys_dir_read_name(tr_sys_dir_t handle, tr_error* error) } else { - if (!FindNextFileW(handle->find_handle, &handle->find_data)) + if (!to_bool(FindNextFileW(handle->find_handle, &handle->find_data))) { error_code = GetLastError(); } @@ -1221,7 +1193,7 @@ bool tr_sys_dir_close(tr_sys_dir_t handle, tr_error* error) { TR_ASSERT(handle != TR_BAD_SYS_DIR); - bool ret = FindClose(handle->find_handle); + bool const ret = to_bool(FindClose(handle->find_handle)); if (!ret) { diff --git a/libtransmission/open-files.cc b/libtransmission/open-files.cc index 41156ca71..813266e31 100644 --- a/libtransmission/open-files.cc +++ b/libtransmission/open-files.cc @@ -46,7 +46,7 @@ bool preallocate_file_sparse(tr_sys_file_t fd, uint64_t length, tr_error* error) tr_logAddDebug(fmt::format("Fast preallocation failed: {} ({})", local_error.message(), local_error.code())); - if (!TR_ERROR_IS_ENOSPC(local_error.code())) + if (!tr_error_is_enospc(local_error.code())) { static char constexpr Zero = '\0'; @@ -86,7 +86,7 @@ bool preallocate_file_full(tr_sys_file_t fd, uint64_t length, tr_error* error) tr_logAddDebug(fmt::format("Full preallocation failed: {} ({})", local_error.message(), local_error.code())); - if (!TR_ERROR_IS_ENOSPC(local_error.code())) + if (!tr_error_is_enospc(local_error.code())) { auto buf = std::array{}; bool success = true; diff --git a/libtransmission/peer-mgr-active-requests.cc b/libtransmission/peer-mgr-active-requests.cc index c66a60bf3..506b598fb 100644 --- a/libtransmission/peer-mgr-active-requests.cc +++ b/libtransmission/peer-mgr-active-requests.cc @@ -26,12 +26,12 @@ struct tr_peer; class ActiveRequests::Impl { public: - size_t size() const + [[nodiscard]] size_t size() const { return size_; } - size_t count(tr_peer const* peer) const + [[nodiscard]] size_t count(tr_peer const* peer) const { auto const it = count_.find(peer); return it != std::end(count_) ? it->second : size_t{}; diff --git a/libtransmission/peer-msgs.cc b/libtransmission/peer-msgs.cc index 149aa1aac..d85a7e97a 100644 --- a/libtransmission/peer-msgs.cc +++ b/libtransmission/peer-msgs.cc @@ -608,40 +608,40 @@ private: // --- - size_t protocol_send_keepalive() const; + size_t protocol_send_keepalive() const; // NOLINT(modernize-use-nodiscard) template size_t protocol_send_message(uint8_t type, Args const&... args) const; - size_t protocol_send_reject(peer_request const& req) const + size_t protocol_send_reject(peer_request const& req) const // NOLINT(modernize-use-nodiscard) { TR_ASSERT(io_->supports_fext()); return protocol_send_message(BtPeerMsgs::FextReject, req.index, req.offset, req.length); } - size_t protocol_send_cancel(peer_request const& req) const + size_t protocol_send_cancel(peer_request const& req) const // NOLINT(modernize-use-nodiscard) { return protocol_send_message(BtPeerMsgs::Cancel, req.index, req.offset, req.length); } - size_t protocol_send_request(peer_request const& req) const + size_t protocol_send_request(peer_request const& req) const // NOLINT(modernize-use-nodiscard) { TR_ASSERT(is_valid_request(req)); return protocol_send_message(BtPeerMsgs::Request, req.index, req.offset, req.length); } - size_t protocol_send_dht_port(tr_port const port) const + size_t protocol_send_dht_port(tr_port const port) const // NOLINT(modernize-use-nodiscard) { return protocol_send_message(BtPeerMsgs::DhtPort, port.host()); } - size_t protocol_send_have(tr_piece_index_t const index) const + size_t protocol_send_have(tr_piece_index_t const index) const // NOLINT(modernize-use-nodiscard) { static_assert(sizeof(tr_piece_index_t) == sizeof(uint32_t)); return protocol_send_message(BtPeerMsgs::Have, index); } - size_t protocol_send_choke(bool const choke) const + size_t protocol_send_choke(bool const choke) const // NOLINT(modernize-use-nodiscard) { return protocol_send_message(choke ? BtPeerMsgs::Choke : BtPeerMsgs::Unchoke); } diff --git a/libtransmission/platform.cc b/libtransmission/platform.cc index 82edad9c1..9dcca67e4 100644 --- a/libtransmission/platform.cc +++ b/libtransmission/platform.cc @@ -54,7 +54,7 @@ namespace #ifdef _WIN32 std::string win32_get_known_folder_ex(REFKNOWNFOLDERID folder_id, DWORD flags) { - if (PWSTR path; SHGetKnownFolderPath(folder_id, flags | KF_FLAG_DONT_UNEXPAND, nullptr, &path) == S_OK) + if (PWSTR path = nullptr; SHGetKnownFolderPath(folder_id, flags | KF_FLAG_DONT_UNEXPAND, nullptr, &path) == S_OK) { auto ret = tr_win32_native_to_utf8(path); CoTaskMemFree(path); diff --git a/libtransmission/session-id.cc b/libtransmission/session-id.cc index 0df33f838..d51d4c999 100644 --- a/libtransmission/session-id.cc +++ b/libtransmission/session-id.cc @@ -128,7 +128,7 @@ bool tr_session_id::is_local(std::string_view session_id) noexcept auto error = tr_error{}; if (auto lockfile_fd = tr_sys_file_open(lockfile_path, TR_SYS_FILE_READ, 0, &error); lockfile_fd == TR_BAD_SYS_FILE) { - if (TR_ERROR_IS_ENOENT(error.code())) + if (tr_error_is_enoent(error.code())) { error = {}; } diff --git a/libtransmission/session-thread.cc b/libtransmission/session-thread.cc index 674c98548..5306306cd 100644 --- a/libtransmission/session-thread.cc +++ b/libtransmission/session-thread.cc @@ -101,10 +101,19 @@ int cond_wait(void* vcond, void* vlock, struct timeval const* tv) return success == std::cv_status::timeout ? 1 : 0; } +#if defined(_WIN32) && defined(__clang_analyzer__) +// See https://github.com/llvm/llvm-project/issues/98823 +#define WORKAROUND_CLANG_TIDY_GH98823 +#endif + unsigned long thread_current_id() { +#ifndef WORKAROUND_CLANG_TIDY_GH98823 thread_local auto const hashed = std::hash()(std::this_thread::get_id()); return hashed; +#else + return 0; +#endif } void init_evthreads_once() diff --git a/libtransmission/session-thread.h b/libtransmission/session-thread.h index 69980e7e9..c0c6a617b 100644 --- a/libtransmission/session-thread.h +++ b/libtransmission/session-thread.h @@ -11,7 +11,6 @@ #include #include -#include #include struct event_base; diff --git a/libtransmission/subprocess-win32.cc b/libtransmission/subprocess-win32.cc index 2779afd80..42f32a4b8 100644 --- a/libtransmission/subprocess-win32.cc +++ b/libtransmission/subprocess-win32.cc @@ -29,7 +29,7 @@ using namespace std::literals; namespace { -enum class tr_app_type +enum class tr_app_type : uint8_t { EXE, BATCH @@ -52,17 +52,22 @@ void set_system_error(tr_error* error, DWORD code, std::string_view what) } } +constexpr bool to_bool(BOOL value) noexcept +{ + return value != FALSE; +} + // "The sort is case-insensitive, Unicode order, without regard to locale" © MSDN class WStrICompare { public: - [[nodiscard]] auto compare(std::wstring_view a, std::wstring_view b) const noexcept // <=> + [[nodiscard]] static auto compare(std::wstring_view a, std::wstring_view b) noexcept // <=> { int diff = wcsnicmp(std::data(a), std::data(b), std::min(std::size(a), std::size(b))); if (diff == 0) { - diff = std::size(a) < std::size(b) ? -1 : (std::size(a) > std::size(b) ? 1 : 0); + diff = tr_compare_3way(std::size(a), std::size(b)); } return diff; @@ -178,6 +183,9 @@ void append_argument(std::string& arguments, char const* argument) case '"': backslash_count = backslash_count * 2 + 1; break; + + default: + break; } if (backslash_count != 0) @@ -298,7 +306,7 @@ bool tr_spawn_async( PROCESS_INFORMATION pi; - bool const ret = CreateProcessW( + bool const ret = to_bool(CreateProcessW( nullptr, std::data(cmd_line), nullptr, @@ -308,7 +316,7 @@ bool tr_spawn_async( std::empty(full_env) ? nullptr : to_env_string(full_env).data(), std::empty(current_dir) ? nullptr : current_dir.c_str(), &si, - &pi); + &pi)); if (ret) { diff --git a/libtransmission/tr-dht.cc b/libtransmission/tr-dht.cc index 9c1cd9bc2..9fc7b750d 100644 --- a/libtransmission/tr-dht.cc +++ b/libtransmission/tr-dht.cc @@ -90,6 +90,7 @@ extern "C" int dht_sendto(int sockfd, void const* buf, int len, int flags, struct sockaddr const* to, int tolen) { + // NOLINTNEXTLINE(readability-redundant-casting) return static_cast(sendto(sockfd, static_cast(buf), len, flags, to, tolen)); } diff --git a/libtransmission/utils.cc b/libtransmission/utils.cc index e39aff71e..8c8f232ac 100644 --- a/libtransmission/utils.cc +++ b/libtransmission/utils.cc @@ -75,21 +75,32 @@ Config::Units Config::Storage{ Config::Base::Kilo, "B"sv, "kB"sv, // --- +#if defined(_WIN32) && defined(__clang_analyzer__) +// See https://github.com/llvm/llvm-project/issues/44701 +#define WORKAROUND_CLANG_TIDY_GH44701 +#endif + std::optional tr_locale_set_global(char const* locale_name) noexcept { +#ifndef WORKAROUND_CLANG_TIDY_GH44701 try +#endif { return tr_locale_set_global(std::locale{ locale_name }); } +#ifndef WORKAROUND_CLANG_TIDY_GH44701 catch (std::runtime_error const&) { return {}; } +#endif } std::optional tr_locale_set_global(std::locale const& locale) noexcept { +#ifndef WORKAROUND_CLANG_TIDY_GH44701 try +#endif { auto old_locale = std::locale::global(locale); @@ -98,10 +109,12 @@ std::optional tr_locale_set_global(std::locale const& locale) noexc return old_locale; } +#ifndef WORKAROUND_CLANG_TIDY_GH44701 catch (std::exception const&) { return {}; } +#endif } // --- @@ -336,7 +349,7 @@ std::string tr_win32_format_message(uint32_t code) nullptr, code, 0, - (LPWSTR)&wide_text, + reinterpret_cast(&wide_text), 0, nullptr); @@ -355,7 +368,7 @@ std::string tr_win32_format_message(uint32_t code) LocalFree(wide_text); // Most (all?) messages contain "\r\n" in the end, chop it - while (!std::empty(text) && isspace(text.back())) + while (!std::empty(text) && isspace(text.back()) != 0) { text.resize(text.size() - 1); } @@ -370,7 +383,7 @@ namespace tr_main_win32_impl std::optional> win32MakeUtf8Argv() { - int argc; + int argc = 0; auto argv = std::vector{}; if (wchar_t** wargv = CommandLineToArgvW(GetCommandLineW(), &argc); wargv != nullptr) { @@ -390,7 +403,7 @@ std::optional> win32MakeUtf8Argv() argv.emplace_back(std::move(str)); } - LocalFree(wargv); + LocalFree(reinterpret_cast(wargv)); } if (static_cast(std::size(argv)) == argc) diff --git a/libtransmission/watchdir-win32.cc b/libtransmission/watchdir-win32.cc index b179a5c9c..3f787f38d 100644 --- a/libtransmission/watchdir-win32.cc +++ b/libtransmission/watchdir-win32.cc @@ -34,6 +34,11 @@ namespace libtransmission namespace { +constexpr bool to_bool(BOOL value) noexcept +{ + return value != FALSE; +} + BOOL tr_get_overlapped_result_ex( HANDLE handle, LPOVERLAPPED overlapped, @@ -48,7 +53,7 @@ BOOL tr_get_overlapped_result_ex( if (!is_real_impl_valid) { - real_impl = (impl_t)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetOverlappedResultEx"); + real_impl = reinterpret_cast(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "GetOverlappedResultEx")); is_real_impl_valid = true; } @@ -142,14 +147,15 @@ private: return; } - if ((fd_ = CreateFileW( - wide_path.c_str(), - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - nullptr, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, - nullptr)) == INVALID_HANDLE_VALUE) + fd_ = CreateFileW( + wide_path.c_str(), + FILE_LIST_DIRECTORY, + FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, + nullptr, + OPEN_EXISTING, + FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED, + nullptr); + if (fd_ == INVALID_HANDLE_VALUE) { tr_logAddError(fmt::format(_("Couldn't read '{path}'"), fmt::arg("path", path))); return; @@ -157,7 +163,15 @@ private: overlapped_.Pointer = this; - if (!ReadDirectoryChangesW(fd_, buffer_, sizeof(buffer_), false, Win32WatchMask, nullptr, &overlapped_, nullptr)) + if (!to_bool(ReadDirectoryChangesW( + fd_, + std::data(buffer_), + std::size(buffer_), + FALSE, + Win32WatchMask, + nullptr, + &overlapped_, + nullptr))) { tr_logAddError(fmt::format(_("Couldn't read '{path}'"), fmt::arg("path", path))); return; @@ -188,7 +202,8 @@ private: bufferevent_setcb(event_, &Win32Watchdir::onBufferEvent, nullptr, nullptr, this); bufferevent_enable(event_, EV_READ); - thread_ = (HANDLE)_beginthreadex(nullptr, 0, Win32Watchdir::staticThreadFunc, this, 0, nullptr); + // NOLINTNEXTLINE(performance-no-int-to-ptr) + thread_ = reinterpret_cast(_beginthreadex(nullptr, 0, Win32Watchdir::staticThreadFunc, this, 0, nullptr)); if (thread_ == nullptr) { tr_logAddError(_("Couldn't create thread")); @@ -203,22 +218,31 @@ private: unsigned int threadFunc() { - DWORD bytes_transferred; + DWORD bytes_transferred = 0; - while (tr_get_overlapped_result_ex(fd_, &overlapped_, &bytes_transferred, INFINITE, FALSE)) + while (to_bool(tr_get_overlapped_result_ex(fd_, &overlapped_, &bytes_transferred, INFINITE, FALSE))) { - PFILE_NOTIFY_INFORMATION info = (PFILE_NOTIFY_INFORMATION)buffer_; + auto* info = reinterpret_cast(std::data(buffer_)); while (info->NextEntryOffset != 0) { - *((BYTE**)&info) += info->NextEntryOffset; + *reinterpret_cast(&info) += info->NextEntryOffset; } - info->NextEntryOffset = bytes_transferred - ((BYTE*)info - (BYTE*)buffer_); + info->NextEntryOffset = bytes_transferred - + (reinterpret_cast(info) - reinterpret_cast(std::data(buffer_))); - send(notify_pipe_[1], (char const*)buffer_, bytes_transferred, 0); + send(notify_pipe_[1], reinterpret_cast(std::data(buffer_)), bytes_transferred, 0); - if (!ReadDirectoryChangesW(fd_, buffer_, sizeof(buffer_), FALSE, Win32WatchMask, nullptr, &overlapped_, nullptr)) + if (!to_bool(ReadDirectoryChangesW( + fd_, + std::data(buffer_), + std::size(buffer_), + FALSE, + Win32WatchMask, + nullptr, + &overlapped_, + nullptr))) { tr_logAddError(_("Couldn't read directory changes")); return 0; @@ -249,7 +273,7 @@ private: auto buffer = std::vector{}; buffer.resize(sizeof(FILE_NOTIFY_INFORMATION) + name_size); - PFILE_NOTIFY_INFORMATION ev = (PFILE_NOTIFY_INFORMATION)std::data(buffer); + auto* ev = reinterpret_cast(std::data(buffer)); size_t const header_size = offsetof(FILE_NOTIFY_INFORMATION, FileName); @@ -263,7 +287,7 @@ private: break; } - if (nread == (size_t)-1) + if (nread == static_cast(-1)) { auto const error_code = errno; tr_logAddError(fmt::format( @@ -292,12 +316,12 @@ private: { name_size = nleft; buffer.resize(sizeof(FILE_NOTIFY_INFORMATION) + name_size); - ev = (PFILE_NOTIFY_INFORMATION)std::data(buffer); + ev = reinterpret_cast(std::data(buffer)); } // consume entire name into buffer nread = bufferevent_read(event, &buffer[header_size], nleft); - if (nread == (size_t)-1) + if (nread == static_cast(-1)) { auto const error_code = errno; tr_logAddError(fmt::format( @@ -330,7 +354,7 @@ private: HANDLE fd_ = INVALID_HANDLE_VALUE; OVERLAPPED overlapped_ = {}; - DWORD buffer_[8 * 1024 / sizeof(DWORD)]; + std::array buffer_ = {}; std::array notify_pipe_{ static_cast(-1), static_cast(-1) }; struct bufferevent* event_ = nullptr; HANDLE thread_ = {}; @@ -342,9 +366,9 @@ std::unique_ptr Watchdir::create( std::string_view dirname, Callback callback, TimerMaker& timer_maker, - struct event_base* event_base) + struct event_base* evbase) { - return std::make_unique(dirname, std::move(callback), timer_maker, event_base); + return std::make_unique(dirname, std::move(callback), timer_maker, evbase); } } // namespace libtransmission diff --git a/libtransmission/watchdir.cc b/libtransmission/watchdir.cc index 76471a01c..cc1dddac1 100644 --- a/libtransmission/watchdir.cc +++ b/libtransmission/watchdir.cc @@ -46,7 +46,7 @@ namespace auto error = tr_error{}; auto const info = tr_sys_path_get_info(path, 0, &error); - if (error && !TR_ERROR_IS_ENOENT(error.code())) + if (error && !tr_error_is_enoent(error.code())) { tr_logAddWarn(fmt::format( _("Skipping '{path}': {error} ({error_code})"), diff --git a/libtransmission/web.cc b/libtransmission/web.cc index 6b37a0184..628f72b83 100644 --- a/libtransmission/web.cc +++ b/libtransmission/web.cc @@ -129,7 +129,7 @@ CURLcode ssl_context_func(CURL* /*curl*/, void* ssl_ctx, void* /*user_data*/) for (auto& sys_store_name : SysStoreNames) { - HCERTSTORE const sys_cert_store = CertOpenSystemStoreW(0, sys_store_name); + auto* const sys_cert_store = CertOpenSystemStoreW(0, sys_store_name); if (sys_cert_store == nullptr) { continue; @@ -145,7 +145,7 @@ CURLcode ssl_context_func(CURL* /*curl*/, void* ssl_ctx, void* /*user_data*/) break; } - tr_x509_cert_t const cert = tr_x509_cert_new(sys_cert->pbCertEncoded, sys_cert->cbCertEncoded); + auto* const cert = tr_x509_cert_new(sys_cert->pbCertEncoded, sys_cert->cbCertEncoded); if (cert == nullptr) { continue; @@ -406,7 +406,7 @@ public: // if unset: steady-state, all is good // if set: do not accept new tasks // if set and deadline reached: kill all remaining tasks - std::atomic deadline_ = {}; + std::atomic deadline_ = {}; // NOLINT(readability-redundant-member-init) [[nodiscard]] auto deadline() const { diff --git a/release/windows/main.ps1 b/release/windows/main.ps1 index 8efb130f1..9ea5dbfd8 100644 --- a/release/windows/main.ps1 +++ b/release/windows/main.ps1 @@ -10,7 +10,7 @@ Param( [string] $BuildArch, [Parameter()] - [ValidateSet('All', 'Deps', 'App')] + [ValidateSet('All', 'CoreDeps', 'Deps', 'App')] [string] $BuildPart = 'All', [Parameter()] @@ -258,14 +258,23 @@ if (-not $SourceDir) { if ($Mode -eq 'DepsHash') { Import-Script Toolchain - $Names = @( - Invoke-Build Expat -CacheArchiveNameOnly - Invoke-Build DBus -CacheArchiveNameOnly - Invoke-Build Zlib -CacheArchiveNameOnly - Invoke-Build OpenSsl -CacheArchiveNameOnly - Invoke-Build Curl -CacheArchiveNameOnly - Invoke-Build Qt$UseQtVersion -CacheArchiveNameOnly - ) + $Names = @() + + if (@('All', 'CoreDeps', 'Deps') -contains $BuildPart) { + $Names = $Names + @( + Invoke-Build Zlib -CacheArchiveNameOnly + Invoke-Build OpenSsl -CacheArchiveNameOnly + Invoke-Build Curl -CacheArchiveNameOnly + ) + } + + if (@('All', 'Deps') -contains $BuildPart) { + $Names = $Names + @( + Invoke-Build Expat -CacheArchiveNameOnly + Invoke-Build DBus -CacheArchiveNameOnly + Invoke-Build Qt$UseQtVersion -CacheArchiveNameOnly + ) + } Write-Output (Get-StringHash ($Names -join ':')) } @@ -285,12 +294,15 @@ if ($Mode -eq 'Build') { $Env:CMAKE_CXX_COMPILER_LAUNCHER = '' } - if (@('All', 'Deps') -contains $BuildPart) { - Invoke-Build Expat - Invoke-Build DBus + if (@('All', 'CoreDeps', 'Deps') -contains $BuildPart) { Invoke-Build Zlib Invoke-Build OpenSsl Invoke-Build Curl + } + + if (@('All', 'Deps') -contains $BuildPart) { + Invoke-Build Expat + Invoke-Build DBus Invoke-Build Qt$UseQtVersion }