From d0ba84d9befa40f39d1546c750e5174cec223d21 Mon Sep 17 00:00:00 2001 From: Timothy Stack Date: Sun, 13 Mar 2022 22:44:12 -0700 Subject: [PATCH] [build] run cmake-init and switch from hunter to conan for packages --- .clang-format | 178 ++++++++++++++++++++++++++ .clang-tidy | 154 ++++++++++++++++++++++ .codespellrc | 6 + .gitignore | 9 ++ CMakeLists.txt | 97 +++++++------- CMakePresets.json | 142 ++++++++++++++++++++ cmake/coverage.cmake | 33 +++++ cmake/dev-mode.cmake | 32 +++++ cmake/docs-ci.cmake | 112 ++++++++++++++++ cmake/docs.cmake | 40 ++++++ cmake/folders.cmake | 21 +++ cmake/install-rules.cmake | 44 +++++++ cmake/install-script.cmake | 18 +++ cmake/lint-targets.cmake | 32 +++++ cmake/lint.cmake | 50 ++++++++ cmake/open-cpp-coverage.cmake.example | 31 +++++ cmake/prelude.cmake | 10 ++ cmake/project-is-top-level.cmake | 6 + cmake/spell-targets.cmake | 22 ++++ cmake/spell.cmake | 29 +++++ cmake/variables.cmake | 28 ++++ conanfile.py | 54 ++++++++ docs/Doxyfile.in | 32 +++++ docs/conf.py.in | 6 + docs/pages/about.dox | 7 + src/CMakeLists.txt | 5 +- src/base/CMakeLists.txt | 6 +- src/config.cmake.h.in | 4 + src/pcrepp/CMakeLists.txt | 4 +- src/remote/CMakeLists.txt | 4 +- src/tailer/CMakeLists.txt | 2 +- test/CMakeLists.txt | 36 +++--- 32 files changed, 1176 insertions(+), 78 deletions(-) create mode 100644 .clang-format create mode 100644 .clang-tidy create mode 100644 .codespellrc create mode 100644 CMakePresets.json create mode 100644 cmake/coverage.cmake create mode 100644 cmake/dev-mode.cmake create mode 100644 cmake/docs-ci.cmake create mode 100644 cmake/docs.cmake create mode 100644 cmake/folders.cmake create mode 100644 cmake/install-rules.cmake create mode 100644 cmake/install-script.cmake create mode 100644 cmake/lint-targets.cmake create mode 100644 cmake/lint.cmake create mode 100644 cmake/open-cpp-coverage.cmake.example create mode 100644 cmake/prelude.cmake create mode 100644 cmake/project-is-top-level.cmake create mode 100644 cmake/spell-targets.cmake create mode 100644 cmake/spell.cmake create mode 100644 cmake/variables.cmake create mode 100644 conanfile.py create mode 100644 docs/Doxyfile.in create mode 100644 docs/conf.py.in create mode 100644 docs/pages/about.dox diff --git a/.clang-format b/.clang-format new file mode 100644 index 00000000..3f4f7735 --- /dev/null +++ b/.clang-format @@ -0,0 +1,178 @@ +--- +Language: Cpp +# BasedOnStyle: Chromium +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveMacros: false +AlignConsecutiveAssignments: false +AlignConsecutiveBitFields: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: DontAlign +AlignOperands: DontAlign +AlignTrailingComments: false +AllowAllArgumentsOnNextLine: true +AllowAllConstructorInitializersOnNextLine: false +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortEnumsOnASingleLine: false +AllowShortBlocksOnASingleLine: Empty +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: Inline +AllowShortLambdasOnASingleLine: All +AllowShortIfStatementsOnASingleLine: Never +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: true +AlwaysBreakTemplateDeclarations: Yes +BinPackArguments: false +BinPackParameters: false +BraceWrapping: + AfterCaseLabel: false + AfterClass: true + AfterControlStatement: MultiLine + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: false + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: false + BeforeElse: false + BeforeLambdaBody: true + BeforeWhile: false + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: Custom +# BreakBeforeInheritanceComma: true +BreakInheritanceList: BeforeComma +BreakBeforeTernaryOperators: true +BreakConstructorInitializersBeforeComma: true +BreakConstructorInitializers: BeforeComma +BreakAfterJavaFieldAnnotations: true +BreakStringLiterals: true +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +CompactNamespaces: false +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DeriveLineEnding: false +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: + - foreach + - Q_FOREACH + - BOOST_FOREACH +IncludeBlocks: Regroup +IncludeCategories: + # Standard library headers come before anything else + - Regex: '^<[a-z_]+>' + Priority: -1 + - Regex: '^<.+\.h(pp)?>' + Priority: 1 + - Regex: '^<.*' + Priority: 2 + - Regex: '.*' + Priority: 3 +IncludeIsMainRegex: '' +IncludeIsMainSourceRegex: '' +IndentCaseLabels: true +IndentCaseBlocks: false +IndentGotoLabels: true +IndentPPDirectives: AfterHash +IndentExternBlock: NoIndent +IndentWidth: 2 +IndentWrappedFunctionNames: false +InsertTrailingCommas: Wrapped +JavaScriptQuotes: Double +JavaScriptWrapImports: true +KeepEmptyLinesAtTheStartOfBlocks: false +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBinPackProtocolList: Never +ObjCBlockIndentWidth: 2 +ObjCBreakBeforeNestedBlockParam: true +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakAssignment: 2 +PenaltyBreakBeforeFirstCallParameter: 1 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyBreakTemplateDeclaration: 10 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 200 +PointerAlignment: Left +RawStringFormats: + - Language: Cpp + Delimiters: + - cc + - CC + - cpp + - Cpp + - CPP + - 'c++' + - 'C++' + CanonicalDelimiter: '' + BasedOnStyle: google + - Language: TextProto + Delimiters: + - pb + - PB + - proto + - PROTO + EnclosingFunctions: + - EqualsProto + - EquivToProto + - PARSE_PARTIAL_TEXT_PROTO + - PARSE_TEST_PROTO + - PARSE_TEXT_PROTO + - ParseTextOrDie + - ParseTextProtoOrDie + - ParseTestProto + - ParsePartialTestProto + CanonicalDelimiter: '' + BasedOnStyle: google +ReflowComments: true +SortIncludes: true +SortUsingDeclarations: true +SpaceAfterCStyleCast: false +SpaceAfterLogicalNot: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeCpp11BracedList: true +SpaceBeforeCtorInitializerColon: true +SpaceBeforeInheritanceColon: true +SpaceBeforeParens: ControlStatementsExceptForEachMacros +SpaceBeforeRangeBasedForLoopColon: true +SpaceInEmptyBlock: false +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInConditionalStatement: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +SpaceBeforeSquareBrackets: false +Standard: Auto +StatementMacros: + - Q_UNUSED + - QT_REQUIRE_VERSION +TabWidth: 8 +UseCRLF: false +UseTab: Never +WhitespaceSensitiveMacros: + - STRINGIZE + - PP_STRINGIZE + - BOOST_PP_STRINGIZE +... diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 00000000..1b570ccb --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,154 @@ +--- +# Enable ALL the things! Except not really +# misc-non-private-member-variables-in-classes: the options don't do anything +Checks: "*,\ + -google-readability-todo,\ + -altera-unroll-loops,\ + -fuchsia-*,\ + fuchsia-multiple-inheritance,\ + -llvm-header-guard,\ + -llvm-include-order,\ + -llvmlibc-*,\ + -modernize-use-trailing-return-type,\ + -misc-non-private-member-variables-in-classes" +WarningsAsErrors: '' +CheckOptions: + - key: 'bugprone-argument-comment.StrictMode' + value: 'true' +# Prefer using enum classes with 2 values for parameters instead of bools + - key: 'bugprone-argument-comment.CommentBoolLiterals' + value: 'true' + - key: 'bugprone-misplaced-widening-cast.CheckImplicitCasts' + value: 'true' + - key: 'bugprone-sizeof-expression.WarnOnSizeOfIntegerExpression' + value: 'true' + - key: 'bugprone-suspicious-string-compare.WarnOnLogicalNotComparison' + value: 'true' + - key: 'readability-simplify-boolean-expr.ChainedConditionalReturn' + value: 'true' + - key: 'readability-simplify-boolean-expr.ChainedConditionalAssignment' + value: 'true' + - key: 'readability-uniqueptr-delete-release.PreferResetCall' + value: 'true' + - key: 'cppcoreguidelines-init-variables.MathHeader' + value: '' + - key: 'cppcoreguidelines-narrowing-conversions.PedanticMode' + value: 'true' + - key: 'readability-else-after-return.WarnOnUnfixable' + value: 'true' + - key: 'readability-else-after-return.WarnOnConditionVariables' + value: 'true' + - key: 'readability-inconsistent-declaration-parameter-name.Strict' + value: 'true' + - key: 'readability-qualified-auto.AddConstToQualified' + value: 'true' + - key: 'readability-redundant-access-specifiers.CheckFirstDeclaration' + value: 'true' +# These seem to be the most common identifier styles + - key: 'readability-identifier-naming.AbstractClassCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ClassCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ClassConstantCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ClassMemberCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ClassMethodCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ConstantCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ConstantMemberCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ConstantParameterCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ConstantPointerParameterCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ConstexprFunctionCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ConstexprMethodCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ConstexprVariableCase' + value: 'lower_case' + - key: 'readability-identifier-naming.EnumCase' + value: 'lower_case' + - key: 'readability-identifier-naming.EnumConstantCase' + value: 'lower_case' + - key: 'readability-identifier-naming.FunctionCase' + value: 'lower_case' + - key: 'readability-identifier-naming.GlobalConstantCase' + value: 'lower_case' + - key: 'readability-identifier-naming.GlobalConstantPointerCase' + value: 'lower_case' + - key: 'readability-identifier-naming.GlobalFunctionCase' + value: 'lower_case' + - key: 'readability-identifier-naming.GlobalPointerCase' + value: 'lower_case' + - key: 'readability-identifier-naming.GlobalVariableCase' + value: 'lower_case' + - key: 'readability-identifier-naming.InlineNamespaceCase' + value: 'lower_case' + - key: 'readability-identifier-naming.LocalConstantCase' + value: 'lower_case' + - key: 'readability-identifier-naming.LocalConstantPointerCase' + value: 'lower_case' + - key: 'readability-identifier-naming.LocalPointerCase' + value: 'lower_case' + - key: 'readability-identifier-naming.LocalVariableCase' + value: 'lower_case' + - key: 'readability-identifier-naming.MacroDefinitionCase' + value: 'UPPER_CASE' + - key: 'readability-identifier-naming.MemberCase' + value: 'lower_case' + - key: 'readability-identifier-naming.MethodCase' + value: 'lower_case' + - key: 'readability-identifier-naming.NamespaceCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ParameterCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ParameterPackCase' + value: 'lower_case' + - key: 'readability-identifier-naming.PointerParameterCase' + value: 'lower_case' + - key: 'readability-identifier-naming.PrivateMemberCase' + value: 'lower_case' + - key: 'readability-identifier-naming.PrivateMemberPrefix' + value: 'm_' + - key: 'readability-identifier-naming.PrivateMethodCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ProtectedMemberCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ProtectedMemberPrefix' + value: 'm_' + - key: 'readability-identifier-naming.ProtectedMethodCase' + value: 'lower_case' + - key: 'readability-identifier-naming.PublicMemberCase' + value: 'lower_case' + - key: 'readability-identifier-naming.PublicMethodCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ScopedEnumConstantCase' + value: 'lower_case' + - key: 'readability-identifier-naming.StaticConstantCase' + value: 'lower_case' + - key: 'readability-identifier-naming.StaticVariableCase' + value: 'lower_case' + - key: 'readability-identifier-naming.StructCase' + value: 'lower_case' + - key: 'readability-identifier-naming.TemplateParameterCase' + value: 'CamelCase' + - key: 'readability-identifier-naming.TemplateTemplateParameterCase' + value: 'CamelCase' + - key: 'readability-identifier-naming.TypeAliasCase' + value: 'lower_case' + - key: 'readability-identifier-naming.TypedefCase' + value: 'lower_case' + - key: 'readability-identifier-naming.TypeTemplateParameterCase' + value: 'CamelCase' + - key: 'readability-identifier-naming.UnionCase' + value: 'lower_case' + - key: 'readability-identifier-naming.ValueTemplateParameterCase' + value: 'CamelCase' + - key: 'readability-identifier-naming.VariableCase' + value: 'lower_case' + - key: 'readability-identifier-naming.VirtualMethodCase' + value: 'lower_case' +... diff --git a/.codespellrc b/.codespellrc new file mode 100644 index 00000000..d3634a3f --- /dev/null +++ b/.codespellrc @@ -0,0 +1,6 @@ +[codespell] +builtin = clear,rare,en-GB_to_en-US,names,informal,code +check-filenames = +check-hidden = +skip = */.git,*/build,*/prefix,*/conan +quiet-level = 2 diff --git a/.gitignore b/.gitignore index 691723ba..51f95aeb 100644 --- a/.gitignore +++ b/.gitignore @@ -91,3 +91,12 @@ test/test_top_status test/test_yajlpp test/truncfile.0 cmake-build/ +.vs/ +.vscode/ +build/ +cmake/open-cpp-coverage.cmake +cmake-build-*/ +conan/ +prefix/ +CMakeLists.txt.user +CMakeUserPresets.json diff --git a/CMakeLists.txt b/CMakeLists.txt index 49173e78..296e0152 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,60 +1,57 @@ -cmake_minimum_required(VERSION 3.2) +cmake_minimum_required(VERSION 3.14) -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) -endif() - -set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-unused-parameter") -set(CMAKE_CXX_FLAGS_DEBUG "-g") -set(CMAKE_CXX_FLAGS_RELEASE "-O3") - -include("cmake/HunterGate.cmake") -huntergate(URL "https://github.com/cpp-pm/hunter/archive/v0.24.0.tar.gz" - SHA1 "a3d7f4372b1dcd52faa6ff4a3bd5358e1d0e5efd" - LOCAL) +include(cmake/prelude.cmake) set(CMAKE_CXX_STANDARD 14) -project(lnav VERSION 0.10.2) - -# include(cmake/CodeCoverage.cmake) append_coverage_compiler_flags() - -include(CTest) -include(GNUInstallDirs) - -hunter_add_package(libpcre) -find_package(libpcre CONFIG REQUIRED) - -hunter_add_package(BZip2) -find_package(BZip2 CONFIG REQUIRED) - -hunter_add_package(sqlite3) -find_package(sqlite3 CONFIG REQUIRED) - -hunter_add_package(ZLIB) +project( + lnav + VERSION 0.10.2 + DESCRIPTION "An advanced log file viewer for the small-scale." + HOMEPAGE_URL "https://lnav.org/" + LANGUAGES CXX C +) + +include(cmake/project-is-top-level.cmake) +include(cmake/variables.cmake) + +find_package(SQLite3 REQUIRED) +find_package(BZip2 REQUIRED) +find_package(LibArchive REQUIRED) find_package(ZLIB REQUIRED) - -hunter_add_package(CURL) -find_package(CURL CONFIG REQUIRED) - -hunter_add_package(ncursesw) -find_package(ncursesw CONFIG REQUIRED) - -hunter_add_package(readline) +find_package(pcre REQUIRED) find_package(readline REQUIRED) - -hunter_add_package(libarchive) -find_package(libarchive CONFIG REQUIRED) +find_package(ncurses REQUIRED) +find_package(CURL REQUIRED) set(lnav_LIBS - ZLIB::zlib - BZip2::bz2 - sqlite3::sqlite3 - PkgConfig::libpcre - CURL::libcurl - readline::readline - readline::history - PkgConfig::ncursesw - PkgConfig::libarchive) + CURL::libcurl + SQLite::SQLite3 + BZip2::BZip2 + ncurses::libcurses + pcre::libpcre + readline::readline + LibArchive::LibArchive + ZLIB::ZLIB + ) add_subdirectory(src) add_subdirectory(test) + +# ---- Install rules ---- + +if(NOT CMAKE_SKIP_INSTALL_RULES) + include(cmake/install-rules.cmake) +endif() + +# ---- Developer mode ---- + +if(NOT lnav_DEVELOPER_MODE) + return() +elseif(NOT PROJECT_IS_TOP_LEVEL) + message( + AUTHOR_WARNING + "Developer mode is intended for developers of lnav" + ) +endif() + +include(cmake/dev-mode.cmake) diff --git a/CMakePresets.json b/CMakePresets.json new file mode 100644 index 00000000..d1adc006 --- /dev/null +++ b/CMakePresets.json @@ -0,0 +1,142 @@ +{ + "version": 2, + "cmakeMinimumRequired": { + "major": 3, + "minor": 14, + "patch": 0 + }, + "configurePresets": [ + { + "name": "cmake-pedantic", + "hidden": true, + "warnings": { + "dev": true, + "deprecated": true, + "uninitialized": true, + "unusedCli": true, + "systemVars": false + }, + "errors": { + "dev": true, + "deprecated": true + } + }, + { + "name": "dev-mode", + "hidden": true, + "inherits": "cmake-pedantic", + "cacheVariables": { + "lnav_DEVELOPER_MODE": "ON" + } + }, + { + "name": "conan", + "hidden": true, + "cacheVariables": { + "CMAKE_TOOLCHAIN_FILE": "${sourceDir}/conan/conan_toolchain.cmake" + } + }, + { + "name": "cppcheck", + "hidden": true, + "cacheVariables": { + "CMAKE_CXX_CPPCHECK": "cppcheck;--inline-suppr" + } + }, + { + "name": "clang-tidy", + "hidden": true, + "cacheVariables": { + "CMAKE_CXX_CLANG_TIDY": "clang-tidy;--header-filter=${sourceDir}/*" + } + }, + { + "name": "ci-std", + "description": "This preset makes sure the project actually builds with at least the specified standard", + "hidden": true, + "cacheVariables": { + "CMAKE_CXX_EXTENSIONS": "OFF", + "CMAKE_CXX_STANDARD": "14", + "CMAKE_CXX_STANDARD_REQUIRED": "ON" + } + }, + { + "name": "flags-unix", + "hidden": true, + "cacheVariables": { + "CMAKE_CXX_FLAGS": "" + } + }, + { + "name": "flags-windows", + "hidden": true, + "cacheVariables": { + "CMAKE_CXX_FLAGS": "/W4 /permissive- /utf-8 /volatile:iso /EHsc /Zc:__cplusplus /Zc:throwingNew" + } + }, + { + "name": "ci-unix", + "generator": "Unix Makefiles", + "hidden": true, + "inherits": ["flags-unix", "ci-std"], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Release" + } + }, + { + "name": "ci-win64", + "inherits": ["flags-windows", "ci-std"], + "generator": "Visual Studio 17 2022", + "architecture": "x64", + "hidden": true + }, + { + "name": "coverage-unix", + "binaryDir": "${sourceDir}/build/coverage", + "inherits": "ci-unix", + "hidden": true, + "cacheVariables": { + "ENABLE_COVERAGE": "ON", + "CMAKE_BUILD_TYPE": "Coverage", + "CMAKE_CXX_FLAGS_COVERAGE": "-Og -g --coverage -fkeep-inline-functions -fkeep-static-functions", + "CMAKE_EXE_LINKER_FLAGS_COVERAGE": "--coverage", + "CMAKE_SHARED_LINKER_FLAGS_COVERAGE": "--coverage", + "CMAKE_MAP_IMPORTED_CONFIG_SANITIZE": "Coverage;RelWithDebInfo;Release;Debug;" + } + }, + { + "name": "ci-coverage", + "inherits": ["coverage-unix", "dev-mode", "conan"], + "cacheVariables": { + "COVERAGE_HTML_COMMAND": "" + } + }, + { + "name": "ci-sanitize", + "binaryDir": "${sourceDir}/build/sanitize", + "inherits": ["ci-unix", "dev-mode", "conan"], + "cacheVariables": { + "CMAKE_BUILD_TYPE": "Sanitize", + "CMAKE_CXX_FLAGS_SANITIZE": "-O2 -g -fsanitize=address,undefined -fno-omit-frame-pointer -fno-common", + "CMAKE_MAP_IMPORTED_CONFIG_SANITIZE": "Sanitize;RelWithDebInfo;Release;Debug;" + } + }, + { + "name": "ci-build", + "binaryDir": "${sourceDir}/build", + "hidden": true + }, + { + "name": "ci-macos", + "inherits": ["ci-build", "ci-unix", "dev-mode", "conan"] + }, + { + "name": "ci-ubuntu", + "inherits": ["ci-build", "ci-unix", "clang-tidy", "conan", "dev-mode"] + }, + { + "name": "ci-windows", + "inherits": ["ci-build", "ci-win64", "dev-mode", "conan"] + } + ] +} diff --git a/cmake/coverage.cmake b/cmake/coverage.cmake new file mode 100644 index 00000000..c89cc161 --- /dev/null +++ b/cmake/coverage.cmake @@ -0,0 +1,33 @@ +# ---- Variables ---- + +# We use variables separate from what CTest uses, because those have +# customization issues +set( + COVERAGE_TRACE_COMMAND + lcov -c -q + -o "${PROJECT_BINARY_DIR}/coverage.info" + -d "${PROJECT_BINARY_DIR}" + --include "${PROJECT_SOURCE_DIR}/*" + CACHE STRING + "; separated command to generate a trace for the 'coverage' target" +) + +set( + COVERAGE_HTML_COMMAND + genhtml --legend -f -q + "${PROJECT_BINARY_DIR}/coverage.info" + -p "${PROJECT_SOURCE_DIR}" + -o "${PROJECT_BINARY_DIR}/coverage_html" + CACHE STRING + "; separated command to generate an HTML report for the 'coverage' target" +) + +# ---- Coverage target ---- + +add_custom_target( + coverage + COMMAND ${COVERAGE_TRACE_COMMAND} + COMMAND ${COVERAGE_HTML_COMMAND} + COMMENT "Generating coverage report" + VERBATIM +) diff --git a/cmake/dev-mode.cmake b/cmake/dev-mode.cmake new file mode 100644 index 00000000..73a31fbe --- /dev/null +++ b/cmake/dev-mode.cmake @@ -0,0 +1,32 @@ +include(cmake/folders.cmake) + +include(CTest) +if(BUILD_TESTING) + add_subdirectory(test) +endif() + +add_custom_target( + run-exe + COMMAND lnav + VERBATIM +) +add_dependencies(run-exe lnav) + +option(BUILD_MCSS_DOCS "Build documentation using Doxygen and m.css" OFF) +if(BUILD_MCSS_DOCS) + include(cmake/docs.cmake) +endif() + +option(ENABLE_COVERAGE "Enable coverage support separate from CTest's" OFF) +if(ENABLE_COVERAGE) + include(cmake/coverage.cmake) +endif() + +if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + include(cmake/open-cpp-coverage.cmake OPTIONAL) +endif() + +include(cmake/lint-targets.cmake) +include(cmake/spell-targets.cmake) + +add_folders(Project) diff --git a/cmake/docs-ci.cmake b/cmake/docs-ci.cmake new file mode 100644 index 00000000..ae7f0c73 --- /dev/null +++ b/cmake/docs-ci.cmake @@ -0,0 +1,112 @@ +cmake_minimum_required(VERSION 3.14) + +foreach(var IN ITEMS PROJECT_BINARY_DIR PROJECT_SOURCE_DIR) + if(NOT DEFINED "${var}") + message(FATAL_ERROR "${var} must be defined") + endif() +endforeach() +set(bin "${PROJECT_BINARY_DIR}") +set(src "${PROJECT_SOURCE_DIR}") + +# ---- Dependencies ---- + +set(mcss_SOURCE_DIR "${bin}/docs/.ci") +if(NOT IS_DIRECTORY "${mcss_SOURCE_DIR}") + file(MAKE_DIRECTORY "${mcss_SOURCE_DIR}") + file( + DOWNLOAD + https://github.com/friendlyanon/m.css/releases/download/release-1/mcss.zip + "${mcss_SOURCE_DIR}/mcss.zip" + STATUS status + EXPECTED_MD5 00cd2757ebafb9bcba7f5d399b3bec7f + ) + if(NOT status MATCHES "^0;") + message(FATAL_ERROR "Download failed with ${status}") + endif() + execute_process( + COMMAND "${CMAKE_COMMAND}" -E tar xf mcss.zip + WORKING_DIRECTORY "${mcss_SOURCE_DIR}" + RESULT_VARIABLE result + ) + if(NOT result EQUAL "0") + message(FATAL_ERROR "Extraction failed with ${result}") + endif() + file(REMOVE "${mcss_SOURCE_DIR}/mcss.zip") +endif() + +find_program(Python3_EXECUTABLE NAMES python3 python) +if(NOT Python3_EXECUTABLE) + message(FATAL_ERROR "Python executable was not found") +endif() + +# ---- Process project() call in CMakeLists.txt ---- + +file(READ "${src}/CMakeLists.txt" content) + +string(FIND "${content}" "project(" index) +if(index EQUAL "-1") + message(FATAL_ERROR "Could not find \"project(\"") +endif() +string(SUBSTRING "${content}" "${index}" -1 content) + +string(FIND "${content}" "\n)\n" index) +if(index EQUAL "-1") + message(FATAL_ERROR "Could not find \"\\n)\\n\"") +endif() +string(SUBSTRING "${content}" 0 "${index}" content) + +file(WRITE "${bin}/docs-ci.project.cmake" "docs_${content}\n)\n") + +macro(list_pop_front list out) + list(GET "${list}" 0 "${out}") + list(REMOVE_AT "${list}" 0) +endmacro() + +function(docs_project name) + cmake_parse_arguments(PARSE_ARGV 1 "" "" "VERSION;DESCRIPTION;HOMEPAGE_URL" LANGUAGES) + set(PROJECT_NAME "${name}" PARENT_SCOPE) + if(DEFINED _VERSION) + set(PROJECT_VERSION "${_VERSION}" PARENT_SCOPE) + string(REGEX MATCH "^[0-9]+(\\.[0-9]+)*" versions "${_VERSION}") + string(REPLACE . ";" versions "${versions}") + set(suffixes MAJOR MINOR PATCH TWEAK) + while(NOT versions STREQUAL "" AND NOT suffixes STREQUAL "") + list_pop_front(versions version) + list_pop_front(suffixes suffix) + set("PROJECT_VERSION_${suffix}" "${version}" PARENT_SCOPE) + endwhile() + endif() + if(DEFINED _DESCRIPTION) + set(PROJECT_DESCRIPTION "${_DESCRIPTION}" PARENT_SCOPE) + endif() + if(DEFINED _HOMEPAGE_URL) + set(PROJECT_HOMEPAGE_URL "${_HOMEPAGE_URL}" PARENT_SCOPE) + endif() +endfunction() + +include("${bin}/docs-ci.project.cmake") + +# ---- Generate docs ---- + +if(NOT DEFINED DOXYGEN_OUTPUT_DIRECTORY) + set(DOXYGEN_OUTPUT_DIRECTORY "${bin}/docs") +endif() +set(out "${DOXYGEN_OUTPUT_DIRECTORY}") + +foreach(file IN ITEMS Doxyfile conf.py) + configure_file("${src}/docs/${file}.in" "${bin}/docs/${file}" @ONLY) +endforeach() + +set(mcss_script "${mcss_SOURCE_DIR}/documentation/doxygen.py") +set(config "${bin}/docs/conf.py") + +file(REMOVE_RECURSE "${out}/html" "${out}/xml") + +execute_process( + COMMAND "${Python3_EXECUTABLE}" "${mcss_script}" "${config}" + WORKING_DIRECTORY "${bin}/docs" + RESULT_VARIABLE result +) +if(NOT result EQUAL "0") + message(FATAL_ERROR "m.css returned with ${result}") +endif() diff --git a/cmake/docs.cmake b/cmake/docs.cmake new file mode 100644 index 00000000..e0e99394 --- /dev/null +++ b/cmake/docs.cmake @@ -0,0 +1,40 @@ +# ---- Dependencies ---- + +include(FetchContent) +FetchContent_Declare( + mcss URL + https://github.com/friendlyanon/m.css/releases/download/release-1/mcss.zip + URL_MD5 00cd2757ebafb9bcba7f5d399b3bec7f + SOURCE_DIR "${PROJECT_BINARY_DIR}/mcss" + UPDATE_DISCONNECTED YES +) +FetchContent_MakeAvailable(mcss) + +find_package(Python3 3.6 REQUIRED) + +# ---- Declare documentation target ---- + +set( + DOXYGEN_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/docs" + CACHE PATH "Path for the generated Doxygen documentation" +) + +set(working_dir "${PROJECT_BINARY_DIR}/docs") + +foreach(file IN ITEMS Doxyfile conf.py) + configure_file("docs/${file}.in" "${working_dir}/${file}" @ONLY) +endforeach() + +set(mcss_script "${mcss_SOURCE_DIR}/documentation/doxygen.py") +set(config "${working_dir}/conf.py") + +add_custom_target( + docs + COMMAND "${CMAKE_COMMAND}" -E remove_directory + "${DOXYGEN_OUTPUT_DIRECTORY}/html" + "${DOXYGEN_OUTPUT_DIRECTORY}/xml" + COMMAND "${Python3_EXECUTABLE}" "${mcss_script}" "${config}" + COMMENT "Building documentation using Doxygen and m.css" + WORKING_DIRECTORY "${working_dir}" + VERBATIM +) diff --git a/cmake/folders.cmake b/cmake/folders.cmake new file mode 100644 index 00000000..da7bd33a --- /dev/null +++ b/cmake/folders.cmake @@ -0,0 +1,21 @@ +set_property(GLOBAL PROPERTY USE_FOLDERS YES) + +# Call this function at the end of a directory scope to assign a folder to +# targets created in that directory. Utility targets will be assigned to the +# UtilityTargets folder, otherwise to the ${name}Targets folder. If a target +# already has a folder assigned, then that target will be skipped. +function(add_folders name) + get_property(targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS) + foreach(target IN LISTS targets) + get_property(folder TARGET "${target}" PROPERTY FOLDER) + if(DEFINED folder) + continue() + endif() + set(folder Utility) + get_property(type TARGET "${target}" PROPERTY TYPE) + if(NOT type STREQUAL "UTILITY") + set(folder "${name}") + endif() + set_property(TARGET "${target}" PROPERTY FOLDER "${folder}Targets") + endforeach() +endfunction() diff --git a/cmake/install-rules.cmake b/cmake/install-rules.cmake new file mode 100644 index 00000000..ed43e76c --- /dev/null +++ b/cmake/install-rules.cmake @@ -0,0 +1,44 @@ +include(CMakePackageConfigHelpers) +include(GNUInstallDirs) + +# find_package() call for consumers to find this project +set(package lnav) + +install( + TARGETS lnav + RUNTIME COMPONENT lnav_Runtime +) + +write_basic_package_version_file( + "${package}ConfigVersion.cmake" + COMPATIBILITY SameMajorVersion +) + +# Allow package maintainers to freely override the path for the configs +set( + lnav_INSTALL_CMAKEDIR "${CMAKE_INSTALL_DATADIR}/${package}" + CACHE PATH "CMake package config location relative to the install prefix" +) +mark_as_advanced(lnav_INSTALL_CMAKEDIR) + +install( + FILES "${PROJECT_BINARY_DIR}/${package}ConfigVersion.cmake" + DESTINATION "${lnav_INSTALL_CMAKEDIR}" + COMPONENT lnav_Development +) + +# Export variables for the install script to use +install(CODE " +set(lnav_NAME [[$]]) +set(lnav_INSTALL_CMAKEDIR [[${lnav_INSTALL_CMAKEDIR}]]) +set(CMAKE_INSTALL_BINDIR [[${CMAKE_INSTALL_BINDIR}]]) +" COMPONENT lnav_Development) + +install( + SCRIPT cmake/install-script.cmake + COMPONENT lnav_Development +) + +if(PROJECT_IS_TOP_LEVEL) + include(CPack) +endif() diff --git a/cmake/install-script.cmake b/cmake/install-script.cmake new file mode 100644 index 00000000..6bd0c6e4 --- /dev/null +++ b/cmake/install-script.cmake @@ -0,0 +1,18 @@ +file( + RELATIVE_PATH relative_path + "/${lnav_INSTALL_CMAKEDIR}" + "/${CMAKE_INSTALL_BINDIR}/${lnav_NAME}" +) + +get_filename_component(prefix "${CMAKE_INSTALL_PREFIX}" ABSOLUTE) +set(config_dir "${prefix}/${lnav_INSTALL_CMAKEDIR}") +set(config_file "${config_dir}/lnavConfig.cmake") + +message(STATUS "Installing: ${config_file}") +file(WRITE "${config_file}" "\ +set( + LNAV_EXECUTABLE + \"\${CMAKE_CURRENT_LIST_DIR}/${relative_path}\" + CACHE FILEPATH \"Path to the lnav executable\" +) +") diff --git a/cmake/lint-targets.cmake b/cmake/lint-targets.cmake new file mode 100644 index 00000000..1ffd8c04 --- /dev/null +++ b/cmake/lint-targets.cmake @@ -0,0 +1,32 @@ +set( + FORMAT_PATTERNS + src/*.cc src/*.hh + test/*.cc test/*.hh + CACHE STRING + "; separated patterns relative to the project source dir to format" +) + +set(FORMAT_COMMAND clang-format CACHE STRING "Formatter to use") + +add_custom_target( + format-check + COMMAND "${CMAKE_COMMAND}" + -D "FORMAT_COMMAND=${FORMAT_COMMAND}" + -D "PATTERNS=${FORMAT_PATTERNS}" + -P "${PROJECT_SOURCE_DIR}/cmake/lint.cmake" + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + COMMENT "Linting the code" + VERBATIM +) + +add_custom_target( + format-fix + COMMAND "${CMAKE_COMMAND}" + -D "FORMAT_COMMAND=${FORMAT_COMMAND}" + -D "PATTERNS=${FORMAT_PATTERNS}" + -D FIX=YES + -P "${PROJECT_SOURCE_DIR}/cmake/lint.cmake" + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}" + COMMENT "Fixing the code" + VERBATIM +) diff --git a/cmake/lint.cmake b/cmake/lint.cmake new file mode 100644 index 00000000..32bfdc42 --- /dev/null +++ b/cmake/lint.cmake @@ -0,0 +1,50 @@ +cmake_minimum_required(VERSION 3.14) + +macro(default name) + if(NOT DEFINED "${name}") + set("${name}" "${ARGN}") + endif() +endmacro() + +default(FORMAT_COMMAND clang-format) +default( + PATTERNS + src/*.cc src/*.hh + test/*.cc test/*.hh +) +default(FIX NO) + +set(flag --output-replacements-xml) +set(args OUTPUT_VARIABLE output) +if(FIX) + set(flag -i) + set(args "") +endif() + +file(GLOB_RECURSE files ${PATTERNS}) +set(badly_formatted "") +set(output "") +string(LENGTH "${CMAKE_SOURCE_DIR}/" path_prefix_length) + +foreach(file IN LISTS files) + execute_process( + COMMAND "${FORMAT_COMMAND}" --style=file "${flag}" "${file}" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + RESULT_VARIABLE result + ${args} + ) + if(NOT result EQUAL "0") + message(FATAL_ERROR "'${file}': formatter returned with ${result}") + endif() + if(NOT FIX AND output MATCHES "\nDoxygen, making use of some useful + * special commands. + */ diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 00a9ea14..d6aea8e6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -7,6 +7,7 @@ check_type_size(off_t SIZEOF_OFF_T) check_include_file("pty.h" HAVE_PTY_H) check_include_file("util.h" HAVE_UTIL_H) +check_include_file("execinfo.h" HAVE_EXECINFO_H) set(VCS_PACKAGE_STRING "lnav ${CMAKE_PROJECT_VERSION}") set(PACKAGE_VERSION "${CMAKE_PROJECT_VERSION}") @@ -20,7 +21,7 @@ add_subdirectory(tailer) add_subdirectory(formats/logfmt) add_executable(bin2c bin2c.hh tools/bin2c.c) -target_link_libraries(bin2c ZLIB::zlib) +target_link_libraries(bin2c ZLIB::ZLIB) add_executable(ptimec ptimec.hh ptimec.c) @@ -223,7 +224,7 @@ add_library( add_library( diag STATIC ${GEN_SRCS} - config.h + config.h.in all_logs_vtab.cc ansi_scrubber.cc archive_manager.cc diff --git a/src/base/CMakeLists.txt b/src/base/CMakeLists.txt index 8f97e21d..2165de80 100644 --- a/src/base/CMakeLists.txt +++ b/src/base/CMakeLists.txt @@ -1,6 +1,6 @@ add_library( base STATIC - ../config.h + ../config.h.in auto_pid.cc date_time_scanner.cc fs_util.cc @@ -41,7 +41,7 @@ add_library( target_include_directories(base PUBLIC . .. ../fmtlib ../third-party ${CMAKE_CURRENT_BINARY_DIR}/..) -target_link_libraries(base cppfmt PkgConfig::libpcre) +target_link_libraries(base cppfmt pcre::libpcre ncurses::libcurses) add_executable( test_base @@ -54,5 +54,5 @@ add_executable( network.tcp.tests.cc test_base.cc) target_include_directories(test_base PUBLIC ../third-party/doctest-root) -target_link_libraries(test_base base pcrepp ZLIB::zlib) +target_link_libraries(test_base base pcrepp ZLIB::ZLIB) add_test(NAME test_base COMMAND test_base) diff --git a/src/config.cmake.h.in b/src/config.cmake.h.in index 17aa46e7..054cbba2 100644 --- a/src/config.cmake.h.in +++ b/src/config.cmake.h.in @@ -1,6 +1,8 @@ #define HAVE_PCRE_H #define HAVE_NCURSESW_CURSES_H +#define HAVE_ARCHIVE_H 1 +#define HAVE_BZLIB_H 1 #define HAVE_LIBCURL @@ -14,6 +16,8 @@ #cmakedefine HAVE_UTIL_H +#cmakedefine HAVE_EXECINFO_H + #define HAVE_SQLITE3_STMT_READONLY #define _XOPEN_SOURCE_EXTENDED 1 diff --git a/src/pcrepp/CMakeLists.txt b/src/pcrepp/CMakeLists.txt index ef76a679..e1fdceab 100644 --- a/src/pcrepp/CMakeLists.txt +++ b/src/pcrepp/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(pcrepp STATIC ../config.h pcrepp.hh pcrepp.cc) +add_library(pcrepp STATIC ../config.h.in pcrepp.hh pcrepp.cc) target_include_directories(pcrepp PUBLIC . .. ../fmtlib ${CMAKE_CURRENT_BINARY_DIR}/..) -target_link_libraries(pcrepp PkgConfig::libpcre) +target_link_libraries(pcrepp pcre::libpcre) diff --git a/src/remote/CMakeLists.txt b/src/remote/CMakeLists.txt index c49162b2..a29fbde8 100644 --- a/src/remote/CMakeLists.txt +++ b/src/remote/CMakeLists.txt @@ -1,5 +1,5 @@ -add_library(remote STATIC ../config.h remote.ssh.cc remote.ssh.hh) +add_library(remote STATIC ../config.h.in remote.ssh.cc remote.ssh.hh) target_include_directories(remote PUBLIC . .. ../fmtlib ${CMAKE_CURRENT_BINARY_DIR}/..) -target_link_libraries(remote cppfmt PkgConfig::libpcre) +target_link_libraries(remote cppfmt pcre::libpcre) diff --git a/src/tailer/CMakeLists.txt b/src/tailer/CMakeLists.txt index e7ed21c0..1d1fb15d 100644 --- a/src/tailer/CMakeLists.txt +++ b/src/tailer/CMakeLists.txt @@ -21,4 +21,4 @@ add_executable(drive_tailer drive_tailer.cc) target_include_directories(drive_tailer PUBLIC . .. ../fmtlib ${CMAKE_CURRENT_BINARY_DIR}/..) -target_link_libraries(drive_tailer base tailercommon tailerpp ZLIB::zlib) +target_link_libraries(drive_tailer base tailercommon tailerpp ZLIB::ZLIB) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 42d028c3..4375c3dc 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,10 +5,10 @@ include_directories( ${CMAKE_CURRENT_BINARY_DIR}/../src ${CMAKE_CURRENT_BINARY_DIR}) add_library(testdummy STATIC test_stubs.cc) -target_link_libraries(testdummy PkgConfig::libpcre) +target_link_libraries(testdummy pcre::libpcre ncurses::libcurses) add_executable(test_abbrev test_abbrev.cc) -target_link_libraries(test_abbrev diag PkgConfig::libpcre) +target_link_libraries(test_abbrev diag pcre::libpcre) add_test(NAME test_abbrev COMMAND test_abbrev) add_executable(test_ansi_scrubber test_ansi_scrubber.cc) @@ -16,31 +16,31 @@ target_link_libraries(test_ansi_scrubber diag) add_test(NAME test_ansi_scrubber COMMAND test_ansi_scrubber) add_executable(test_auto_fd test_auto_fd.cc) -target_link_libraries(test_auto_fd diag PkgConfig::libpcre) +target_link_libraries(test_auto_fd diag pcre::libpcre) add_test(NAME test_auto_fd COMMAND test_auto_fd) add_executable(test_auto_mem test_auto_mem.cc) -target_link_libraries(test_auto_mem diag PkgConfig::libpcre) +target_link_libraries(test_auto_mem diag pcre::libpcre) add_test(NAME test_auto_mem COMMAND test_auto_mem) add_executable(test_bookmarks test_bookmarks.cc) -target_link_libraries(test_bookmarks diag PkgConfig::libpcre) +target_link_libraries(test_bookmarks diag pcre::libpcre) add_test(NAME test_bookmarks COMMAND test_bookmarks) add_executable(test_date_time_scanner test_date_time_scanner.cc) -target_link_libraries(test_date_time_scanner diag PkgConfig::libpcre) +target_link_libraries(test_date_time_scanner diag pcre::libpcre) add_test(NAME test_date_time_scanner COMMAND test_date_time_scanner) add_executable(test_grep_proc2 test_grep_proc2.cc) -target_link_libraries(test_grep_proc2 diag PkgConfig::libpcre) +target_link_libraries(test_grep_proc2 diag pcre::libpcre) add_test(NAME test_grep_proc2 COMMAND test_grep_proc2) add_executable(test_line_buffer2 test_line_buffer2.cc) -target_link_libraries(test_line_buffer2 diag BZip2::bz2 ZLIB::zlib) +target_link_libraries(test_line_buffer2 diag BZip2::BZip2 ZLIB::ZLIB) add_test(NAME test_line_buffer2 COMMAND test_line_buffer2) add_executable(test_log_accel test_log_accel.cc) -target_link_libraries(test_log_accel diag PkgConfig::libpcre) +target_link_libraries(test_log_accel diag pcre::libpcre) add_test(NAME test_log_accel COMMAND test_log_accel) add_executable(lnav_doctests lnav_doctests.cc) @@ -49,32 +49,32 @@ target_link_libraries(lnav_doctests diag ${lnav_LIBS}) add_test(NAME lnav_doctests COMMAND lnav_doctests) add_executable(test_pcrepp ../src/pcrepp/test_pcrepp.cc) -target_link_libraries(test_pcrepp diag PkgConfig::libpcre) +target_link_libraries(test_pcrepp diag pcre::libpcre) add_test(NAME test_pcrepp COMMAND test_pcrepp) add_executable(test_reltime test_reltime.cc) target_include_directories(test_reltime PUBLIC ../src/third-party/doctest-root) -target_link_libraries(test_reltime diag PkgConfig::libpcre) +target_link_libraries(test_reltime diag pcre::libpcre) add_test(NAME test_reltime COMMAND test_reltime) add_executable(test_top_status test_top_status.cc) -target_link_libraries(test_top_status diag testdummy PkgConfig::libpcre logfmt) +target_link_libraries(test_top_status diag testdummy pcre::libpcre logfmt) add_test(NAME test_top_status COMMAND test_top_status) add_executable(drive_view_colors drive_view_colors.cc) -target_link_libraries(drive_view_colors diag testdummy PkgConfig::ncursesw) +target_link_libraries(drive_view_colors diag testdummy ncurses::libcurses) add_executable(drive_vt52_curses drive_vt52_curses.cc) -target_link_libraries(drive_vt52_curses diag PkgConfig::ncursesw) +target_link_libraries(drive_vt52_curses diag ncurses::libcurses) add_executable(drive_logfile drive_logfile.cc) -target_link_libraries(drive_logfile diag testdummy PkgConfig::libpcre) +target_link_libraries(drive_logfile diag testdummy pcre::libpcre) add_executable(drive_sql_anno drive_sql_anno.cc) -target_link_libraries(drive_sql_anno diag testdummy PkgConfig::libpcre) +target_link_libraries(drive_sql_anno diag testdummy pcre::libpcre) add_executable(drive_data_scanner drive_data_scanner.cc) -target_link_libraries(drive_data_scanner diag testdummy PkgConfig::libpcre logfmt) +target_link_libraries(drive_data_scanner diag testdummy pcre::libpcre logfmt) add_executable(scripty scripty.cc) -target_link_libraries(scripty diag PkgConfig::ncursesw) +target_link_libraries(scripty diag ncurses::libcurses)