Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ci: Add clang-tidy to CI #95

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions .clang-tidy
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2023 The Khronos Group Inc.
# Copyright 2023 Valve Corporation
# Copyright 2023 LunarG, Inc.
#
# SPDX-License-Identifier: Apache-2.0
Checks: "-*,\
google*,\
readability-identifier-naming,\
-google-readability-todo,\
-google-readability-avoid-underscore-in-googletest-name,\
-google-runtime-references,\
"
WarningsAsErrors: "*"
HeaderFilterRegex: ".*"
CheckOptions:
- { key: readability-identifier-naming.VariableCase, value: lower_case }
- { key: readability-identifier-naming.GlobalConstantCase, value: CamelCase }
- { key: readability-identifier-naming.GlobalConstantPrefix, value: k }
17 changes: 17 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,23 @@ on:
- main

jobs:
clang_tidy:
runs-on: ${{matrix.os}}
strategy:
matrix:
os: [ ubuntu-22.04, windows-2022 ]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: '3.8'
- uses: ilammy/msvc-dev-cmd@v1
- uses: lukka/get-cmake@latest
- name: Configure
run: cmake -S. -B build -D VUL_CLANG_TIDY=ON -D VUL_WERROR=ON -D BUILD_TESTS=ON -D CMAKE_BUILD_TYPE=Release -D UPDATE_DEPS=ON -G "Ninja"
- name: Build
run: cmake --build build --verbose

