mirror of
https://github.com/KhronosGroup/Vulkan-Utility-Libraries.git
synced 2025-05-15 09:18:49 +00:00
Initial cmake to build the LayerUtils lib and tests
This commit is contained in:
parent
d9f5dd7466
commit
a41380f9fb
10 changed files with 888 additions and 25 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ __pycache__
|
||||||
build
|
build
|
||||||
.vscode/
|
.vscode/
|
||||||
**/.*.swp
|
**/.*.swp
|
||||||
|
external
|
34
BUILD.md
34
BUILD.md
|
@ -0,0 +1,34 @@
|
||||||
|
# Build Instructions
|
||||||
|
This document contains the instructions for building this repository on Linux, macOS and Windows.
|
||||||
|
|
||||||
|
## Getting Started Build Instructions
|
||||||
|
|
||||||
|
### 64-bit Windows Build
|
||||||
|
```
|
||||||
|
git clone git@github.com:KhronosGroup/Vulkan-Profiles.git
|
||||||
|
cd Vulkan-Profiles
|
||||||
|
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Debug -D UPDATE_DEPS=ON -A x64
|
||||||
|
cmake --build . --config Debug
|
||||||
|
```
|
||||||
|
|
||||||
|
### Windows Unit Tests
|
||||||
|
|
||||||
|
```
|
||||||
|
cd build/
|
||||||
|
ctest -C Debug --output-on-failure --parallel 16
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux and macOS Build
|
||||||
|
```
|
||||||
|
git clone git@github.com:KhronosGroup/Vulkan-Profiles.git
|
||||||
|
cd Vulkan-Profiles
|
||||||
|
cmake -S . -B build/ -D CMAKE_BUILD_TYPE=Debug -D UPDATE_DEPS=ON
|
||||||
|
cmake --build .
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux and macOS Unit Tests
|
||||||
|
|
||||||
|
```
|
||||||
|
cd build/
|
||||||
|
ctest --parallel 8 --output-on-failure
|
||||||
|
```
|
|
@ -0,0 +1,72 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023-2023 Valve Corporation
|
||||||
|
# Copyright (c) 2023-2023 LunarG, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.17.2)
|
||||||
|
|
||||||
|
project(VULKAN_UTILITY_LIBRARIES LANGUAGES CXX)
|
||||||
|
|
||||||
|
include(GNUInstallDirs)
|
||||||
|
|
||||||
|
option(UTILITY_LIBRARIES_BUILD_TESTS "Build utility libraries tests" ON)
|
||||||
|
|
||||||
|
set(UTILITY_LIBRARIES_CPP_STANDARD 17 CACHE STRING "Set the C++ standard to build against.")
|
||||||
|
set(CMAKE_CXX_STANDARD ${UTILITY_LIBRARIES_CPP_STANDARD})
|
||||||
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
|
||||||
|
set(CMAKE_VISIBILITY_INLINES_HIDDEN "YES")
|
||||||
|
|
||||||
|
find_package(PythonInterp 3.7.2 REQUIRED)
|
||||||
|
|
||||||
|
add_subdirectory(scripts)
|
||||||
|
|
||||||
|
find_package(VulkanHeaders REQUIRED CONFIG QUIET)
|
||||||
|
|
||||||
|
if(UTILITY_LIBRARIES_BUILD_TESTS)
|
||||||
|
enable_testing()
|
||||||
|
find_package(GTest REQUIRED CONFIG)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Enable GUI folders
|
||||||
|
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
|
||||||
|
|
||||||
|
# NOTE: The idiom for open source projects is to not enable warnings as errors.
|
||||||
|
# This reduces problems for users who simply want to build the repository.
|
||||||
|
option(BUILD_WERROR "Treat compiler warnings as errors")
|
||||||
|
if (BUILD_WERROR)
|
||||||
|
add_compile_options("$<IF:$<CXX_COMPILER_ID:MSVC>,/WX,-Werror>")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# Platform-specific compiler switches
|
||||||
|
if(${CMAKE_C_COMPILER_ID} MATCHES "(GNU|Clang)")
|
||||||
|
add_compile_options(-Werror)
|
||||||
|
elseif(MSVC)
|
||||||
|
add_compile_options(/W4 /WX)
|
||||||
|
add_link_options(/WX)
|
||||||
|
# Ignore some warnings that we know we'll generate. In the future the
|
||||||
|
# code that generates these warnings should be fixed properly.
|
||||||
|
# vk_loader_platform.h provokes:
|
||||||
|
# warning C4505: unreferenced local function has been removed
|
||||||
|
# gtest.h provokes:
|
||||||
|
# warning C4389: '==': signed/unsigned mismatch
|
||||||
|
# warning C4018: '>=': signed/unsigned mismatch
|
||||||
|
add_compile_options(/wd4505 /wd4389 /wd4018)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
add_subdirectory(layer_utils)
|
||||||
|
|
31
layer_utils/CMakeLists.txt
Normal file
31
layer_utils/CMakeLists.txt
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
#
|
||||||
|
# Copyright (c) 2023-2023 Valve Corporation
|
||||||
|
# Copyright (c) 2023-2023 LunarG, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#
|
||||||
|
|
||||||
|
add_library(VulkanLayerUtils STATIC)
|
||||||
|
target_sources(VulkanLayerUtils PRIVATE
|
||||||
|
vk_layer_settings.cpp
|
||||||
|
vk_layer_settings.h
|
||||||
|
)
|
||||||
|
target_link_Libraries(VulkanLayerUtils PRIVATE Vulkan::Headers)
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
target_compile_definitions(VulkanLayerUtils PUBLIC _CRT_SECURE_NO_WARNINGS)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(UTILITY_LIBRARIES_BUILD_TESTS)
|
||||||
|
add_subdirectory(tests)
|
||||||
|
endif()
|
16
layer_utils/tests/CMakeLists.txt
Normal file
16
layer_utils/tests/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
|
set(test_libraries GTest::gtest GTest::gtest_main Vulkan::Headers VulkanLayerUtils)
|
||||||
|
|
||||||
|
function(add_unit_test_simple NAME)
|
||||||
|
set(TEST_FILE ./${NAME}.cpp)
|
||||||
|
set(TEST_NAME VulkanLayerUtils_${NAME})
|
||||||
|
|
||||||
|
add_executable(${TEST_NAME} ${TEST_FILE})
|
||||||
|
target_include_directories(${TEST_NAME} PUBLIC "${vulkan-headers_SOURCE_DIR}/include")
|
||||||
|
target_link_libraries(${TEST_NAME} PRIVATE ${test_libraries})
|
||||||
|
add_dependencies(${TEST_NAME} VulkanLayerUtils)
|
||||||
|
add_test(NAME ${TEST_NAME} COMMAND ${TEST_NAME} --gtest_catch_exceptions=0)
|
||||||
|
set_target_properties(${TEST_NAME} PROPERTIES FOLDER "VulkanLayerUtils-Tests")
|
||||||
|
endfunction(add_unit_test_simple)
|
||||||
|
|
||||||
|
add_unit_test_simple(test_util)
|
29
layer_utils/tests/test_util.cpp
Normal file
29
layer_utils/tests/test_util.cpp
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2023-2023 Valve Corporation
|
||||||
|
* Copyright (c) 2023-2023 LunarG, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* - Christophe Riccio <christophe@lunarg.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "../vk_layer_settings.h"
|
||||||
|
|
||||||
|
TEST(test_library_util, Something) {
|
||||||
|
EXPECT_TRUE(true);
|
||||||
|
EXPECT_FALSE(vku::IsLayerSetting("layer_name", "setting_key"));
|
||||||
|
}
|
632
layer_utils/vk_layer_settings.cpp
Normal file
632
layer_utils/vk_layer_settings.cpp
Normal file
|
@ -0,0 +1,632 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015-2022 The Khronos Group Inc.
|
||||||
|
* Copyright (c) 2015-2022 Valve Corporation
|
||||||
|
* Copyright (c) 2015-2022 LunarG, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* - Christophe Riccio <christophe@lunarg.com>
|
||||||
|
* - Mark Lobodzinski <mark@lunarg.com>
|
||||||
|
* - Jon Ashburn
|
||||||
|
* - Courtney Goeltzenleuchter
|
||||||
|
* - Tobin Ehlis
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "vk_layer_settings.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstdarg>
|
||||||
|
#include <fstream>
|
||||||
|
#include <array>
|
||||||
|
#include <map>
|
||||||
|
#include <sstream>
|
||||||
|
#include <regex>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
|
||||||
|
#include <vulkan/vk_layer.h>
|
||||||
|
|
||||||
|
#if defined(_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#include <direct.h>
|
||||||
|
#define GetCurrentDir _getcwd
|
||||||
|
#else
|
||||||
|
#include <unistd.h>
|
||||||
|
#define GetCurrentDir getcwd
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
#include <sys/system_properties.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace vku {
|
||||||
|
|
||||||
|
static std::string format(const char *message, ...) {
|
||||||
|
std::size_t const STRING_BUFFER(4096);
|
||||||
|
|
||||||
|
assert(message != nullptr);
|
||||||
|
assert(strlen(message) >= 0 && strlen(message) < STRING_BUFFER);
|
||||||
|
|
||||||
|
char buffer[STRING_BUFFER];
|
||||||
|
va_list list;
|
||||||
|
|
||||||
|
va_start(list, message);
|
||||||
|
vsnprintf(buffer, STRING_BUFFER, message, list);
|
||||||
|
va_end(list);
|
||||||
|
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsFrames(const std::string &s) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsNumber(const std::string &s) {
|
||||||
|
static const std::regex FRAME_REGEX("^-?[0-9]*$");
|
||||||
|
|
||||||
|
return std::regex_search(s, FRAME_REGEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsFloat(const std::string &s) {
|
||||||
|
static const std::regex FRAME_REGEX("^-?[0-9]*([.][0-9]*)?$");
|
||||||
|
|
||||||
|
return std::regex_search(s, FRAME_REGEX);
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Source {
|
||||||
|
SOURCE_VKCONFIG,
|
||||||
|
SOURCE_ENV_VAR,
|
||||||
|
SOURCE_LOCAL,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SettingsFileInfo {
|
||||||
|
SettingsFileInfo() : file_found(false), source(SOURCE_LOCAL) {}
|
||||||
|
|
||||||
|
bool file_found;
|
||||||
|
std::string location;
|
||||||
|
Source source;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LayerSettings {
|
||||||
|
public:
|
||||||
|
LayerSettings();
|
||||||
|
~LayerSettings(){};
|
||||||
|
|
||||||
|
void SetCallback(LAYER_SETTING_LOG_CALLBACK callback) { this->callback_ = callback; }
|
||||||
|
void Log(const std::string &setting_key, const std::string &message);
|
||||||
|
|
||||||
|
bool Is(const std::string &setting_key);
|
||||||
|
const char *Get(const std::string &setting_key);
|
||||||
|
void Set(const std::string &setting_key, const std::string &setting_value);
|
||||||
|
|
||||||
|
std::string vk_layer_disables_env_var;
|
||||||
|
SettingsFileInfo settings_info;
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool file_is_parsed_;
|
||||||
|
std::map<std::string, std::string> value_map_;
|
||||||
|
|
||||||
|
std::string last_log_setting;
|
||||||
|
std::string last_log_message;
|
||||||
|
|
||||||
|
std::string FindSettings();
|
||||||
|
void ParseFile(const char *filename);
|
||||||
|
LAYER_SETTING_LOG_CALLBACK callback_;
|
||||||
|
};
|
||||||
|
|
||||||
|
static LayerSettings vk_layer_settings;
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
std::string GetAndroidProperty(const char* name) {
|
||||||
|
std::string output;
|
||||||
|
const prop_info* pi = __system_property_find(name);
|
||||||
|
if (pi) {
|
||||||
|
__system_property_read_callback(
|
||||||
|
pi,
|
||||||
|
[](void* cookie, const char* name, const char* value, uint32_t serial) {
|
||||||
|
reinterpret_cast<std::string*>(cookie)->assign(value);
|
||||||
|
},
|
||||||
|
reinterpret_cast<void*>(&output));
|
||||||
|
}
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static bool IsEnvironment(const char *variable) {
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
return !GetAndroidProperty(variable).empty();
|
||||||
|
#else
|
||||||
|
return std::getenv(variable) != NULL;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string GetEnvironment(const char *variable) {
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
return GetAndroidProperty(variable);
|
||||||
|
#else
|
||||||
|
const char *output = std::getenv(variable);
|
||||||
|
return output == NULL ? "" : output;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string string_tolower(const std::string &s) {
|
||||||
|
std::string result = s;
|
||||||
|
for (auto &c : result) {
|
||||||
|
c = (char) std::tolower(c);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string string_toupper(const std::string &s) {
|
||||||
|
std::string result = s;
|
||||||
|
for (auto &c : result) {
|
||||||
|
c = (char) std::toupper(c);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *GetLayerEnvVar(const char *setting_env) {
|
||||||
|
vk_layer_settings.vk_layer_disables_env_var = GetEnvironment(setting_env);
|
||||||
|
return vk_layer_settings.vk_layer_disables_env_var.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string TrimPrefix(const std::string &layer_key) {
|
||||||
|
std::string key {};
|
||||||
|
if (layer_key.find("VK_LAYER_") == 0) {
|
||||||
|
std::size_t prefix = std::strlen("VK_LAYER_");
|
||||||
|
key = layer_key.substr(prefix, layer_key.size() - prefix);
|
||||||
|
} else {
|
||||||
|
key = layer_key;
|
||||||
|
}
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string GetSettingKey(const char *layer_key, const char *setting_key) {
|
||||||
|
std::stringstream result;
|
||||||
|
result << string_tolower(TrimPrefix(layer_key)) << "." << setting_key;
|
||||||
|
return result.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::string TrimVendor(const std::string &layer_key) {
|
||||||
|
static const char *separator = "_";
|
||||||
|
|
||||||
|
const std::string &namespace_key = TrimPrefix(layer_key);
|
||||||
|
|
||||||
|
const auto trimmed_beg = namespace_key.find_first_of(separator);
|
||||||
|
if (trimmed_beg == std::string::npos) return namespace_key;
|
||||||
|
|
||||||
|
assert(namespace_key.find_last_not_of(separator) != std::string::npos &&
|
||||||
|
trimmed_beg <= namespace_key.find_last_not_of(separator));
|
||||||
|
|
||||||
|
return namespace_key.substr(trimmed_beg + 1, namespace_key.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
enum TrimMode {
|
||||||
|
TRIM_NONE,
|
||||||
|
TRIM_VENDOR,
|
||||||
|
TRIM_NAMESPACE,
|
||||||
|
|
||||||
|
TRIM_FIRST = TRIM_NONE,
|
||||||
|
TRIM_LAST = TRIM_NAMESPACE,
|
||||||
|
};
|
||||||
|
|
||||||
|
static std::string GetEnvVarKey(const char *layer_key, const char *setting_key, TrimMode trim_mode) {
|
||||||
|
std::stringstream result;
|
||||||
|
|
||||||
|
#if defined(__ANDROID__)
|
||||||
|
switch (trim_mode) {
|
||||||
|
default:
|
||||||
|
case TRIM_NONE: {
|
||||||
|
result << "debug.vulkan." << GetSettingKey(layer_key, setting_key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TRIM_VENDOR: {
|
||||||
|
result << "debug.vulkan." << GetSettingKey(TrimVendor(layer_key).c_str(), setting_key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TRIM_NAMESPACE: {
|
||||||
|
result << "debug.vulkan." << setting_key;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
switch (trim_mode) {
|
||||||
|
default:
|
||||||
|
case TRIM_NONE: {
|
||||||
|
result << "VK_" << string_toupper(TrimPrefix(layer_key)) << "_" << string_toupper(setting_key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TRIM_VENDOR: {
|
||||||
|
result << "VK_" << string_toupper(TrimVendor(layer_key)) << "_" << string_toupper(setting_key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TRIM_NAMESPACE: {
|
||||||
|
result << "VK_" << string_toupper(setting_key);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
return result.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InitLayerSettingsLogCallback(LAYER_SETTING_LOG_CALLBACK callback) {
|
||||||
|
vk_layer_settings.SetCallback(callback);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsLayerSetting(const char *layer_key, const char *setting_key) {
|
||||||
|
assert(layer_key);
|
||||||
|
assert(!std::string(layer_key).empty());
|
||||||
|
assert(setting_key);
|
||||||
|
assert(!std::string(setting_key).empty());
|
||||||
|
|
||||||
|
for (int i = TRIM_FIRST, n = TRIM_LAST; i <= n; ++i) {
|
||||||
|
if (IsEnvironment(GetEnvVarKey(layer_key, setting_key, static_cast<TrimMode>(i)).c_str())) return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return vk_layer_settings.Is(GetSettingKey(layer_key, setting_key).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string GetLayerSettingData(const char *layer_key, const char *setting_key) {
|
||||||
|
// First search in the environment variables
|
||||||
|
for (int i = TRIM_FIRST, n = TRIM_LAST; i <= n; ++i) {
|
||||||
|
std::string setting = GetLayerEnvVar(GetEnvVarKey(layer_key, setting_key, static_cast<TrimMode>(i)).c_str());
|
||||||
|
if (!setting.empty()) return setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Second search in vk_layer_settings.txt
|
||||||
|
return vk_layer_settings.Get(GetSettingKey(layer_key, setting_key).c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GetLayerSettingBool(const char *layer_key, const char *setting_key) {
|
||||||
|
assert(IsLayerSetting(layer_key, setting_key));
|
||||||
|
|
||||||
|
bool result = false; // default value
|
||||||
|
|
||||||
|
std::string setting = string_tolower(GetLayerSettingData(layer_key, setting_key));
|
||||||
|
if (setting.empty()) {
|
||||||
|
vk_layer_settings.Log(setting_key,
|
||||||
|
"The setting is used but the value is empty which is invalid for a boolean setting type.");
|
||||||
|
} else if (IsNumber(setting)) {
|
||||||
|
result = std::atoi(setting.c_str()) != 0;
|
||||||
|
} else if (setting == "true" || setting == "false") {
|
||||||
|
result = setting == "true";
|
||||||
|
} else {
|
||||||
|
std::string message = format("The data provided (%s) is not a boolean value.", setting.c_str());
|
||||||
|
vk_layer_settings.Log(setting_key, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetLayerSettingInt(const char *layer_key, const char *setting_key) {
|
||||||
|
assert(IsLayerSetting(layer_key, setting_key));
|
||||||
|
|
||||||
|
int result = 0; // default value
|
||||||
|
|
||||||
|
std::string setting = GetLayerSettingData(layer_key, setting_key);
|
||||||
|
if (setting.empty()) {
|
||||||
|
std::string message = "The setting is used but the value is empty which is invalid for a integer setting type.";
|
||||||
|
vk_layer_settings.Log(setting_key, message);
|
||||||
|
} else if (!IsNumber(setting)) {
|
||||||
|
std::string message = format("The data provided (%s) is not an integer value.", setting.c_str());
|
||||||
|
vk_layer_settings.Log(setting_key, message);
|
||||||
|
} else {
|
||||||
|
result = std::atoi(setting.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
double GetLayerSettingFloat(const char *layer_key, const char *setting_key) {
|
||||||
|
assert(IsLayerSetting(layer_key, setting_key));
|
||||||
|
|
||||||
|
double result = 0.0; // default value
|
||||||
|
|
||||||
|
std::string setting = GetLayerSettingData(layer_key, setting_key);
|
||||||
|
if (setting.empty()) {
|
||||||
|
std::string message = "The setting is used but the value is empty which is invalid for a floating-point setting type.";
|
||||||
|
vk_layer_settings.Log(setting_key, message);
|
||||||
|
} else if (!IsFloat(setting)) {
|
||||||
|
std::string message = format("The data provided (%s) is not a floating-point value.", setting.c_str());
|
||||||
|
vk_layer_settings.Log(setting_key, message);
|
||||||
|
} else {
|
||||||
|
result = std::atof(setting.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetLayerSettingString(const char *layer_key, const char *setting_key) {
|
||||||
|
assert(IsLayerSetting(layer_key, setting_key));
|
||||||
|
|
||||||
|
std::string setting = GetLayerSettingData(layer_key, setting_key);
|
||||||
|
if (setting.empty()) {
|
||||||
|
std::string message = "The setting is used but the value is empty which is invalid for a string setting type.";
|
||||||
|
vk_layer_settings.Log(setting_key, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GetLayerSettingFrames(const char *layer_key, const char *setting_key) {
|
||||||
|
assert(IsLayerSetting(layer_key, setting_key));
|
||||||
|
|
||||||
|
std::string setting = GetLayerSettingData(layer_key, setting_key);
|
||||||
|
if (!setting.empty() && !IsFrames(setting)) {
|
||||||
|
std::string message = format("The data provided (%s) is not a frames value.", setting.c_str());
|
||||||
|
vk_layer_settings.Log(setting_key, message);
|
||||||
|
}
|
||||||
|
|
||||||
|
return setting;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::vector<std::string> Split(const std::string &value, const std::string &delimiter) {
|
||||||
|
std::vector<std::string> result;
|
||||||
|
|
||||||
|
std::string parse = value;
|
||||||
|
|
||||||
|
std::size_t start = 0;
|
||||||
|
std::size_t end = parse.find(delimiter);
|
||||||
|
while (end != std::string::npos) {
|
||||||
|
result.push_back(parse.substr(start, end - start));
|
||||||
|
start = end + delimiter.length();
|
||||||
|
end = parse.find(delimiter, start);
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string last = parse.substr(start, end);
|
||||||
|
if (!last.empty()) {
|
||||||
|
result.push_back(last);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Strings GetLayerSettingStrings(const char *layer_key, const char *setting_key) {
|
||||||
|
assert(IsLayerSetting(layer_key, setting_key));
|
||||||
|
|
||||||
|
std::string setting = GetLayerSettingData(layer_key, setting_key);
|
||||||
|
if (setting.find_first_of(",") != std::string::npos) {
|
||||||
|
return Split(setting, ",");
|
||||||
|
} else {
|
||||||
|
#ifdef _WIN32
|
||||||
|
const char *delimiter = ";";
|
||||||
|
#else
|
||||||
|
const char *delimiter = ":";
|
||||||
|
#endif
|
||||||
|
return Split(setting, delimiter);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List GetLayerSettingList(const char *layer_key, const char *setting_key) {
|
||||||
|
assert(IsLayerSetting(layer_key, setting_key));
|
||||||
|
|
||||||
|
std::vector<std::string> inputs = GetLayerSettingStrings(layer_key, setting_key);
|
||||||
|
|
||||||
|
List result;
|
||||||
|
for (std::size_t i = 0, n = inputs.size(); i < n; ++i) {
|
||||||
|
std::pair<std::string, int> value;
|
||||||
|
if (IsNumber(inputs[i])) {
|
||||||
|
value.second = atoi(inputs[i].c_str());
|
||||||
|
} else {
|
||||||
|
value.first = inputs[i];
|
||||||
|
}
|
||||||
|
result.push_back(value);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Constructor for ConfigFile. Initialize layers to log error messages to stdout by default. If a vk_layer_settings file is present,
|
||||||
|
// its settings will override the defaults.
|
||||||
|
LayerSettings::LayerSettings() : file_is_parsed_(false), callback_(nullptr) {}
|
||||||
|
|
||||||
|
void LayerSettings::Log(const std::string &setting_key, const std::string &message) {
|
||||||
|
this->last_log_setting = setting_key;
|
||||||
|
this->last_log_message = message;
|
||||||
|
|
||||||
|
if (this->callback_ == nullptr) {
|
||||||
|
fprintf(stderr, "LAYER SETTING (%s) error: %s\n", this->last_log_setting.c_str(), this->last_log_message.c_str());
|
||||||
|
} else {
|
||||||
|
this->callback_(this->last_log_setting.c_str(), this->last_log_message.c_str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool LayerSettings::Is(const std::string &setting_key) {
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
if (!file_is_parsed_) {
|
||||||
|
std::string settings_file = FindSettings();
|
||||||
|
ParseFile(settings_file.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return value_map_.find(setting_key) != value_map_.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *LayerSettings::Get(const std::string &setting_key) {
|
||||||
|
std::map<std::string, std::string>::const_iterator it;
|
||||||
|
if (!file_is_parsed_) {
|
||||||
|
std::string settings_file = FindSettings();
|
||||||
|
ParseFile(settings_file.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((it = value_map_.find(setting_key)) == value_map_.end()) {
|
||||||
|
return "";
|
||||||
|
} else {
|
||||||
|
return it->second.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerSettings::Set(const std::string &setting_key, const std::string &value) {
|
||||||
|
if (!file_is_parsed_) {
|
||||||
|
std::string settings_file = FindSettings();
|
||||||
|
ParseFile(settings_file.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
value_map_[setting_key] = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
// Check for admin rights
|
||||||
|
static inline bool IsHighIntegrity() {
|
||||||
|
HANDLE process_token;
|
||||||
|
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_QUERY_SOURCE, &process_token)) {
|
||||||
|
// Maximum possible size of SID_AND_ATTRIBUTES is maximum size of a SID + size of attributes DWORD.
|
||||||
|
uint8_t mandatory_label_buffer[SECURITY_MAX_SID_SIZE + sizeof(DWORD)];
|
||||||
|
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 DWORD sub_authority_count = *GetSidSubAuthorityCount(mandatory_label->Label.Sid);
|
||||||
|
const DWORD integrity_level = *GetSidSubAuthority(mandatory_label->Label.Sid, sub_authority_count - 1);
|
||||||
|
|
||||||
|
CloseHandle(process_token);
|
||||||
|
return integrity_level > SECURITY_MANDATORY_MEDIUM_RID;
|
||||||
|
}
|
||||||
|
|
||||||
|
CloseHandle(process_token);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::string LayerSettings::FindSettings() {
|
||||||
|
struct stat info;
|
||||||
|
|
||||||
|
#if defined(WIN32)
|
||||||
|
// Look for VkConfig-specific settings location specified in the windows registry
|
||||||
|
HKEY key;
|
||||||
|
|
||||||
|
const std::array<HKEY, 2> hives = {HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER};
|
||||||
|
const size_t hives_to_check_count = IsHighIntegrity() ? 1 : hives.size(); // Admin checks only the default hive
|
||||||
|
|
||||||
|
for (size_t hive_index = 0; hive_index < hives_to_check_count; ++hive_index) {
|
||||||
|
LSTATUS err = RegOpenKeyEx(hives[hive_index], "Software\\Khronos\\Vulkan\\Settings", 0, KEY_READ, &key);
|
||||||
|
if (err == ERROR_SUCCESS) {
|
||||||
|
char name[2048];
|
||||||
|
DWORD i = 0, name_size, type, value, value_size;
|
||||||
|
while (ERROR_SUCCESS == RegEnumValue(key, i++, name, &(name_size = sizeof(name)), nullptr, &type,
|
||||||
|
reinterpret_cast<LPBYTE>(&value), &(value_size = sizeof(value)))) {
|
||||||
|
// Check if the registry entry is a dword with a value of zero
|
||||||
|
if (type != REG_DWORD || value != 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this actually points to a file
|
||||||
|
if ((stat(name, &info) != 0) || !(info.st_mode & S_IFREG)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Use this file
|
||||||
|
RegCloseKey(key);
|
||||||
|
settings_info.source = SOURCE_VKCONFIG;
|
||||||
|
settings_info.location = name;
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
RegCloseKey(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
// Look for VkConfig-specific settings location specified in a specific spot in the linux settings store
|
||||||
|
std::string search_path = GetEnvironment("XDG_DATA_HOME");
|
||||||
|
if (search_path == "") {
|
||||||
|
search_path = GetEnvironment("HOME");
|
||||||
|
if (search_path != "") {
|
||||||
|
search_path += "/.local/share";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Use the vk_layer_settings.txt file from here, if it is present
|
||||||
|
if (search_path != "") {
|
||||||
|
std::string home_file = search_path + "/vulkan/settings.d/vk_layer_settings.txt";
|
||||||
|
if (stat(home_file.c_str(), &info) == 0) {
|
||||||
|
if (info.st_mode & S_IFREG) {
|
||||||
|
settings_info.source = SOURCE_VKCONFIG;
|
||||||
|
settings_info.location = home_file;
|
||||||
|
return home_file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef __ANDROID__
|
||||||
|
std::string env_path = GetEnvironment("debug.vulkan.khronos_profiles.settings_path");
|
||||||
|
#else
|
||||||
|
// Look for an environment variable override for the settings file location
|
||||||
|
std::string env_path = GetEnvironment("VK_LAYER_SETTINGS_PATH");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// If the path exists use it, else use vk_layer_settings
|
||||||
|
if (stat(env_path.c_str(), &info) == 0) {
|
||||||
|
// If this is a directory, append settings file name
|
||||||
|
if (info.st_mode & S_IFDIR) {
|
||||||
|
env_path.append("/vk_layer_settings.txt");
|
||||||
|
}
|
||||||
|
settings_info.source = SOURCE_ENV_VAR;
|
||||||
|
settings_info.location = env_path;
|
||||||
|
return env_path;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Default -- use the current working directory for the settings file location
|
||||||
|
settings_info.source = SOURCE_LOCAL;
|
||||||
|
char buff[512];
|
||||||
|
auto buf_ptr = GetCurrentDir(buff, 512);
|
||||||
|
if (buf_ptr) {
|
||||||
|
settings_info.location = buf_ptr;
|
||||||
|
settings_info.location.append("/vk_layer_settings.txt");
|
||||||
|
}
|
||||||
|
return "vk_layer_settings.txt";
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline std::string TrimWhitespace(const std::string &s) {
|
||||||
|
const char *whitespace = " \t\f\v\n\r";
|
||||||
|
|
||||||
|
const auto trimmed_beg = s.find_first_not_of(whitespace);
|
||||||
|
if (trimmed_beg == std::string::npos) return "";
|
||||||
|
|
||||||
|
const auto trimmed_end = s.find_last_not_of(whitespace);
|
||||||
|
assert(trimmed_end != std::string::npos && trimmed_beg <= trimmed_end);
|
||||||
|
|
||||||
|
return s.substr(trimmed_beg, trimmed_end - trimmed_beg + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LayerSettings::ParseFile(const char *filename) {
|
||||||
|
file_is_parsed_ = true;
|
||||||
|
|
||||||
|
// Extract option = value pairs from a file
|
||||||
|
std::ifstream file(filename);
|
||||||
|
if (file.good()) {
|
||||||
|
settings_info.file_found = true;
|
||||||
|
for (std::string line; std::getline(file, line);) {
|
||||||
|
// discard comments, which start with '#'
|
||||||
|
const auto comments_pos = line.find_first_of('#');
|
||||||
|
if (comments_pos != std::string::npos) line.erase(comments_pos);
|
||||||
|
|
||||||
|
const auto value_pos = line.find_first_of('=');
|
||||||
|
if (value_pos != std::string::npos) {
|
||||||
|
const std::string setting_key = TrimWhitespace(line.substr(0, value_pos));
|
||||||
|
const std::string setting_value = TrimWhitespace(line.substr(value_pos + 1));
|
||||||
|
value_map_[setting_key] = setting_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace vku
|
63
layer_utils/vk_layer_settings.h
Normal file
63
layer_utils/vk_layer_settings.h
Normal file
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2015-2022 The Khronos Group Inc.
|
||||||
|
* Copyright (c) 2015-2022 Valve Corporation
|
||||||
|
* Copyright (c) 2015-2022 LunarG, Inc.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*
|
||||||
|
* Authors:
|
||||||
|
* - Christophe Riccio <christophe@lunarg.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <vulkan/vk_layer.h>
|
||||||
|
#include <vulkan/vulkan.h>
|
||||||
|
|
||||||
|
namespace vku {
|
||||||
|
|
||||||
|
typedef std::vector<std::string> Strings;
|
||||||
|
typedef std::vector<std::pair<std::string, int>> List;
|
||||||
|
typedef void *(*LAYER_SETTING_LOG_CALLBACK)(const char *setting_key, const char *message);
|
||||||
|
|
||||||
|
// Initialize the callback function to get error messages. By default the error messages are outputed to stderr. Use nullptr to
|
||||||
|
// return to the default behavior.
|
||||||
|
void InitLayerSettingsLogCallback(LAYER_SETTING_LOG_CALLBACK callback);
|
||||||
|
|
||||||
|
// Check whether a setting was set either from vk_layer_settings.txt or an environment variable
|
||||||
|
bool IsLayerSetting(const char *layer_key, const char *setting_key);
|
||||||
|
|
||||||
|
// Query setting data for BOOL setting type in the layer manifest
|
||||||
|
bool GetLayerSettingBool(const char *layer_key, const char *setting_key);
|
||||||
|
|
||||||
|
// Query setting data for INT setting type in the layer manifest
|
||||||
|
int GetLayerSettingInt(const char *layer_key, const char *setting_key);
|
||||||
|
|
||||||
|
// Query setting data for FLOAT setting type in the layer manifest
|
||||||
|
double GetLayerSettingFloat(const char *layer_key, const char *setting_key);
|
||||||
|
|
||||||
|
// Query setting data for FRAMES setting type in the layer manifest
|
||||||
|
std::string GetLayerSettingFrames(const char *layer_key, const char *setting_key);
|
||||||
|
|
||||||
|
// Query setting data for STRING, ENUM, LOAD_FILE, SAVE_FILE and SAVE_FOLDER setting types in the layer manifest
|
||||||
|
std::string GetLayerSettingString(const char *layer_key, const char *setting_key);
|
||||||
|
|
||||||
|
// Query setting data for FLAGS setting type in the layer manifest
|
||||||
|
Strings GetLayerSettingStrings(const char *layer_key, const char *setting_key);
|
||||||
|
|
||||||
|
// Query setting data for LIST setting type in the layer manifest
|
||||||
|
List GetLayerSettingList(const char *layer_key, const char *setting_key);
|
||||||
|
} // namespace vku
|
|
@ -34,13 +34,8 @@ if (UPDATE_DEPS)
|
||||||
set(_build_type ${CMAKE_BUILD_TYPE})
|
set(_build_type ${CMAKE_BUILD_TYPE})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message("********************************************************************************")
|
|
||||||
message("* NOTE: Adding target vvl_update_deps to run as needed for updating *")
|
|
||||||
message("* dependencies. *")
|
|
||||||
message("********************************************************************************")
|
|
||||||
|
|
||||||
set(optional_args)
|
set(optional_args)
|
||||||
if (NOT BUILD_TESTS)
|
if (NOT UTILITY_LIBRARIES_BUILD_TESTS)
|
||||||
set(optional_args "--optional=tests")
|
set(optional_args "--optional=tests")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
@ -53,39 +48,29 @@ if (UPDATE_DEPS)
|
||||||
set(optional_args ${optional_args} "CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}")
|
set(optional_args ${optional_args} "CMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE}")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(_update_deps_dir ${VVL_SOURCE_DIR}/external/${_build_type})
|
|
||||||
if (UPDATE_DEPS_DIR)
|
|
||||||
set(_update_deps_dir ${UPDATE_DEPS_DIR})
|
|
||||||
endif()
|
|
||||||
set(_helper_file "${_update_deps_dir}/helper.cmake")
|
|
||||||
|
|
||||||
set(update_dep_py "${CMAKE_CURRENT_LIST_DIR}/update_deps.py")
|
|
||||||
set(known_good_json "${CMAKE_CURRENT_LIST_DIR}/known_good.json")
|
|
||||||
|
|
||||||
# Add a target so that update_deps.py will run when necessary
|
# Add a target so that update_deps.py will run when necessary
|
||||||
# NOTE: This is triggered off of the timestamps of known_good.json and helper.cmake
|
# NOTE: This is triggered off of the timestamps of known_good.json and helper.cmake
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${_helper_file}
|
OUTPUT ${PROJECT_SOURCE_DIR}/external/helper.cmake
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${update_dep_py}
|
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/update_deps.py
|
||||||
--dir ${_update_deps_dir} --arch ${_target_arch} --config ${_build_type} --generator "${CMAKE_GENERATOR}" ${optional_args}
|
--dir ${PROJECT_SOURCE_DIR}/external --arch ${_target_arch} --config ${_build_type} --generator "${CMAKE_GENERATOR}" ${optional_args}
|
||||||
DEPENDS ${known_good_json}
|
DEPENDS ${CMAKE_CURRENT_LIST_DIR}/known_good.json
|
||||||
)
|
)
|
||||||
|
|
||||||
add_custom_target(vvl_update_deps ALL DEPENDS ${_helper_file})
|
|
||||||
|
|
||||||
# Check if update_deps.py needs to be run on first cmake run
|
# Check if update_deps.py needs to be run on first cmake run
|
||||||
if (${known_good_json} IS_NEWER_THAN ${_helper_file})
|
if (${CMAKE_CURRENT_LIST_DIR}/known_good.json IS_NEWER_THAN ${PROJECT_SOURCE_DIR}/external/helper.cmake)
|
||||||
execute_process(
|
execute_process(
|
||||||
COMMAND ${PYTHON_EXECUTABLE} ${update_dep_py}
|
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_LIST_DIR}/update_deps.py
|
||||||
--dir ${_update_deps_dir} --arch ${_target_arch} --config ${_build_type} --generator "${CMAKE_GENERATOR}" ${optional_args}
|
--dir ${PROJECT_SOURCE_DIR}/external --arch ${_target_arch} --config ${_build_type} --generator "${CMAKE_GENERATOR}" ${optional_args}
|
||||||
WORKING_DIRECTORY ${VVL_SOURCE_DIR}
|
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
|
||||||
RESULT_VARIABLE _update_deps_result
|
RESULT_VARIABLE _update_deps_result
|
||||||
)
|
)
|
||||||
if (NOT (${_update_deps_result} EQUAL 0))
|
if (NOT (${_update_deps_result} EQUAL 0))
|
||||||
message(FATAL_ERROR "Could not run update_deps.py which is necessary to download dependencies.")
|
message(FATAL_ERROR "Could not run update_deps.py which is necessary to download dependencies.")
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
include(${_helper_file})
|
include(${PROJECT_SOURCE_DIR}/external/helper.cmake)
|
||||||
else()
|
else()
|
||||||
message("********************************************************************************")
|
message("********************************************************************************")
|
||||||
message("* NOTE: Not adding target to run update_deps.py automatically. *")
|
message("* NOTE: Not adding target to run update_deps.py automatically. *")
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue