summaryrefslogtreecommitdiffstats
path: root/BuildTools
diff options
context:
space:
mode:
authorEgor Yusov <egor.yusov@gmail.com>2019-11-25 16:34:35 +0000
committerEgor Yusov <egor.yusov@gmail.com>2019-11-25 16:48:32 +0000
commit13a9ae2a88d1cef3787215b5ff5966ce60b5cedd (patch)
tree254c67f9742241fba9a3c75aa7b8b23b8e526ef5 /BuildTools
parentCMake: updated Diligent-ValidateFormatting target to run every time (diff)
downloadDiligentCore-13a9ae2a88d1cef3787215b5ff5966ce60b5cedd.tar.gz
DiligentCore-13a9ae2a88d1cef3787215b5ff5966ce60b5cedd.zip
Renamed Utilities folder to BuildTools
Diffstat (limited to 'BuildTools')
-rw-r--r--BuildTools/CMakeLists.txt3
-rw-r--r--BuildTools/File2Include/.gitignore1
-rw-r--r--BuildTools/File2Include/CMakeLists.txt60
-rw-r--r--BuildTools/File2Include/File2String.cpp63
-rw-r--r--BuildTools/File2Include/bin/Linux/File2Stringbin0 -> 12856 bytes
-rw-r--r--BuildTools/File2Include/bin/MacOS/File2Stringbin0 -> 13068 bytes
-rw-r--r--BuildTools/File2Include/bin/Win32/x32/File2String.exebin0 -> 120832 bytes
-rw-r--r--BuildTools/File2Include/bin/Win32/x64/File2String.exebin0 -> 143872 bytes
-rw-r--r--BuildTools/FormatValidation/clang-format-validate-license21
-rw-r--r--BuildTools/FormatValidation/clang-format-validate.py383
-rw-r--r--BuildTools/FormatValidation/clang-format_10.0.0.exebin0 -> 3663872 bytes
-rw-r--r--BuildTools/FormatValidation/validate_format_win.bat5
12 files changed, 536 insertions, 0 deletions
diff --git a/BuildTools/CMakeLists.txt b/BuildTools/CMakeLists.txt
new file mode 100644
index 00000000..8d20e25d
--- /dev/null
+++ b/BuildTools/CMakeLists.txt
@@ -0,0 +1,3 @@
+cmake_minimum_required (VERSION 3.3)
+
+add_subdirectory(File2Include)
diff --git a/BuildTools/File2Include/.gitignore b/BuildTools/File2Include/.gitignore
new file mode 100644
index 00000000..f5135fa6
--- /dev/null
+++ b/BuildTools/File2Include/.gitignore
@@ -0,0 +1 @@
+!bin \ No newline at end of file
diff --git a/BuildTools/File2Include/CMakeLists.txt b/BuildTools/File2Include/CMakeLists.txt
new file mode 100644
index 00000000..8bf6e8c9
--- /dev/null
+++ b/BuildTools/File2Include/CMakeLists.txt
@@ -0,0 +1,60 @@
+cmake_minimum_required (VERSION 3.6)
+
+if(PLATFORM_WIN32 OR PLATFORM_LINUX OR PLATFORM_MACOS)
+ project(File2Include)
+
+ set(SOURCE
+ File2String.cpp
+ )
+
+ add_executable(File2String ${SOURCE})
+ target_compile_features(File2String PRIVATE cxx_std_11)
+
+ if(PLATFORM_WIN32)
+ if(MSVC)
+ set(MSVC_DBG_COMPILE_OPTIONS /MTd)
+ set(MSVC_REL_COMPILE_OPTIONS /MT)
+ target_compile_options(File2String PRIVATE /wd4996)
+ foreach(DBG_CONFIG ${DEBUG_CONFIGURATIONS})
+ target_compile_options(File2String PRIVATE "$<$<CONFIG:${DBG_CONFIG}>:${MSVC_DBG_COMPILE_OPTIONS}>")
+ endforeach()
+
+ foreach(REL_CONFIG ${RELEASE_CONFIGURATIONS})
+ target_compile_options(File2String PRIVATE "$<$<CONFIG:${REL_CONFIG}>:${MSVC_REL_COMPILE_OPTIONS}>")
+ endforeach()
+ endif()
+ set(DST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/bin/Win32/x${ARCH}/")
+ elseif(PLATFORM_LINUX)
+ set(DST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/bin/Linux/")
+ elseif(PLATFORM_MACOS)
+ set(DST_DIR "${CMAKE_CURRENT_SOURCE_DIR}/bin/MacOS/")
+ endif()
+ source_group("source" FILES ${SOURCE})
+
+ set_target_properties(File2String PROPERTIES
+ FOLDER DiligentCore/BuildTools
+ )
+
+ # When setting RUNTIME_OUTPUT_DIRECTORY_RELEASE to DST_DIR,
+ # the executable is deleted by the clean build command
+ add_custom_command(TARGET File2String POST_BUILD
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different
+ "\"$<TARGET_FILE:File2String>\""
+ # In release build, copy to the destination folder
+ # In all other configurations, do nothing by copying to the same target folder
+ $<IF:$<CONFIG:RELEASE>,${DST_DIR},$<TARGET_FILE_DIR:File2String>>
+ )
+endif()
+
+if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+ # Use prebuilt 32-bit version
+ set(FILE2STRING_PATH "${CMAKE_CURRENT_SOURCE_DIR}/bin/Win32/x32/File2String.exe" CACHE INTERNAL "File2String utility")
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux")
+ # Use prebuilt version
+ set(FILE2STRING_PATH "${CMAKE_CURRENT_SOURCE_DIR}/bin/Linux/File2String" CACHE INTERNAL "File2String utility")
+elseif(CMAKE_HOST_SYSTEM_NAME STREQUAL "Darwin")
+ # Use prebuilt version
+ set(FILE2STRING_PATH "${CMAKE_CURRENT_SOURCE_DIR}/bin/MacOS/File2String" CACHE INTERNAL "File2String utility")
+else()
+ set(FILE2STRING_PATH "" CACHE INTERNAL "File2String utility unavailable on this host system")
+endif()
diff --git a/BuildTools/File2Include/File2String.cpp b/BuildTools/File2Include/File2String.cpp
new file mode 100644
index 00000000..04463a1b
--- /dev/null
+++ b/BuildTools/File2Include/File2String.cpp
@@ -0,0 +1,63 @@
+// File2Include.cpp : Defines the entry point for the console application.
+//
+
+#include <stdio.h>
+#include <string.h>
+
+int main(int argc, char* argv[])
+{
+ if( argc < 3 )
+ {
+ printf( "Incorrect number of command line arguments. Expected arguments: src file, dst file\n");
+ return -1;
+ }
+ auto SrcFile = argv[1];
+ auto DstFile = argv[2];
+ if (strcmp(SrcFile, DstFile) == 0)
+ {
+ printf( "Source and destination files must be different\n");
+ return -1;
+ }
+
+ FILE *pSrcFile = fopen( SrcFile, "r" );
+ if( pSrcFile == nullptr )
+ {
+ printf( "Failed to open source file %s\n", SrcFile );
+ return -1;
+ }
+
+ FILE *pDstFile = fopen( DstFile, "w" );
+ if( pDstFile == nullptr )
+ {
+ printf( "Failed to open destination file %s\n", DstFile );
+ fclose(pSrcFile);
+ return -1;
+ }
+
+
+ char Buff[2048];
+ char SpecialChars[] = "\'\"\\";
+ while( !feof( pSrcFile ) )
+ {
+ auto* Line = fgets( Buff, sizeof( Buff )/sizeof(Buff[0]) , pSrcFile );
+ if( Line == nullptr )
+ break;
+ fputc( '\"', pDstFile );
+ auto* CurrChar = Line;
+ while( *CurrChar != 0 && *CurrChar != '\n' && *CurrChar != '\r' )
+ {
+ if( strchr( SpecialChars, *CurrChar) )
+ fputc( '\\', pDstFile );
+ fputc( *CurrChar, pDstFile );
+ ++CurrChar;
+ }
+ fputs( "\\n\"\n", pDstFile );
+ }
+
+ fclose(pDstFile);
+ fclose(pSrcFile);
+
+ printf( "File2String: sucessfully converted %s to %s\n", SrcFile, DstFile );
+
+ return 0;
+}
diff --git a/BuildTools/File2Include/bin/Linux/File2String b/BuildTools/File2Include/bin/Linux/File2String
new file mode 100644
index 00000000..e6e677f6
--- /dev/null
+++ b/BuildTools/File2Include/bin/Linux/File2String
Binary files differ
diff --git a/BuildTools/File2Include/bin/MacOS/File2String b/BuildTools/File2Include/bin/MacOS/File2String
new file mode 100644
index 00000000..93e4e168
--- /dev/null
+++ b/BuildTools/File2Include/bin/MacOS/File2String
Binary files differ
diff --git a/BuildTools/File2Include/bin/Win32/x32/File2String.exe b/BuildTools/File2Include/bin/Win32/x32/File2String.exe
new file mode 100644
index 00000000..575caac6
--- /dev/null
+++ b/BuildTools/File2Include/bin/Win32/x32/File2String.exe
Binary files differ
diff --git a/BuildTools/File2Include/bin/Win32/x64/File2String.exe b/BuildTools/File2Include/bin/Win32/x64/File2String.exe
new file mode 100644
index 00000000..f24e2ffc
--- /dev/null
+++ b/BuildTools/File2Include/bin/Win32/x64/File2String.exe
Binary files differ
diff --git a/BuildTools/FormatValidation/clang-format-validate-license b/BuildTools/FormatValidation/clang-format-validate-license
new file mode 100644
index 00000000..e728f248
--- /dev/null
+++ b/BuildTools/FormatValidation/clang-format-validate-license
@@ -0,0 +1,21 @@
+MIT License
+
+Copyright (c) 2017 Guillaume Papin
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/BuildTools/FormatValidation/clang-format-validate.py b/BuildTools/FormatValidation/clang-format-validate.py
new file mode 100644
index 00000000..b8ad22ee
--- /dev/null
+++ b/BuildTools/FormatValidation/clang-format-validate.py
@@ -0,0 +1,383 @@
+#!/usr/bin/env python
+"""A wrapper script around clang-format, suitable for linting multiple files
+and to use for continuous integration.
+This is an alternative API for the clang-format command line.
+It runs over multiple files and directories in parallel.
+A diff output is produced and a sensible exit code is returned.
+"""
+
+from __future__ import print_function, unicode_literals
+
+import argparse
+import codecs
+import difflib
+import fnmatch
+import io
+import errno
+import multiprocessing
+import os
+import signal
+import subprocess
+import sys
+import traceback
+
+from functools import partial
+
+try:
+ from subprocess import DEVNULL # py3k
+except ImportError:
+ DEVNULL = open(os.devnull, "wb")
+
+
+DEFAULT_EXTENSIONS = 'c,h,C,H,cpp,hpp,cc,hh,c++,h++,cxx,hxx'
+DEFAULT_CLANG_FORMAT_IGNORE = '.clang-format-ignore'
+
+
+class ExitStatus:
+ SUCCESS = 0
+ DIFF = 1
+ TROUBLE = 2
+
+def excludes_from_file(ignore_file):
+ excludes = []
+ try:
+ with io.open(ignore_file, 'r', encoding='utf-8') as f:
+ for line in f:
+ if line.startswith('#'):
+ # ignore comments
+ continue
+ pattern = line.rstrip()
+ if not pattern:
+ # allow empty lines
+ continue
+ excludes.append(pattern)
+ except EnvironmentError as e:
+ if e.errno != errno.ENOENT:
+ raise
+ return excludes;
+
+def list_files(files, recursive=False, extensions=None, exclude=None):
+ if extensions is None:
+ extensions = []
+ if exclude is None:
+ exclude = []
+
+ out = []
+ for file in files:
+ if recursive and os.path.isdir(file):
+ for dirpath, dnames, fnames in os.walk(file):
+ fpaths = [os.path.join(dirpath, fname) for fname in fnames]
+ for pattern in exclude:
+ # os.walk() supports trimming down the dnames list
+ # by modifying it in-place,
+ # to avoid unnecessary directory listings.
+ dnames[:] = [
+ x for x in dnames
+ if
+ not fnmatch.fnmatch(os.path.join(dirpath, x), pattern)
+ ]
+ fpaths = [
+ x for x in fpaths if not fnmatch.fnmatch(x, pattern)
+ ]
+ for f in fpaths:
+ ext = os.path.splitext(f)[1][1:]
+ if ext in extensions:
+ out.append(f)
+ else:
+ out.append(file)
+ return out
+
+
+def make_diff(file, original, reformatted):
+ return list(
+ difflib.unified_diff(
+ original,
+ reformatted,
+ fromfile='{}\t(original)'.format(file),
+ tofile='{}\t(reformatted)'.format(file),
+ n=3))
+
+
+class DiffError(Exception):
+ def __init__(self, message, errs=None):
+ super(DiffError, self).__init__(message)
+ self.errs = errs or []
+
+
+class UnexpectedError(Exception):
+ def __init__(self, message, exc=None):
+ super(UnexpectedError, self).__init__(message)
+ self.formatted_traceback = traceback.format_exc()
+ self.exc = exc
+
+
+def run_clang_format_diff_wrapper(args, file):
+ try:
+ ret = run_clang_format_diff(args, file)
+ return ret
+ except DiffError:
+ raise
+ except Exception as e:
+ raise UnexpectedError('{}: {}: {}'.format(file, e.__class__.__name__,
+ e), e)
+
+
+def run_clang_format_diff(args, file):
+ try:
+ with io.open(file, 'r', encoding='utf-8') as f:
+ original = f.readlines()
+ except IOError as exc:
+ raise DiffError(str(exc))
+ invocation = [args.clang_format_executable, file]
+
+ # Use of utf-8 to decode the process output.
+ #
+ # Hopefully, this is the correct thing to do.
+ #
+ # It's done due to the following assumptions (which may be incorrect):
+ # - clang-format will returns the bytes read from the files as-is,
+ # without conversion, and it is already assumed that the files use utf-8.
+ # - if the diagnostics were internationalized, they would use utf-8:
+ # > Adding Translations to Clang
+ # >
+ # > Not possible yet!
+ # > Diagnostic strings should be written in UTF-8,
+ # > the client can translate to the relevant code page if needed.
+ # > Each translation completely replaces the format string
+ # > for the diagnostic.
+ # > -- http://clang.llvm.org/docs/InternalsManual.html#internals-diag-translation
+ #
+ # It's not pretty, due to Python 2 & 3 compatibility.
+ encoding_py3 = {}
+ if sys.version_info[0] >= 3:
+ encoding_py3['encoding'] = 'utf-8'
+
+ try:
+ proc = subprocess.Popen(
+ invocation,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ universal_newlines=True,
+ **encoding_py3)
+ except OSError as exc:
+ raise DiffError(
+ "Command '{}' failed to start: {}".format(
+ subprocess.list2cmdline(invocation), exc
+ )
+ )
+ proc_stdout = proc.stdout
+ proc_stderr = proc.stderr
+ if sys.version_info[0] < 3:
+ # make the pipes compatible with Python 3,
+ # reading lines should output unicode
+ encoding = 'utf-8'
+ proc_stdout = codecs.getreader(encoding)(proc_stdout)
+ proc_stderr = codecs.getreader(encoding)(proc_stderr)
+ # hopefully the stderr pipe won't get full and block the process
+ outs = list(proc_stdout.readlines())
+ errs = list(proc_stderr.readlines())
+ proc.wait()
+ if proc.returncode:
+ raise DiffError(
+ "Command '{}' returned non-zero exit status {}".format(
+ subprocess.list2cmdline(invocation), proc.returncode
+ ),
+ errs,
+ )
+ return make_diff(file, original, outs), errs
+
+
+def bold_red(s):
+ return '\x1b[1m\x1b[31m' + s + '\x1b[0m'
+
+
+def colorize(diff_lines):
+ def bold(s):
+ return '\x1b[1m' + s + '\x1b[0m'
+
+ def cyan(s):
+ return '\x1b[36m' + s + '\x1b[0m'
+
+ def green(s):
+ return '\x1b[32m' + s + '\x1b[0m'
+
+ def red(s):
+ return '\x1b[31m' + s + '\x1b[0m'
+
+ for line in diff_lines:
+ if line[:4] in ['--- ', '+++ ']:
+ yield bold(line)
+ elif line.startswith('@@ '):
+ yield cyan(line)
+ elif line.startswith('+'):
+ yield green(line)
+ elif line.startswith('-'):
+ yield red(line)
+ else:
+ yield line
+
+
+def print_diff(diff_lines, use_color):
+ if use_color:
+ diff_lines = colorize(diff_lines)
+ if sys.version_info[0] < 3:
+ sys.stdout.writelines((l.encode('utf-8') for l in diff_lines))
+ else:
+ sys.stdout.writelines(diff_lines)
+
+
+def print_trouble(prog, message, use_colors):
+ error_text = 'error:'
+ if use_colors:
+ error_text = bold_red(error_text)
+ print("{}: {} {}".format(prog, error_text, message), file=sys.stderr)
+
+
+def main():
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ '--clang-format-executable',
+ metavar='EXECUTABLE',
+ help='path to the clang-format executable',
+ default='clang-format')
+ parser.add_argument(
+ '--extensions',
+ help='comma separated list of file extensions (default: {})'.format(
+ DEFAULT_EXTENSIONS),
+ default=DEFAULT_EXTENSIONS)
+ parser.add_argument(
+ '-r',
+ '--recursive',
+ action='store_true',
+ help='run recursively over directories')
+ parser.add_argument('files', metavar='file', nargs='+')
+ parser.add_argument(
+ '-q',
+ '--quiet',
+ action='store_true',
+ help="disable output, useful for the exit code")
+ parser.add_argument(
+ '-j',
+ metavar='N',
+ type=int,
+ default=0,
+ help='run N clang-format jobs in parallel'
+ ' (default number of cpus + 1)')
+ parser.add_argument(
+ '--color',
+ default='auto',
+ choices=['auto', 'always', 'never'],
+ help='show colored diff (default: auto)')
+ parser.add_argument(
+ '-e',
+ '--exclude',
+ metavar='PATTERN',
+ action='append',
+ default=[],
+ help='exclude paths matching the given glob-like pattern(s)'
+ ' from recursive search')
+
+ args = parser.parse_args()
+
+ # use default signal handling, like diff return SIGINT value on ^C
+ # https://bugs.python.org/issue14229#msg156446
+ signal.signal(signal.SIGINT, signal.SIG_DFL)
+ try:
+ signal.SIGPIPE
+ except AttributeError:
+ # compatibility, SIGPIPE does not exist on Windows
+ pass
+ else:
+ signal.signal(signal.SIGPIPE, signal.SIG_DFL)
+
+ colored_stdout = False
+ colored_stderr = False
+ if args.color == 'always':
+ colored_stdout = True
+ colored_stderr = True
+ elif args.color == 'auto':
+ colored_stdout = sys.stdout.isatty()
+ colored_stderr = sys.stderr.isatty()
+
+ version_invocation = [args.clang_format_executable, str("--version")]
+ try:
+ subprocess.check_call(version_invocation, stdout=DEVNULL)
+ except subprocess.CalledProcessError as e:
+ print_trouble(parser.prog, str(e), use_colors=colored_stderr)
+ return ExitStatus.TROUBLE
+ except OSError as e:
+ print_trouble(
+ parser.prog,
+ "Command '{}' failed to start: {}".format(
+ subprocess.list2cmdline(version_invocation), e
+ ),
+ use_colors=colored_stderr,
+ )
+ return ExitStatus.TROUBLE
+
+ retcode = ExitStatus.SUCCESS
+
+ excludes = excludes_from_file(DEFAULT_CLANG_FORMAT_IGNORE)
+ excludes.extend(args.exclude)
+
+ files = list_files(
+ args.files,
+ recursive=args.recursive,
+ exclude=excludes,
+ extensions=args.extensions.split(','))
+
+ if not files:
+ return
+
+ njobs = args.j
+ if njobs == 0:
+ njobs = multiprocessing.cpu_count() + 1
+ njobs = min(len(files), njobs)
+
+ if njobs == 1:
+ # execute directly instead of in a pool,
+ # less overhead, simpler stacktraces
+ it = (run_clang_format_diff_wrapper(args, file) for file in files)
+ pool = None
+ else:
+ pool = multiprocessing.Pool(njobs)
+ it = pool.imap_unordered(
+ partial(run_clang_format_diff_wrapper, args), files)
+ while True:
+ try:
+ outs, errs = next(it)
+ except StopIteration:
+ break
+ except DiffError as e:
+ print_trouble(parser.prog, str(e), use_colors=colored_stderr)
+ retcode = ExitStatus.TROUBLE
+ sys.stderr.writelines(e.errs)
+ except UnexpectedError as e:
+ print_trouble(parser.prog, str(e), use_colors=colored_stderr)
+ sys.stderr.write(e.formatted_traceback)
+ retcode = ExitStatus.TROUBLE
+ # stop at the first unexpected error,
+ # something could be very wrong,
+ # don't process all files unnecessarily
+ if pool:
+ pool.terminate()
+ break
+ else:
+ sys.stderr.writelines(errs)
+ if outs == []:
+ continue
+ if not args.quiet:
+ print_diff(outs, use_color=colored_stdout)
+ if retcode == ExitStatus.SUCCESS:
+ retcode = ExitStatus.DIFF
+
+ if retcode == ExitStatus.SUCCESS:
+ sys.stdout.write("clang-format validation passed: no issues found in " + str(len(files)) + " files\n")
+ else:
+ sys.stderr.write("clang-format validation failed\n")
+
+ return retcode
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/BuildTools/FormatValidation/clang-format_10.0.0.exe b/BuildTools/FormatValidation/clang-format_10.0.0.exe
new file mode 100644
index 00000000..033e310b
--- /dev/null
+++ b/BuildTools/FormatValidation/clang-format_10.0.0.exe
Binary files differ
diff --git a/BuildTools/FormatValidation/validate_format_win.bat b/BuildTools/FormatValidation/validate_format_win.bat
new file mode 100644
index 00000000..1ff7f1a9
--- /dev/null
+++ b/BuildTools/FormatValidation/validate_format_win.bat
@@ -0,0 +1,5 @@
+python clang-format-validate.py --color never --clang-format-executable clang-format_10.0.0.exe ^
+-r ../../Common ../../Graphics ../../Platforms ../../Primitives ^
+--exclude ../../Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions.h ^
+--exclude ../../Graphics/HLSL2GLSLConverterLib/include/GLSLDefinitions_inc.h ^
+--exclude ../../Graphics/GraphicsEngineVulkan/shaders/*