From a813c435ab4dcf30a72fdbe26883cf851c13793b Mon Sep 17 00:00:00 2001 From: Zhuo Zhang Date: Sat, 23 Nov 2024 10:52:17 +0800 Subject: [PATCH] clean: adjust folder structures and delete useless --- README.md | 50 --- cmake_sanitizer.py | 372 ------------------ cmake_sanitizer_test.py | 73 ---- .../CMakeLists.txt | 8 - .../testbed.cpp | 9 - .../CMakeLists.txt | 4 - .../CMakeLists.txt | 3 - .../CMakeLists.txt | 5 - .../CMakeLists.txt | 3 - .../CMakeLists.txt | 3 - .../test_link_directories/CMakeLists.txt | 3 - .../test_minimal_version/CMakeLists.txt | 1 - modules/FindPthread.cmake | 87 ---- mytest.py | 276 ------------- QueryCodePage.py => plugins/QueryCodePage.py | 6 - plugins/README.md | 35 ++ .../check_glibc_version.cmake | 0 clang-tidy.cmake => plugins/clang-tidy.cmake | 0 cppcheck.cmake => plugins/cppcheck.cmake | 0 cvbuild.cmake => plugins/cvbuild.cmake | 0 .../debug_symbols.cmake | 0 msvc_EHsc.cmake => plugins/msvc_EHsc.cmake | 0 ..._disable_constexpr_mutex_constructor.cmake | 0 .../msvc_dynamic_crt.cmake | 0 .../msvc_exception_fh3.cmake | 0 .../msvc_ignore_no_pdb_warning.cmake | 0 .../msvc_parallel_build.cmake | 0 .../msvc_static_crt.cmake | 0 .../msvc_unicode.cmake | 0 .../msvc_utf8_encoding.cmake | 0 postfix.cmake => plugins/postfix.cmake | 0 properties.cmake => plugins/properties.cmake | 0 .../source_group.cmake | 0 summary.cmake => plugins/summary.cmake | 0 requirements.txt | 1 - {test => tests}/lldb_string/CMakeLists.txt | 0 {test => tests}/lldb_string/main.cpp | 0 .../msvc_utf8_encoding/CMakeLists.txt | 0 {test => tests}/msvc_utf8_encoding/test.cpp | 0 39 files changed, 35 insertions(+), 904 deletions(-) delete mode 100644 cmake_sanitizer.py delete mode 100644 cmake_sanitizer_test.py delete mode 100644 cmake_sanitizer_test/test_add_compile_options_after_target_creation/CMakeLists.txt delete mode 100644 cmake_sanitizer_test/test_add_compile_options_after_target_creation/testbed.cpp delete mode 100644 cmake_sanitizer_test/test_add_definitions_for_compile_flags/CMakeLists.txt delete mode 100644 cmake_sanitizer_test/test_add_definitions_for_fPIC/CMakeLists.txt delete mode 100644 cmake_sanitizer_test/test_add_definitions_for_macro/CMakeLists.txt delete mode 100644 cmake_sanitizer_test/test_add_definitions_with_value/CMakeLists.txt delete mode 100644 cmake_sanitizer_test/test_global_fPIC_with_wrong_var_name/CMakeLists.txt delete mode 100644 cmake_sanitizer_test/test_link_directories/CMakeLists.txt delete mode 100644 cmake_sanitizer_test/test_minimal_version/CMakeLists.txt delete mode 100644 modules/FindPthread.cmake delete mode 100644 mytest.py rename QueryCodePage.py => plugins/QueryCodePage.py (85%) create mode 100644 plugins/README.md rename check_glibc_version.cmake => plugins/check_glibc_version.cmake (100%) rename clang-tidy.cmake => plugins/clang-tidy.cmake (100%) rename cppcheck.cmake => plugins/cppcheck.cmake (100%) rename cvbuild.cmake => plugins/cvbuild.cmake (100%) rename debug_symbols.cmake => plugins/debug_symbols.cmake (100%) rename msvc_EHsc.cmake => plugins/msvc_EHsc.cmake (100%) rename msvc_disable_constexpr_mutex_constructor.cmake => plugins/msvc_disable_constexpr_mutex_constructor.cmake (100%) rename msvc_dynamic_crt.cmake => plugins/msvc_dynamic_crt.cmake (100%) rename msvc_exception_fh3.cmake => plugins/msvc_exception_fh3.cmake (100%) rename msvc_ignore_no_pdb_warning.cmake => plugins/msvc_ignore_no_pdb_warning.cmake (100%) rename msvc_parallel_build.cmake => plugins/msvc_parallel_build.cmake (100%) rename msvc_static_crt.cmake => plugins/msvc_static_crt.cmake (100%) rename msvc_unicode.cmake => plugins/msvc_unicode.cmake (100%) rename msvc_utf8_encoding.cmake => plugins/msvc_utf8_encoding.cmake (100%) rename postfix.cmake => plugins/postfix.cmake (100%) rename properties.cmake => plugins/properties.cmake (100%) rename source_group.cmake => plugins/source_group.cmake (100%) rename summary.cmake => plugins/summary.cmake (100%) delete mode 100644 requirements.txt rename {test => tests}/lldb_string/CMakeLists.txt (100%) rename {test => tests}/lldb_string/main.cpp (100%) rename {test => tests}/msvc_utf8_encoding/CMakeLists.txt (100%) rename {test => tests}/msvc_utf8_encoding/test.cpp (100%) diff --git a/README.md b/README.md index 641f1c2..6b11d4a 100644 --- a/README.md +++ b/README.md @@ -23,53 +23,3 @@ Ease your cmake build experience, by add one line in your `CMakeLists.txt`: ```cmake include(rocbuild.cmake) ``` - -## asan.cmake - -Enable Address Sanitizer globally in your CMake-based project, by download [asan.cmake](asan.cmake) and only add one line in CMakeLists.txt -```cmake -include(asan.cmake) -``` - -Support many compiler platforms: -- GCC/Linux/Android NDK -- VS2019 -- VS2022 - -## tsan.cmake - -Enable ThreadSanitizer globally in your CMake-based project, by download [tsan.cmake](tsan.cmake) and only add one line in CMakeLists.txt -```cmake -include(tsan.cmake) -``` - -## overlook.cmake - -Treat 30+ severe C/C++ warnings as errors, by download [overlook.cmake](overlook/overlook.cmake) and only add one line in CMakeLists.txt -```cmake -include(overlook.cmake) -``` - -## summary.cmake - -Get a summary message for your current build, including global stuffs and list each target, by download [summary.cmake](summary.cmake) and only add one line in CMakeLists.txt -```cmake -include(summary.cmake) -``` - -## msvc_utf8_encoding.cmake - -When you write unicode chars (e.g. Chinese characters) in utf-8 encoding source files (.c/.cpp/.h/.hpp), and your command prompt use encodings like `/cp936` (due to OS language), it prints garbage. You may avoid that by specify encoding for source files and execution, separately. - -Here is the tool you can use, just download [msvc_utf8_encoding.cmake](msvc_utf8_encoding.cmake) (and also [QueryCodePage.py](QueryCodePage.py) if your cmake < 3.24), and only add one line in CMakeLists.txt - -```cmake -include(msvc_utf8_encoding.cmake) -``` - -## msvc_static_crt.cmake - -Switch to MT/MTd globally, by download [msvc_static_crt.cmake](msvc_static_crt.cmake) and only add one line in CMakeLists.txt -```cmake -include(msvc_static_crt.cmake) -``` diff --git a/cmake_sanitizer.py b/cmake_sanitizer.py deleted file mode 100644 index 969fc41..0000000 --- a/cmake_sanitizer.py +++ /dev/null @@ -1,372 +0,0 @@ -#!/usr/bin/env python - -""" -Author : ChrisZZ -Start Date : 2023-02-08 11:00:00 -Description : Parse, validate and report bad uses in CMakeLists.txt/xxx.cmake files. -""" - -# init logging -import logging -from rich.logging import RichHandler - -FORMAT = "%(message)s" -logging.basicConfig( - level="NOTSET", format=FORMAT, datefmt="[%X]", handlers=[RichHandler()] -) # set level=20 or logging.INFO to turn of debug -logger = logging.getLogger("rich") - - -def print_version_info(): - print("--------------------------------------------------------") - print(" CMake Sanitizer: detect bad uses in CMake files") - print(" Author: Zhuo Zhang (imzhuo#foxmail.com)") - print(" Version: 2023.07.15") - print("--------------------------------------------------------") - - -def get_lines(filepath): - """ - @param filepath path to CMakeLists.txt, or path to xxx.cmake - """ - fin = open(filepath, encoding="UTF-8") - lines = [_.rstrip("\n") for _ in fin.readlines()] - fin.close() - return lines - - -""" -cmake 的语法包括这几种: -- 函数调用: <函数名字>(<参数列表>), 可以写成多行的形式, 寻找右括号)即可 - - set(), unset(), return(), add_definitions(), add_compile_definitions(), include_directories(), - add_compile_options(), cmake_minimum_required(), find_package(), target_include_directories(), - target_link_libraries(), ... - - list(), include(), get_filepath_component() - - find_program(), message(), string() - - file() - - set_property(), get_target_property(), set_target_properties() - - execute_process(), add_custom_command() - - target_sources() - - 自定义函数() / 宏() -- 控制流 - - if()/endif() - - if()/elseif()/endif() - - foreach()/endforeach() - - macro()/endmacro() - - function()/endfunction() -""" -control_flow_keywords = [ - "if", - "endif", - "elseif", - "foreach", - "endforeach", - "macro", - "endmacro", - "function", - "endfunction", -] - - -class Node(object): - def __init__(self, identifier, content, start_line_number, end_line_number): - self.identifier = identifier - self.content = content - self.start_line_number = start_line_number - self.end_line_number = end_line_number - - def __str__(self): - return self.content - - -class Ast(object): - def __init__(self, node_lst, filepath): - self.filepath = filepath - self.node_lst = node_lst - self.minimum_cmake_version = None - for node in node_lst: - if node.identifier == "cmake_minimum_required": - self.minimum_cmake_version = node.content.split(" ")[1] - break - - -def remove_trailing_comments(line): - pos = -1 - has_left_quote = False - for i in range(len(line)): - if line[i] == "#" and (not has_left_quote): - pos = i - break - if line[i] == '"': # TODO: consider escaped quote char - has_left_quote = not has_left_quote - if pos == -1: - return line - return line[0:pos] - - -def parse(filepath): - """ - @param filepath of CMakeLists.txt, or xxx.cmake - - @brief parse the given text lines, get list of nodes - return the ast - """ - lines = get_lines(filepath) - num_of_lines = len(lines) - i = 0 - - node_lst = [] - while i < num_of_lines: - line = lines[i] - # print('line {:d} = {:s}'.format(i, line)) - - lstriped_line = line.lstrip() - - # ignore single line comment - if lstriped_line.startswith("#"): - i += 1 - continue - - lstriped_line = remove_trailing_comments(lstriped_line) - - # non-control-flow: functions. maybe single line, maybe multiple line. end with ')'. No nesting (assume no - # trailing comments) actually, `link_directories()` allow nested braces. - left_brace_pos = lstriped_line.find("(") - # print('!!', lstriped_line) - if left_brace_pos > 0: - identifier = lstriped_line[0:left_brace_pos].rstrip() - # print('!! ' + identifier) - if identifier not in control_flow_keywords: - # print('!!' + identifier) - - # single line - if lstriped_line.rstrip().endswith(")"): - line_number = i + 1 - node = Node(identifier, line, line_number, line_number) - node_lst.append(node) - else: - j = i + 1 - content_lines = [line] - while j < num_of_lines: - content_lines.append(lines[j]) - if lines[j].rstrip().endswith(")"): - break - j += 1 - content = "\n".join(content_lines) - start_line_number = i + 1 - end_line_number = j + 1 - node = Node(identifier, content, start_line_number, end_line_number) - node_lst.append(node) - i = j - i += 1 - - # print all node - # print('----------\ndump node info:') - # for node in node_lst: - # print(node.identifier, node.start_line_number, node.end_line_number) - - # return node_lst - ast = Ast(node_lst, filepath) - return ast - - -def check_rule1(ast, node): - # rule1: 不应当使用 add_definitions() 对于 add_definitions(-w) 或 add_definitions(-Wfoo=123) 的用法则更是大坑, - # 无法在 CMakeLists.txt 里获取到指定的 flags, 但 compile_commands.json 中却确实存在, 导致 overlook 工具失效并且难以察觉 - ret = True - if node.identifier == "add_definitions": - ret = False - if ("-w" in node.content) or ("-W" in node.content): - logger.error( - "Wrong usage detected in {:s}:{:d}\n{:s}\n".format( - ast.filepath, node.start_line_number, node.content - ) - ) - logger.info( - "add_definitions() should only be used for macro definitions(e.g. -Dfoo=1)," - "you should not pass compile options (e.g. -w, -Werror=return-type) to it!" - ) - else: - logger.warning( - "Not recommended usage detected in {:s}:{:d}\n{:s}".format( - ast.filepath, node.start_line_number, node.content - ) - ) - - if "-D" in node.content: - logger.info( - " Use add_compile_definitions(foo=1) to add preprocessor definitions (cmake>=3.12)" - ) - if "-I" in node.content: - logger.info( - " Use include_directories(some_dir) to add include directories." - ) - if ("-D" not in node.content) and ("-I" not in node.content): - logger.info( - " Use add_compile_options() to add other options, e.g. -Werror=return-type, -fPIC" - ) - logger.info( - " c.f. https://cmake.org/cmake/help/latest/command/add_definitions.html\n" - ) - return ret - - -def check_rule2(ast, node): - # rule2: - # 尽量不要使用具有全局作用域的函数 link_directories - ret = True - if node.identifier in ["link_directories", "link_libraries"]: - ret = False - logger.warning( - "Not recommended usage detected in {:s}:{:d}\n{:s}".format( - ast.filepath, node.start_line_number, node.content - ) - ) - logger.info( - " Use target_link_libraries(target dep_target_lst)\n" - ) - logger.info( - " or, target_link_libraries(target /absolute/path/to/lib/file)\n" - ) - logger.info( - " or, target_link_directories(target the_dir)\n" - ) - return ret - - -def check_rule3(ast): - ret = True - - # rule3: - # add_compile_options() 是对它之后的 target 生效的, 如果它之前没有任何 target 则不起作用, 应当报 error。 - # ref: https://stackoverflow.com/a/40522384/2999096 - node_lst = ast.node_lst - add_compile_options_appeared_lines = [] - for node in node_lst: - if node.identifier == "add_compile_options": - add_compile_options_appeared_lines.append(node.start_line_number) - if len(add_compile_options_appeared_lines) == 0: - return ret - - target_nodes = [] - for node in node_lst: - # print(' ', node.identifier) - if node.identifier in ["add_executable", "add_libraries"]: - target_nodes.append(node) - - # print('target_create_lines:') - # print(target_create_lines) - - # print('add_compile_options_appeared_lines') - # print(add_compile_options_appeared_lines) - - for target_node in target_nodes: - for compile_options_line in add_compile_options_appeared_lines: - if target_node.start_line_number < compile_options_line: - ret = False - logger.error( - "add_compile_options() should appear before all targets creation. It appeard in {:s}:{:d}".format( - ast.filepath, compile_options_line - ) - ) - logger.error( - " while {:s}() appeared in {:s}:{:d}".format( - target_node.identifier, - ast.filepath, - target_node.start_line_number, - ) - ) - logger.error("You may also use target_compile_options() instead.") - - return ret - - -def parse_set(content): - # 解析 set(xxKey xxValue) 的语句, 得到 xxKey, xxValue - inner_content = content.split("(")[1].split(")")[0] - key, value = inner_content.split(" ")[0], inner_content.split(" ")[1] - return key, value - - -def check_rule4(ast): - # rule4: 检查 fPIC 全局设置是否正确 - ret = True - node_lst = ast.node_lst - for node in node_lst: - if node.identifier == "set": - key, value = parse_set(node.content) - if key == "POSITION_INDEPENDENT_CODE": - logger.error( - "Invalid variable name for setting fPIC: `POSITION_INDEPENDENT_CODE`. It appeard in {:s}:{:d}".format( - ast.filepath, node.start_line_number - ) - ) - logger.error("The correct one is `CMAKE_POSITION_INDEPENDENT_CODE`") - ret = False - break - return ret - - -def validate(ast): - node_lst = ast.node_lst - ret = True - - if ast.minimum_cmake_version < "3.15": - ret = False - logger.warning( - "Suggested minimum cmake version >= 3.15, detected is {:s}".format( - ast.minimum_cmake_version - ) - ) - return ret - - print("--- checking rule1") - for node in node_lst: - ret = check_rule1(ast, node) - if ret != True: - return ret - - print("--- checking rule2") - for node in node_lst: - ret = check_rule2(ast, node) - if ret != True: - return ret - - print("--- checking rule3") - ret = check_rule3(ast) - if ret != True: - return ret - - print("--- checking rule4") - ret = check_rule4(ast) - if ret != True: - return ret - - print("===") - if ret == True: - print("CMake Sanity Result: OK") - else: - print("CMake Sanity Result: Not OK") - return ret - - -def test_remove_trailing_comments(): - s = remove_trailing_comments('set(s "1#2")#555') - assert s == 'set(s "1#2")' - - -if __name__ == "__main__": - print_version_info() - - import sys - - if len(sys.argv) > 1: - path = sys.argv[1] - ast = parse(path) - - # path = 'cmake_sanitizer_test/test_global_fPIC_with_wrong_var_name/CMakeLists.txt' - # check_rule4(ast) - - validate(ast) - else: - print("Usage: python cmake_sanitizer.py /path/to/CMakeLists.txt") diff --git a/cmake_sanitizer_test.py b/cmake_sanitizer_test.py deleted file mode 100644 index 684b14d..0000000 --- a/cmake_sanitizer_test.py +++ /dev/null @@ -1,73 +0,0 @@ -from mytest import MyTestRunner -import unittest -import cmake_sanitizer as csan - - -class ParseSet_Test(unittest.TestCase): - def test_simple(self): - s = "set(CMAKE_CXX_STANDARD 11)" - key, value = csan.parse_set(s) - self.assertEqual(key, "CMAKE_CXX_STANDARD") - self.assertEqual(value, "11") - - def test_have_space_between_set_and_left_parenthesis(self): - s = "set (CMAKE_CXX_STANDARD 11)" - key, value = csan.parse_set(s) - self.assertEqual(key, "CMAKE_CXX_STANDARD") - self.assertEqual(value, "11") - - def test_setting_cache_variable(self): - s = 'set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build" FORCE)' - key, value = csan.parse_set(s) - self.assertEqual(key, "CMAKE_BUILD_TYPE") - self.assertEqual(value, "Release") - - -class CMakeLists_Test(unittest.TestCase): - def test_version(self): - path = "cmake_sanitizer_test/test_minimal_version/CMakeLists.txt" - ast = csan.parse(path) - self.assertFalse(csan.validate(ast)) - - def test_add_definitions_for_compile_flags(self): - path = ( - "cmake_sanitizer_test/test_add_definitions_for_compile_flags/CMakeLists.txt" - ) - ast = csan.parse(path) - self.assertFalse(csan.validate(ast)) - - def test_add_definitions_for_macro(self): - path = "cmake_sanitizer_test/test_add_definitions_for_macro/CMakeLists.txt" - ast = csan.parse(path) - self.assertFalse(csan.validate(ast)) - - def test_add_definitions_for_fPIC(self): - path = "cmake_sanitizer_test/test_add_definitions_for_fPIC/CMakeLists.txt" - ast = csan.parse(path) - self.assertFalse(csan.validate(ast)) - - def test_link_directories(self): - path = "cmake_sanitizer_test/test_link_directories/CMakeLists.txt" - ast = csan.parse(path) - self.assertFalse(csan.validate(ast)) - - def test_link_directories(self): - path = "cmake_sanitizer_test/test_add_definitions_with_value/CMakeLists.txt" - ast = csan.parse(path) - self.assertFalse(csan.validate(ast)) - - def test_add_compile_options_after_target_creation(self): - path = "cmake_sanitizer_test/test_add_compile_options_after_target_creation/CMakeLists.txt" - ast = csan.parse(path) - self.assertFalse(csan.validate(ast)) - - def test_global_fPIC_with_wrong_var_name(self): - path = ( - "cmake_sanitizer_test/test_global_fPIC_with_wrong_var_name/CMakeLists.txt" - ) - ast = csan.parse(path) - self.assertFalse(csan.validate(ast)) - - -if __name__ == "__main__": - unittest.main(testRunner=MyTestRunner()) diff --git a/cmake_sanitizer_test/test_add_compile_options_after_target_creation/CMakeLists.txt b/cmake_sanitizer_test/test_add_compile_options_after_target_creation/CMakeLists.txt deleted file mode 100644 index 9857259..0000000 --- a/cmake_sanitizer_test/test_add_compile_options_after_target_creation/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(t6) # for rule3 -add_executable(testbed testbed.cpp) - -# the following options won't apply on the target `testbed` ! -# check the generated compile_commands.json to verify -add_compile_options(-Werror=literal-conversion -Wall -Wextra -pedantic -Werror) -include("../../summary.cmake") diff --git a/cmake_sanitizer_test/test_add_compile_options_after_target_creation/testbed.cpp b/cmake_sanitizer_test/test_add_compile_options_after_target_creation/testbed.cpp deleted file mode 100644 index 5cb9b44..0000000 --- a/cmake_sanitizer_test/test_add_compile_options_after_target_creation/testbed.cpp +++ /dev/null @@ -1,9 +0,0 @@ -#include -int main() -{ - printf("hello\n"); - int a = 1.3; - printf("a = %d\n", a); - - return 0; -} \ No newline at end of file diff --git a/cmake_sanitizer_test/test_add_definitions_for_compile_flags/CMakeLists.txt b/cmake_sanitizer_test/test_add_definitions_for_compile_flags/CMakeLists.txt deleted file mode 100644 index dde1c0d..0000000 --- a/cmake_sanitizer_test/test_add_definitions_for_compile_flags/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(x) -add_definitions(-w) -#add_compile_options(-w) diff --git a/cmake_sanitizer_test/test_add_definitions_for_fPIC/CMakeLists.txt b/cmake_sanitizer_test/test_add_definitions_for_fPIC/CMakeLists.txt deleted file mode 100644 index f6e46a7..0000000 --- a/cmake_sanitizer_test/test_add_definitions_for_fPIC/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(x) -add_definitions(-fPIC) \ No newline at end of file diff --git a/cmake_sanitizer_test/test_add_definitions_for_macro/CMakeLists.txt b/cmake_sanitizer_test/test_add_definitions_for_macro/CMakeLists.txt deleted file mode 100644 index abf496a..0000000 --- a/cmake_sanitizer_test/test_add_definitions_for_macro/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -cmake_minimum_required(VERSION 3.20) - -project(x) - -add_definitions(-DNDEBUG) diff --git a/cmake_sanitizer_test/test_add_definitions_with_value/CMakeLists.txt b/cmake_sanitizer_test/test_add_definitions_with_value/CMakeLists.txt deleted file mode 100644 index 9878ae2..0000000 --- a/cmake_sanitizer_test/test_add_definitions_with_value/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(x) -add_definitions(-Dfoo=1) \ No newline at end of file diff --git a/cmake_sanitizer_test/test_global_fPIC_with_wrong_var_name/CMakeLists.txt b/cmake_sanitizer_test/test_global_fPIC_with_wrong_var_name/CMakeLists.txt deleted file mode 100644 index 0ba6ef0..0000000 --- a/cmake_sanitizer_test/test_global_fPIC_with_wrong_var_name/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(x) -set(POSITION_INDEPENDENT_CODE ON) \ No newline at end of file diff --git a/cmake_sanitizer_test/test_link_directories/CMakeLists.txt b/cmake_sanitizer_test/test_link_directories/CMakeLists.txt deleted file mode 100644 index c6e754c..0000000 --- a/cmake_sanitizer_test/test_link_directories/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -cmake_minimum_required(VERSION 3.20) -project(x) -link_directories(lib) \ No newline at end of file diff --git a/cmake_sanitizer_test/test_minimal_version/CMakeLists.txt b/cmake_sanitizer_test/test_minimal_version/CMakeLists.txt deleted file mode 100644 index 03be826..0000000 --- a/cmake_sanitizer_test/test_minimal_version/CMakeLists.txt +++ /dev/null @@ -1 +0,0 @@ -cmake_minimum_required(VERSION 3.0) diff --git a/modules/FindPthread.cmake b/modules/FindPthread.cmake deleted file mode 100644 index da2ec57..0000000 --- a/modules/FindPthread.cmake +++ /dev/null @@ -1,87 +0,0 @@ -# Find Pthread package -# It is either an .h+.a/.so library, or an header-only library -# Usage: -# find_package(Pthread) -# target_link_libraries(your_target Pthread::Pthread) -#---------------------------------------------------------------------- -# Pthread is a header-only library on Android NDK, MacOSX. -# Pthread can also be an header-only library. -# -# ubuntu 16.04: -# gcc 5.4.0 requires explicit linking to pthread -# GLIBC version 2.23 -# ubuntu 20.04: -# gcc 9.4.0 requires explicit linking to pthread -# /usr/lib/x86_64-linux-gnu/libpthread.a is 6.3M -# /usr/lib/x86_64-linux-gnu/libpthread-2.31.so is 156K -# GLIBC version: 2.31 -# ubuntu 22.04 -# gcc 11.4.0 on ubuntu 22.04 does not require explicit linking to pthread -# /usr/lib/x86_64-linux-gnu/libpthread.a is 4KB -# /usr/lib/x86_64-linux-gnu/libpthread.so.0 is 24KB -# GLIBC version: 2.35 -# https://godbolt.org/z/a8KncEjeG godbolt GCC 13.2 looks like version higher than 11.4.0(the ubuntu22.04 default one) -# but GLIBC version 2.31, still requires explicit linking to pthread -# https://developers.redhat.com/articles/2021/12/17/why-glibc-234-removed-libpthread# -# https://gitlab.kitware.com/cmake/cmake/-/issues/23092 -# GLIBC version 2.34, libpthread is removed, and pthread is integrated into libc - -include(check_glibc_version.cmake) -include(CheckFunctionExists) - -# find header file -find_path(Pthread_INCLUDE_DIR NAMES pthread.h) - -# find library file -CHECK_GLIBC_VERSION(GLIBC_FOUND GLIBC_VERSION) - -# skip on Android due to implemened in Bionic -if(ANDROID OR (CMAKE_SYSTEM_NAME MATCHES "Darwin")) - # nop -elseif(FOUND_GLIBC AND GLIBC_VERSION VERSION_LESS 2.35) - # for glibc version < 2.34, find pthread library - find_library(Pthread_LIBRARY NAMES pthread) -endif() - -if(Pthread_INCLUDE_DIR) - if(Pthread_LIBRARY) - set(Pthread_FOUND TRUE) - else() - check_function_exists(pthread_create Pthread_FOUND) - set(Pthread_LIBRARY "") - endif() -else() - set(Pthread_FOUND FALSE) - set(Pthread_LIBRARY "") -endif() - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(Pthread - FOUND_VAR - Pthread_FOUND - REQUIRED_VARS - Pthread_INCLUDE_DIR -) - -mark_as_advanced(Pthread_INCLUDE_DIR Pthread_LIBRARY) - -# encapsulate as a target (package) -if(Pthread_FOUND AND NOT TARGET Pthread::Pthread) - if(Pthread_LIBRARY) - get_filename_component(file_ext ${Pthread_LIBRARY} EXT) - if(file_ext MATCHES "\\.a") - set(lib_type "STATIC") - else() - set(lib_type "SHARED") - endif() - add_library(Pthread::Pthread "${lib_type}" IMPORTED) - set_target_properties(Pthread::Pthread PROPERTIES - IMPORTED_LOCATION "${Pthread_LIBRARY}" - ) - else() - add_library(Pthread::Pthread INTERFACE IMPORTED) - endif() - set_target_properties(Pthread::Pthread PROPERTIES - INTERFACE_INCLUDE_DIRECTORIES "${Pthread_INCLUDE_DIR}" - ) -endif() \ No newline at end of file diff --git a/mytest.py b/mytest.py deleted file mode 100644 index ded84bb..0000000 --- a/mytest.py +++ /dev/null @@ -1,276 +0,0 @@ -################################################################################################################## -# Make Python unittest output like googletest -# -------------------- -# -# Example usage: -# -------------------- -# import unittest -# from mytest import MyTestRunner -# -# def inc(x): -# return x + 1 -# -# class JustTest(unittest.TestCase): -# def test_answer(self): -# assert inc(3) == 5 -# -# if __name__ == '__main__': -# unittest.main(testRunner=MyTestRunner()) -# -# References -# -------------------- -# https://www.cnblogs.com/coderzh/archive/2010/08/23/custom-python-unittestoutput-as-gtest.html -# https://github.com/xxhfg/youlook/blob/8d30e008260540902dacf5fbc5d4015bd68dc13e/libs/ColorUnittest/myunittest.py -# https://github.com/sndnyang/Tools/blob/d0bc2a7f5aa645048bd2fbaa28a43b1cccfac323/colortest.py -# -################################################################################################################## - -import unittest -import time -import sys - -import os - -if os.name == 'nt': - import ctypes - - ## {{{ http://code.activestate.com/recipes/496901/ (r3) - # See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winprog/winprog/windows_api_reference.asp - # for information on Windows APIs. - STD_INPUT_HANDLE = -10 - STD_OUTPUT_HANDLE = -11 - STD_ERROR_HANDLE = -12 - - FOREGROUND_WHITE = 0x0007 - FOREGROUND_BLUE = 0x01 # text color contains blue. - FOREGROUND_GREEN = 0x02 # text color contains green. - FOREGROUND_RED = 0x04 # text color contains red. - FOREGROUND_INTENSITY = 0x08 # text color is intensified. - FOREGROUND_YELLOW = FOREGROUND_RED | FOREGROUND_GREEN - - BACKGROUND_BLUE = 0x10 # background color contains blue. - BACKGROUND_GREEN = 0x20 # background color contains green. - BACKGROUND_RED = 0x40 # background color contains red. - BACKGROUND_INTENSITY = 0x80 # background color is intensified. - - std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) - - - def set_color(color, handle=std_out_handle): - """(color) -> BOOL - Example: set_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY) - """ - bool = ctypes.windll.kernel32.SetConsoleTextAttribute(handle, color) - return bool - - - class _ColorWritelnDecorator: - """Used to decorate file-like objects with a handy 'writeln' method""" - - def __init__(self, stream): - self.stream = stream - if os.name == 'nt': - self.std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) - - def __getattr__(self, name): - return getattr(self.stream, name) - - def yellow(self, msg): - set_color(FOREGROUND_YELLOW | FOREGROUND_INTENSITY) - self.write(msg) - set_color(FOREGROUND_WHITE) - - def writeln(self, msg=None): - if msg: - self.write(msg) - self.write('\n') - - def red(self, msg): - set_color(FOREGROUND_RED | FOREGROUND_INTENSITY) - self.write(msg) - set_color(FOREGROUND_WHITE) - - def green(self, msg): - set_color(FOREGROUND_GREEN | FOREGROUND_INTENSITY) - self.write(msg) - set_color(FOREGROUND_WHITE) - -else: - # https://en.wikipedia.org/wiki/ANSI_escape_code - black = (1, 1, 1) - red = (222, 56, 43) - green = (57, 181, 74) - yellow = (255, 199, 6) - blue = (0, 111, 184) - magenta = (118, 38, 113) - cyan = (44, 181, 233) - white = (204, 204, 204) - bright_black = (128, 128, 128) - bright_red = (255, 0, 0) - bright_green = (0, 255, 0) - bright_yellow = (255, 255, 0) - bright_blue = (0, 0, 255) - bright_magenta = (255, 0, 255) - bright_cyan = (0, 255, 255) - bright_white = (255, 255, 255) - - - class _ColorWritelnDecorator: - """Used to decorate file-like objects with a handy 'writeln' method""" - - def __init__(self, stream): - self.stream = stream - if os.name == 'nt': - self.std_out_handle = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) - - def __getattr__(self, name): - return getattr(self.stream, name) - - def set_color(self, color): - # stream.write("\033[38;2;{};{};{}m{} \033[38;2;255;255;255m".format(255, 0, 0, msg)) - r, g, b = color - self.stream.write("\033[38;2;{};{};{}m ".format(r, g, b)) - - def yellow(self, msg): - self.set_color(yellow) - self.write(msg) - self.set_color(white) - - def writeln(self, msg=None): - if msg: - self.write(msg) - self.write('\n') - - def red(self, msg): - self.set_color(red) - self.write(msg) - self.set_color(white) - - def green(self, msg): - self.set_color(green) - self.write(msg) - self.set_color(white) - -import re - -pattern = re.compile('File "(.+)",', re.IGNORECASE) - - -class MyTestResult(unittest.TestResult): - separator1 = '[----------] ' - separator2 = '[==========] ' - - def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1): - unittest.TestResult.__init__(self) - self.stream = stream - self.showAll = verbosity > 1 - self.dots = verbosity == 1 - self.descriptions = descriptions - - def getDescription(self, test): - if self.descriptions: - return test.shortDescription() or str(test) - else: - return str(test) - - def startTest(self, test): - self.stream.green('[ Run ] ') - self.stream.writeln(self.getDescription(test)) - unittest.TestResult.startTest(self, test) - if self.showAll: - self.stream.write(self.getDescription(test)) - self.stream.write(" ... ") - - def addSuccess(self, test): - unittest.TestResult.addSuccess(self, test) - if self.showAll: - self.stream.writeln("ok") - elif self.dots: - self.stream.green('[ OK ] ') - self.stream.writeln(self.getDescription(test)) - - def addError(self, test, err): - unittest.TestResult.addError(self, test, err) - if self.showAll: - self.stream.writeln("ERROR") - elif self.dots: - self.stream.red('[ ERRORED ] ') - self.stream.writeln(self.getDescription(test)) - self.stream.write(self._exc_info_to_string(err, test)) - - def addFailure(self, test, err): - unittest.TestResult.addFailure(self, test, err) - if self.showAll: - self.stream.writeln("FAIL") - elif self.dots: - # self.stream.write(self._exc_info_to_string(err, test)) - content = self._exc_info_to_string(err, test) - content_lines = content.split('\n') - linenum_line = content_lines[1] - file_desc, linenum_desc, testcase_desc = linenum_line.split(', ') - linenum = linenum_desc.split(' ')[-1] - filename = file_desc.split(' ')[-1][1:-1] - result = '{:s}:{:s} Failure'.format(filename, linenum) - self.stream.writeln(result) - self.stream.writeln('Expected:') - self.stream.writeln("\t" + content_lines[2].strip()) - self.stream.writeln('Actual:') - self.stream.writeln("\t" + content_lines[3].strip()) - - self.stream.red('[ FAILED ] ') - self.stream.writeln(self.getDescription(test)) - - -class MyTestRunner: - def __init__(self, stream=sys.stderr, descriptions=1, verbosity=1): - self.stream = _ColorWritelnDecorator(stream) - self.descriptions = descriptions - self.verbosity = verbosity - - def run(self, test): - result = MyTestResult(self.stream, self.descriptions, self.verbosity) - self.stream.green(result.separator2) - self.stream.writeln('Your Unit Tests Start') - - startTime = time.time() - test(result) - - stopTime = time.time() - timeTaken = stopTime - startTime - self.stream.green(result.separator2) - run = result.testsRun - self.stream.writeln("Run %d test%s in %.3fs" % - (run, run != 1 and "s" or "", timeTaken)) - - failed, errored = map(len, (result.failures, result.errors)) - - self.stream.green("[ PASSED ] %d tests" % (run - failed - errored)) - self.stream.writeln() - - if not result.wasSuccessful(): - if failed: - self.stream.red("[ FAILED ] %d tests, listed below:" % failed) - self.stream.writeln() - for failedtest, failederorr in result.failures: - match = pattern.findall(failederorr) - if match: - src_file = match[0] - self.stream.red("[ FAILED ] %s in %s" % (failedtest, src_file)) - self.stream.writeln() - if errored: - self.stream.red("[ ERRORED ] %d tests, listed below:" % errored) - self.stream.writeln() - for erroredtest, erorrmsg in result.errors: - match = pattern.findall(erorrmsg) - if match: - src_file = match[0] - self.stream.red("[ ERRORED ] %s in %s" % (erroredtest, src_file)) - self.stream.writeln() - - self.stream.writeln() - if failed: - self.stream.writeln("%2d FAILED TEST" % failed) - if errored: - self.stream.writeln("%2d ERRORED TEST" % errored) - - return result diff --git a/QueryCodePage.py b/plugins/QueryCodePage.py similarity index 85% rename from QueryCodePage.py rename to plugins/QueryCodePage.py index 2de5c18..e043f56 100644 --- a/QueryCodePage.py +++ b/plugins/QueryCodePage.py @@ -12,16 +12,10 @@ def is_windows(): if is_windows(): from winreg import ( - CloseKey, OpenKey, QueryValueEx, - SetValueEx, - HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, - KEY_ALL_ACCESS, KEY_READ, - REG_EXPAND_SZ, - REG_SZ, ) if __name__ == "__main__": diff --git a/plugins/README.md b/plugins/README.md new file mode 100644 index 0000000..1e48117 --- /dev/null +++ b/plugins/README.md @@ -0,0 +1,35 @@ +## asan.cmake + +Enable Address Sanitizer globally in your CMake-based project, by download [asan.cmake](asan.cmake) and only add one line in CMakeLists.txt +```cmake +include(asan.cmake) +``` + +Support many compiler platforms: +- GCC/Linux/Android NDK +- VS2019 +- VS2022 + +## tsan.cmake + +Enable ThreadSanitizer globally in your CMake-based project, by download [tsan.cmake](tsan.cmake) and only add one line in CMakeLists.txt +```cmake +include(tsan.cmake) +``` + +## summary.cmake + +Get a summary message for your current build, including global stuffs and list each target, by download [summary.cmake](summary.cmake) and only add one line in CMakeLists.txt +```cmake +include(summary.cmake) +``` + +## msvc_utf8_encoding.cmake + +When you write unicode chars (e.g. Chinese characters) in utf-8 encoding source files (.c/.cpp/.h/.hpp), and your command prompt use encodings like `/cp936` (due to OS language), it prints garbage. You may avoid that by specify encoding for source files and execution, separately. + +Here is the tool you can use, just download [msvc_utf8_encoding.cmake](msvc_utf8_encoding.cmake) (and also [QueryCodePage.py](QueryCodePage.py) if your cmake < 3.24), and only add one line in CMakeLists.txt + +```cmake +include(msvc_utf8_encoding.cmake) +``` diff --git a/check_glibc_version.cmake b/plugins/check_glibc_version.cmake similarity index 100% rename from check_glibc_version.cmake rename to plugins/check_glibc_version.cmake diff --git a/clang-tidy.cmake b/plugins/clang-tidy.cmake similarity index 100% rename from clang-tidy.cmake rename to plugins/clang-tidy.cmake diff --git a/cppcheck.cmake b/plugins/cppcheck.cmake similarity index 100% rename from cppcheck.cmake rename to plugins/cppcheck.cmake diff --git a/cvbuild.cmake b/plugins/cvbuild.cmake similarity index 100% rename from cvbuild.cmake rename to plugins/cvbuild.cmake diff --git a/debug_symbols.cmake b/plugins/debug_symbols.cmake similarity index 100% rename from debug_symbols.cmake rename to plugins/debug_symbols.cmake diff --git a/msvc_EHsc.cmake b/plugins/msvc_EHsc.cmake similarity index 100% rename from msvc_EHsc.cmake rename to plugins/msvc_EHsc.cmake diff --git a/msvc_disable_constexpr_mutex_constructor.cmake b/plugins/msvc_disable_constexpr_mutex_constructor.cmake similarity index 100% rename from msvc_disable_constexpr_mutex_constructor.cmake rename to plugins/msvc_disable_constexpr_mutex_constructor.cmake diff --git a/msvc_dynamic_crt.cmake b/plugins/msvc_dynamic_crt.cmake similarity index 100% rename from msvc_dynamic_crt.cmake rename to plugins/msvc_dynamic_crt.cmake diff --git a/msvc_exception_fh3.cmake b/plugins/msvc_exception_fh3.cmake similarity index 100% rename from msvc_exception_fh3.cmake rename to plugins/msvc_exception_fh3.cmake diff --git a/msvc_ignore_no_pdb_warning.cmake b/plugins/msvc_ignore_no_pdb_warning.cmake similarity index 100% rename from msvc_ignore_no_pdb_warning.cmake rename to plugins/msvc_ignore_no_pdb_warning.cmake diff --git a/msvc_parallel_build.cmake b/plugins/msvc_parallel_build.cmake similarity index 100% rename from msvc_parallel_build.cmake rename to plugins/msvc_parallel_build.cmake diff --git a/msvc_static_crt.cmake b/plugins/msvc_static_crt.cmake similarity index 100% rename from msvc_static_crt.cmake rename to plugins/msvc_static_crt.cmake diff --git a/msvc_unicode.cmake b/plugins/msvc_unicode.cmake similarity index 100% rename from msvc_unicode.cmake rename to plugins/msvc_unicode.cmake diff --git a/msvc_utf8_encoding.cmake b/plugins/msvc_utf8_encoding.cmake similarity index 100% rename from msvc_utf8_encoding.cmake rename to plugins/msvc_utf8_encoding.cmake diff --git a/postfix.cmake b/plugins/postfix.cmake similarity index 100% rename from postfix.cmake rename to plugins/postfix.cmake diff --git a/properties.cmake b/plugins/properties.cmake similarity index 100% rename from properties.cmake rename to plugins/properties.cmake diff --git a/source_group.cmake b/plugins/source_group.cmake similarity index 100% rename from source_group.cmake rename to plugins/source_group.cmake diff --git a/summary.cmake b/plugins/summary.cmake similarity index 100% rename from summary.cmake rename to plugins/summary.cmake diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index c94be38..0000000 --- a/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -rich \ No newline at end of file diff --git a/test/lldb_string/CMakeLists.txt b/tests/lldb_string/CMakeLists.txt similarity index 100% rename from test/lldb_string/CMakeLists.txt rename to tests/lldb_string/CMakeLists.txt diff --git a/test/lldb_string/main.cpp b/tests/lldb_string/main.cpp similarity index 100% rename from test/lldb_string/main.cpp rename to tests/lldb_string/main.cpp diff --git a/test/msvc_utf8_encoding/CMakeLists.txt b/tests/msvc_utf8_encoding/CMakeLists.txt similarity index 100% rename from test/msvc_utf8_encoding/CMakeLists.txt rename to tests/msvc_utf8_encoding/CMakeLists.txt diff --git a/test/msvc_utf8_encoding/test.cpp b/tests/msvc_utf8_encoding/test.cpp similarity index 100% rename from test/msvc_utf8_encoding/test.cpp rename to tests/msvc_utf8_encoding/test.cpp