build_and_test:
runs-on: ${{matrix.os}}
strategy:
Expand Down
8 changes: 6 additions & 2 deletions BUILD.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,6 @@ cd build/
ctest -C Debug --parallel 8 --output-on-failure
```

## CMake

### Warnings as errors off by default!

By default `VUL_WERROR` is `OFF`
Expand All @@ -55,3 +53,9 @@ System package managers, and language package managers have to build on multiple
By defaulting to `ON` we cause issues for package managers since there is no standard way to disable warnings until CMake 3.24

Add `-D VUL_WERROR=ON` to your workflow. Or use the `dev` preset shown below which will also enabling warnings as errors.

### clang-tidy

By default clang-tidy checking is disabled by default.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is it disabled by default? It seems much better for me to hit issues on my system than on C.I., consume more C.I. resource and have to iterate, taking more development time. This is especially true that I don't see how the developer would even now what the rules are.

I would argu the same with VUL_WERROR being OFF by default.

I think we need to be more consious when we add new checks how this is going to affect the developers productivity.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's off by default to avoid issues with package managers, machines that don't have clang-tidy installed by default, FetchContent/add_subdirectory users, etc.

Having it on by default is more complicated than having it on. That's just the way it is with open source projects.


To enable it set `VUL_CLANG_TIDY` to `ON`. clang-tidy is required to pass CI.
9 changes: 9 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,15 @@ if (VUL_WERROR)
endif()
endif()

option(VVL_CLANG_TIDY "Use clang-tidy")
if (VUL_CLANG_TIDY)
find_program(CLANG_TIDY NAMES clang-tidy)
if(NOT CLANG_TIDY)
message(FATAL_ERROR "clang-tidy not found!")
endif()
set(CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY}")
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CMAKE_<LANG>_CLANG_TIDY only works on the makefile / ninja generator.

Given how popular the visual studio generator is within our team this is likely only going to cause confusion.

endif()

if(${CMAKE_CXX_COMPILER_ID} MATCHES "(GNU|Clang)")
add_compile_options(
-Wall
Expand Down
3 changes: 3 additions & 0 deletions include/vulkan/utility/vul_dispatch_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

#include <string.h>

// NOLINTBEGIN(google-readability-casting)

typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName);

// Instance function pointer dispatch table
Expand Down Expand Up @@ -1573,3 +1575,4 @@ static inline void vulInitInstanceDispatchTable(VkInstance instance, VulInstance
#endif // VK_USE_PLATFORM_SCREEN_QNX
table->GetPhysicalDeviceOpticalFlowImageFormatsNV = (PFN_vkGetPhysicalDeviceOpticalFlowImageFormatsNV)gipa(instance, "vkGetPhysicalDeviceOpticalFlowImageFormatsNV");
}
// NOLINTEND(google-readability-casting)
6 changes: 5 additions & 1 deletion scripts/generators/dispatch_table_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def generate(self):

#include <string.h>

// NOLINTBEGIN(google-readability-casting)

typedef PFN_vkVoidFunction(VKAPI_PTR *PFN_GetPhysicalDeviceProcAddr)(VkInstance instance, const char *pName);
''')
out.append('''
Expand Down Expand Up @@ -88,6 +90,8 @@ def generate(self):
out.extend([f'#ifdef {command.protect}\n'] if command.protect else [])
out.append(f' table->{command.name[2:]} = (PFN_{command.name})gipa(instance, "{command.name}");\n')
out.extend([f'#endif // {command.protect}\n'] if command.protect else [])
out.append('}')
out.append('}\n')

out.append("// NOLINTEND(google-readability-casting)")

self.write("".join(out))
12 changes: 6 additions & 6 deletions src/layer/layer_settings_manager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ static inline bool IsHighIntegrity() {
DWORD buffer_size;
if (GetTokenInformation(process_token, TokenIntegrityLevel, mandatory_label_buffer, sizeof(mandatory_label_buffer),
&buffer_size) != 0) {
const TOKEN_MANDATORY_LABEL *mandatory_label = (const TOKEN_MANDATORY_LABEL *)mandatory_label_buffer;
const TOKEN_MANDATORY_LABEL *mandatory_label = reinterpret_cast<const TOKEN_MANDATORY_LABEL *>(mandatory_label_buffer);
const DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);

Expand Down Expand Up @@ -150,17 +150,17 @@ std::filesystem::path LayerSettings::FindSettingsFile() {
LSTATUS err = RegOpenKeyEx(hives[hive_index], TEXT("Software\\Khronos\\Vulkan\\Settings"), 0, KEY_READ, &key);
if (err == ERROR_SUCCESS) {
TCHAR name[2048];
DWORD i = 0, name_size, type, pValues, value_size;
DWORD i = 0, name_size, type, p_values, value_size;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have never seen this convention before.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I grabbed the clang-tidy file from the vulkan validation layers.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no preference tbh. Just a matter of changing the clang-tidy file.

- { key: readability-identifier-naming.VariableCase, value: lower_case }

while (ERROR_SUCCESS == RegEnumValue(key, i++, name, &(name_size = sizeof(name)), nullptr, &type,
reinterpret_cast<LPBYTE>(&pValues), &(value_size = sizeof(pValues)))) {
reinterpret_cast<LPBYTE>(&p_values), &(value_size = sizeof(p_values)))) {
// Check if the registry entry is a dword with a value of zero
if (type != REG_DWORD || pValues != 0) {
if (type != REG_DWORD || p_values != 0) {
continue;
}

// Check if this actually points to a file
DWORD fileAttrib = GetFileAttributes(name);
if ((fileAttrib == INVALID_FILE_ATTRIBUTES) || (fileAttrib & FILE_ATTRIBUTE_DIRECTORY)) {
DWORD file_attrib = GetFileAttributes(name);
if ((file_attrib == INVALID_FILE_ATTRIBUTES) || (file_attrib & FILE_ATTRIBUTE_DIRECTORY)) {
continue;
}

Expand Down
30 changes: 15 additions & 15 deletions src/layer/layer_settings_util.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ std::string GetFileSettingName(const char *pLayerName, const char *pSettingName)
assert(pLayerName != nullptr);
assert(pSettingName != nullptr);

std::stringstream settingName;
settingName << vl::ToLower(TrimPrefix(pLayerName)) << "." << pSettingName;
std::stringstream setting_name;
setting_name << vl::ToLower(TrimPrefix(pLayerName)) << "." << pSettingName;

return settingName.str();
return setting_name.str();
}

std::string GetEnvSettingName(const char *layer_key, const char *setting_key, TrimMode trim_mode) {
Expand Down Expand Up @@ -145,15 +145,15 @@ std::string TrimVendor(const std::string &layer_key) {
std::string ToLower(const std::string &s) {
std::string result = s;
for (auto &c : result) {
c = (char)std::tolower(c);
c = static_cast<char>(std::tolower(c));
}
return result;
}

std::string ToUpper(const std::string &s) {
std::string result = s;
for (auto &c : result) {
c = (char)std::toupper(c);
c = static_cast<char>(std::toupper(c));
}
return result;
}
Expand Down Expand Up @@ -230,34 +230,34 @@ std::vector<VlFrameset> ToFrameSets(const std::string &s) {
}

bool IsFrameSets(const std::string &s) {
static const std::regex FRAME_REGEX("^([0-9]+([-][0-9]+){0,2})(,([0-9]+([-][0-9]+){0,2}))*$");
static const std::regex frame_regex("^([0-9]+([-][0-9]+){0,2})(,([0-9]+([-][0-9]+){0,2}))*$");

return std::regex_search(s, FRAME_REGEX);
return std::regex_search(s, frame_regex);
}

bool IsInteger(const std::string &s) {
static const std::regex FRAME_REGEX("^-?([0-9]*|0x[0-9|a-z|A-Z]*)$");
static const std::regex frame_regex("^-?([0-9]*|0x[0-9|a-z|A-Z]*)$");

return std::regex_search(s, FRAME_REGEX);
return std::regex_search(s, frame_regex);
}

bool IsFloat(const std::string &s) {
static const std::regex FRAME_REGEX("^-?[0-9]*([.][0-9]*f?)?$");
static const std::regex frame_regex("^-?[0-9]*([.][0-9]*f?)?$");

return std::regex_search(s, FRAME_REGEX);
return std::regex_search(s, frame_regex);
}

std::string FormatString(const char *message, ...) {
std::size_t const STRING_BUFFER(4096);
std::size_t const string_buffer(4096);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

string_buffer is a confusing name since its the length of the buffer, not the buffer itself.


assert(message != nullptr);
assert(strlen(message) >= 1 && strlen(message) < STRING_BUFFER);
assert(strlen(message) >= 1 && strlen(message) < string_buffer);

char buffer[STRING_BUFFER];
char buffer[string_buffer];
va_list list;

va_start(list, message);
vsnprintf(buffer, STRING_BUFFER, message, list);
vsnprintf(buffer, string_buffer, message, list);
va_end(list);

return buffer;
Expand Down
16 changes: 8 additions & 8 deletions src/layer/vk_layer_settings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ void test_helper_SetLayerSetting(VlLayerSettingSet layerSettingSet, const char *
assert(pSettingName != nullptr);
assert(pValue != nullptr);

vl::LayerSettings *layer_setting_set = (vl::LayerSettings *)layerSettingSet;
vl::LayerSettings *layer_setting_set = reinterpret_cast<vl::LayerSettings *>(layerSettingSet);

layer_setting_set->SetFileSetting(pSettingName, pValue);
}
Expand All @@ -36,15 +36,15 @@ VkResult vlCreateLayerSettingSet(const char *pLayerName, const VkLayerSettingsCr
(void)pAllocator;

vl::LayerSettings* layer_setting_set = new vl::LayerSettings(pLayerName, pCreateInfo, pAllocator, pCallback);
*pLayerSettingSet = (VlLayerSettingSet)layer_setting_set;
*pLayerSettingSet = reinterpret_cast<VlLayerSettingSet>(layer_setting_set);

return VK_SUCCESS;
}

void vlDestroyLayerSettingSet(VlLayerSettingSet layerSettingSet, const VkAllocationCallbacks *pAllocator) {
(void)pAllocator;

vl::LayerSettings *layer_setting_set = (vl::LayerSettings*)layerSettingSet;
vl::LayerSettings *layer_setting_set = reinterpret_cast<vl::LayerSettings *>(layerSettingSet);
delete layer_setting_set;
}

Expand All @@ -53,7 +53,7 @@ VkBool32 vlHasLayerSetting(VlLayerSettingSet layerSettingSet, const char *pSetti
assert(pSettingName);
assert(!std::string(pSettingName).empty());

vl::LayerSettings *layer_setting_set = (vl::LayerSettings *)layerSettingSet;
vl::LayerSettings *layer_setting_set = reinterpret_cast<vl::LayerSettings *>(layerSettingSet);

const bool has_env_setting = layer_setting_set->HasEnvSetting(pSettingName);
const bool has_file_setting = layer_setting_set->HasFileSetting(pSettingName);
Expand All @@ -79,7 +79,7 @@ VkResult vlGetLayerSettingValues(VlLayerSettingSet layerSettingSet, const char *
return VK_ERROR_UNKNOWN;
}

vl::LayerSettings *layer_setting_set = (vl::LayerSettings *)layerSettingSet;
vl::LayerSettings *layer_setting_set = reinterpret_cast<vl::LayerSettings *>(layerSettingSet);

// First: search in the environment variables
const std::string &env_setting_list = layer_setting_set->GetEnvSetting(pSettingName);
Expand Down Expand Up @@ -589,9 +589,9 @@ VkResult vlGetLayerSettingValues(VlLayerSettingSet layerSettingSet, const char *
break;
case VK_LAYER_SETTING_TYPE_UINT32_EXT:
for (std::size_t i = 0, n = settings_cache.size(); i < n; ++i) {
const VlFrameset *asFramesets = static_cast<const VlFrameset *>(api_setting->pValues);
settings_cache[i] = vl::FormatString("%d-%d-%d",
asFramesets[i].first, asFramesets[i].count, asFramesets[i].step);
const VlFrameset *as_framesets = static_cast<const VlFrameset *>(api_setting->pValues);
settings_cache[i] = vl::FormatString("%d-%d-%d", as_framesets[i].first, as_framesets[i].count,
as_framesets[i].step);
}
break;
default:
Expand Down
6 changes: 3 additions & 3 deletions src/layer/vk_layer_settings_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ static std::string Merge(const std::vector<std::string> &strings) {

void vlGetLayerSettingValue(VlLayerSettingSet layerSettingSet, const char *pSettingName, bool &settingValue) {
uint32_t value_count = 1;
VkBool32 pValues;
vlGetLayerSettingValues(layerSettingSet, pSettingName, VL_LAYER_SETTING_TYPE_BOOL32, &value_count, &pValues);
settingValue = pValues == VK_TRUE;
VkBool32 p_values;
vlGetLayerSettingValues(layerSettingSet, pSettingName, VL_LAYER_SETTING_TYPE_BOOL32, &value_count, &p_values);
settingValue = p_values == VK_TRUE;
}

void vlGetLayerSettingValues(VlLayerSettingSet layerSettingSet, const char *pSettingName, std::vector<bool> &settingValues) {
Expand Down
Loading