basic template

This commit is contained in:
2025-08-05 11:51:38 -03:00
commit cda7a68e0e
14 changed files with 967 additions and 0 deletions

235
.clang-format Normal file
View File

@@ -0,0 +1,235 @@
---
Language: Cpp
# BasedOnStyle: LLVM
AccessModifierOffset: -2
AlignAfterOpenBracket: Align
AlignArrayOfStructures: None
AlignConsecutiveAssignments:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: true
AlignConsecutiveBitFields:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveDeclarations:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveMacros:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCompound: false
PadOperators: false
AlignConsecutiveShortCaseStatements:
Enabled: false
AcrossEmptyLines: false
AcrossComments: false
AlignCaseColons: false
AlignEscapedNewlines: Right
AlignOperands: Align
AlignTrailingComments:
Kind: Always
OverEmptyLines: 0
AllowAllArgumentsOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortEnumsOnASingleLine: true
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLambdasOnASingleLine: All
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
AttributeMacros:
- __capability
BinPackArguments: true
BinPackParameters: true
BitFieldColonSpacing: Both
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterExternBlock: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
BeforeLambdaBody: false
BeforeWhile: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakAfterAttributes: Never
BreakAfterJavaFieldAnnotations: false
BreakArrays: true
BreakBeforeBinaryOperators: None
BreakBeforeConceptDeclarations: Always
BreakBeforeBraces: Attach
BreakBeforeInlineASMColon: OnlyMultiline
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: true
ColumnLimit: 128
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
EmptyLineAfterAccessModifier: Never
EmptyLineBeforeAccessModifier: LogicalBlock
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: true
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IfMacros:
- KJ_IF_MAYBE
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
SortPriority: 0
CaseSensitive: false
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
SortPriority: 0
CaseSensitive: false
- Regex: '.*'
Priority: 1
SortPriority: 0
CaseSensitive: false
IncludeIsMainRegex: '(Test)?$'
IncludeIsMainSourceRegex: ''
IndentAccessModifiers: false
IndentCaseBlocks: false
IndentCaseLabels: false
IndentExternBlock: AfterExternBlock
IndentGotoLabels: true
IndentPPDirectives: None
IndentRequiresClause: true
IndentWidth: 2
IndentWrappedFunctionNames: false
InsertBraces: false
InsertNewlineAtEOF: false
InsertTrailingCommas: None
IntegerLiteralSeparator:
Binary: 0
BinaryMinDigits: 0
Decimal: 0
DecimalMinDigits: 0
Hex: 0
HexMinDigits: 0
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
KeepEmptyLinesAtEOF: false
LambdaBodyIndentation: Signature
LineEnding: DeriveLF
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 2
ObjCBreakBeforeNestedBlockParam: true
ObjCSpaceAfterProperty: false
ObjCSpaceBeforeProtocolList: true
PackConstructorInitializers: BinPack
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakOpenParenthesis: 0
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyIndentedWhitespace: 0
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
PPIndentWidth: -1
QualifierAlignment: Leave
ReferenceAlignment: Pointer
ReflowComments: true
RemoveBracesLLVM: false
RemoveParentheses: Leave
RemoveSemicolon: false
RequiresClausePosition: OwnLine
RequiresExpressionIndentation: OuterScope
SeparateDefinitionBlocks: Leave
ShortNamespaceLines: 1
SortIncludes: CaseSensitive
SortJavaStaticImport: Before
SortUsingDeclarations: LexicographicNumeric
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceAroundPointerQualifiers: Default
SpaceBeforeAssignmentOperators: true
SpaceBeforeCaseColon: false
SpaceBeforeCpp11BracedList: false
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeJsonColon: false
SpaceBeforeParens: ControlStatements
SpaceBeforeParensOptions:
AfterControlStatements: true
AfterForeachMacros: true
AfterFunctionDefinitionName: false
AfterFunctionDeclarationName: false
AfterIfMacros: true
AfterOverloadedOperator: false
AfterRequiresInClause: false
AfterRequiresInExpression: false
BeforeNonEmptyParentheses: false
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: Never
SpacesInContainerLiterals: true
SpacesInLineCommentPrefix:
Minimum: 1
Maximum: -1
SpacesInParens: Never
SpacesInParensOptions:
InCStyleCasts: false
InConditionalStatements: false
InEmptyParentheses: false
Other: false
SpacesInSquareBrackets: false
Standard: Latest
StatementAttributeLikeMacros:
- Q_EMIT
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 8
UseTab: Never
VerilogBreakBetweenInstancePorts: true
WhitespaceSensitiveMacros:
- BOOST_PP_STRINGIZE
- CF_SWIFT_NAME
- NS_SWIFT_NAME
- PP_STRINGIZE
- STRINGIZE
...

3
.clang-tidy Normal file
View File

@@ -0,0 +1,3 @@
Checks: "-*,performance-*,readability-*,bugprone-*,clang-analyzer-*,cppcoreguidelines-*,mpi-*,misc-*"
WarningsAsErrors: "*"
FormatStyle: none

247
.cmake-format.yaml Normal file
View File

@@ -0,0 +1,247 @@
_help_parse: Options affecting listfile parsing
parse:
_help_additional_commands:
- Specify structure for custom cmake functions
additional_commands:
foo:
flags:
- BAR
- BAZ
kwargs:
HEADERS: '*'
SOURCES: '*'
DEPENDS: '*'
_help_override_spec:
- Override configurations per-command where available
override_spec: {}
_help_vartags:
- Specify variable tags.
vartags: []
_help_proptags:
- Specify property tags.
proptags: []
_help_format: Options affecting formatting.
format:
_help_disable:
- Disable formatting entirely, making cmake-format a no-op
disable: false
_help_line_width:
- How wide to allow formatted cmake files
line_width: 128
_help_tab_size:
- How many spaces to tab for indent
tab_size: 2
_help_use_tabchars:
- If true, lines are indented using tab characters (utf-8
- 0x09) instead of <tab_size> space characters (utf-8 0x20).
- In cases where the layout would require a fractional tab
- character, the behavior of the fractional indentation is
- governed by <fractional_tab_policy>
use_tabchars: false
_help_fractional_tab_policy:
- If <use_tabchars> is True, then the value of this variable
- indicates how fractional indentions are handled during
- whitespace replacement. If set to 'use-space', fractional
- indentation is left as spaces (utf-8 0x20). If set to
- '`round-up` fractional indentation is replaced with a single'
- tab character (utf-8 0x09) effectively shifting the column
- to the next tabstop
fractional_tab_policy: use-space
_help_max_subgroups_hwrap:
- If an argument group contains more than this many sub-groups
- (parg or kwarg groups) then force it to a vertical layout.
max_subgroups_hwrap: 3
_help_max_pargs_hwrap:
- If a positional argument group contains more than this many
- arguments, then force it to a vertical layout.
max_pargs_hwrap: 6
_help_max_rows_cmdline:
- If a cmdline positional group consumes more than this many
- lines without nesting, then invalidate the layout (and nest)
max_rows_cmdline: 2
_help_separate_ctrl_name_with_space:
- If true, separate flow control names from their parentheses
- with a space
separate_ctrl_name_with_space: false
_help_separate_fn_name_with_space:
- If true, separate function names from parentheses with a
- space
separate_fn_name_with_space: false
_help_dangle_parens:
- If a statement is wrapped to more than one line, than dangle
- the closing parenthesis on its own line.
dangle_parens: false
_help_dangle_align:
- If the trailing parenthesis must be 'dangled' on its on
- 'line, then align it to this reference: `prefix`: the start'
- 'of the statement, `prefix-indent`: the start of the'
- 'statement, plus one indentation level, `child`: align to'
- the column of the arguments
dangle_align: prefix
_help_min_prefix_chars:
- If the statement spelling length (including space and
- parenthesis) is smaller than this amount, then force reject
- nested layouts.
min_prefix_chars: 4
_help_max_prefix_chars:
- If the statement spelling length (including space and
- parenthesis) is larger than the tab width by more than this
- amount, then force reject un-nested layouts.
max_prefix_chars: 10
_help_max_lines_hwrap:
- If a candidate layout is wrapped horizontally but it exceeds
- this many lines, then reject the layout.
max_lines_hwrap: 3
_help_line_ending:
- What style line endings to use in the output.
line_ending: unix
_help_command_case:
- Format command names consistently as 'lower' or 'upper' case
command_case: canonical
_help_keyword_case:
- Format keywords consistently as 'lower' or 'upper' case
keyword_case: unchanged
_help_always_wrap:
- A list of command names which should always be wrapped
always_wrap: []
_help_enable_sort:
- If true, the argument lists which are known to be sortable
- will be sorted lexicographicall
enable_sort: true
_help_autosort:
- If true, the parsers may infer whether or not an argument
- list is sortable (without annotation).
autosort: false
_help_require_valid_layout:
- By default, if cmake-format cannot successfully fit
- everything into the desired linewidth it will apply the
- last, most aggressive attempt that it made. If this flag is
- True, however, cmake-format will print error, exit with non-
- zero status code, and write-out nothing
require_valid_layout: false
_help_layout_passes:
- A dictionary mapping layout nodes to a list of wrap
- decisions. See the documentation for more information.
layout_passes: {}
_help_markup: Options affecting comment reflow and formatting.
markup:
_help_bullet_char:
- What character to use for bulleted lists
bullet_char: '*'
_help_enum_char:
- What character to use as punctuation after numerals in an
- enumerated list
enum_char: .
_help_first_comment_is_literal:
- If comment markup is enabled, don't reflow the first comment
- block in each listfile. Use this to preserve formatting of
- your copyright/license statements.
first_comment_is_literal: false
_help_literal_comment_pattern:
- If comment markup is enabled, don't reflow any comment block
- which matches this (regex) pattern. Default is `None`
- (disabled).
literal_comment_pattern: null
_help_fence_pattern:
- Regular expression to match preformat fences in comments
- default= ``r'^\s*([`~]{3}[`~]*)(.*)$'``
fence_pattern: ^\s*([`~]{3}[`~]*)(.*)$
_help_ruler_pattern:
- Regular expression to match rulers in comments default=
- '``r''^\s*[^\w\s]{3}.*[^\w\s]{3}$''``'
ruler_pattern: ^\s*[^\w\s]{3}.*[^\w\s]{3}$
_help_explicit_trailing_pattern:
- If a comment line matches starts with this pattern then it
- is explicitly a trailing comment for the preceding
- argument. Default is '#<'
explicit_trailing_pattern: '#<'
_help_hashruler_min_length:
- If a comment line starts with at least this many consecutive
- hash characters, then don't lstrip() them off. This allows
- for lazy hash rulers where the first hash char is not
- separated by space
hashruler_min_length: 10
_help_canonicalize_hashrulers:
- If true, then insert a space between the first hash char and
- remaining hash chars in a hash ruler, and normalize its
- length to fill the column
canonicalize_hashrulers: true
_help_enable_markup:
- enable comment markup parsing and reflow
enable_markup: false
_help_lint: Options affecting the linter
lint:
_help_disabled_codes:
- a list of lint codes to disable
disabled_codes: []
_help_function_pattern:
- regular expression pattern describing valid function names
function_pattern: '[0-9a-z_]+'
_help_macro_pattern:
- regular expression pattern describing valid macro names
macro_pattern: '[0-9A-Z_]+'
_help_global_var_pattern:
- regular expression pattern describing valid names for
- variables with global (cache) scope
global_var_pattern: '[A-Z][0-9A-Z_]+'
_help_internal_var_pattern:
- regular expression pattern describing valid names for
- variables with global scope (but internal semantic)
internal_var_pattern: _[A-Z][0-9A-Z_]+
_help_local_var_pattern:
- regular expression pattern describing valid names for
- variables with local scope
local_var_pattern: '[a-z][a-z0-9_]+'
_help_private_var_pattern:
- regular expression pattern describing valid names for
- privatedirectory variables
private_var_pattern: _[0-9a-z_]+
_help_public_var_pattern:
- regular expression pattern describing valid names for public
- directory variables
public_var_pattern: '[A-Z][0-9A-Z_]+'
_help_argument_var_pattern:
- regular expression pattern describing valid names for
- function/macro arguments and loop variables.
argument_var_pattern: '[a-z][a-z0-9_]+'
_help_keyword_pattern:
- regular expression pattern describing valid names for
- keywords used in functions or macros
keyword_pattern: '[A-Z][0-9A-Z_]+'
_help_max_conditionals_custom_parser:
- In the heuristic for C0201, how many conditionals to match
- within a loop in before considering the loop a parser.
max_conditionals_custom_parser: 2
_help_min_statement_spacing:
- Require at least this many newlines between statements
min_statement_spacing: 1
_help_max_statement_spacing:
- Require no more than this many newlines between statements
max_statement_spacing: 2
max_returns: 6
max_branches: 12
max_arguments: 5
max_localvars: 15
max_statements: 50
_help_encode: Options affecting file encoding
encode:
_help_emit_byteorder_mark:
- If true, emit the unicode byte-order mark (BOM) at the start
- of the file
emit_byteorder_mark: false
_help_input_encoding:
- Specify the encoding of the input file. Defaults to utf-8
input_encoding: utf-8
_help_output_encoding:
- Specify the encoding of the output file. Defaults to utf-8.
- Note that cmake only claims to support utf-8 so be careful
- when using anything else
output_encoding: utf-8
_help_misc: Miscellaneous configurations options.
misc:
_help_per_command:
- A dictionary containing any per-command configuration
- overrides. Currently only `command_case` is supported.
per_command: {}

6
.codespellrc Normal file
View File

@@ -0,0 +1,6 @@
[codespell]
skip = ./build,.git,.cache
check-hidden =
check-filenames =
count =
write-changes =

107
.gitignore vendored Normal file
View File

@@ -0,0 +1,107 @@
# Development
.stignore
.stfolder/
.cache/
var/
# ---> C++
# Prerequisites
*.d
# Compiled Object files
*.slo
*.lo
*.o
*.obj
# Precompiled Headers
*.gch
*.pch
# Compiled Dynamic libraries
*.so
*.dylib
*.dll
# Fortran module files
*.mod
*.smod
# Compiled Static libraries
*.lai
*.la
*.a
*.lib
# Executables
*.exe
*.out
*.app
# ---> CMake
CMakeLists.txt.user
CMakeCache.txt
CMakeFiles
CMakeScripts
Testing
Makefile
cmake_install.cmake
install_manifest.txt
compile_commands.json
CTestTestfile.cmake
_deps
build
# ---> C
# Prerequisites
*.d
# Object files
*.o
*.ko
*.obj
*.elf
# Linker output
*.ilk
*.map
*.exp
# Precompiled Headers
*.gch
*.pch
# Libraries
*.lib
*.a
*.la
*.lo
# Shared objects (inc. Windows DLLs)
*.dll
*.so
*.so.*
*.dylib
# Executables
*.exe
*.out
*.app
*.i*86
*.x86_64
*.hex
# Debug files
*.dSYM/
*.su
*.idb
*.pdb
# Kernel Module Compile Results
*.mod*
*.cmd
.tmp_versions/
modules.order
Module.symvers
Mkfile.old
dkms.conf

24
.pre-commit-config.yaml Normal file
View File

@@ -0,0 +1,24 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v5.0.0
hooks:
- id: trailing-whitespace
exclude: ^patches/
- id: end-of-file-fixer
exclude: ^patches/
- id: check-added-large-files
- id: check-toml
- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
- id: codespell
- repo: https://github.com/commitizen-tools/commitizen
rev: v4.8.2
hooks:
- id: commitizen
- id: commitizen-branch
stages: [pre-push]
- repo: https://github.com/gitleaks/gitleaks
rev: v8.27.0
hooks:
- id: gitleaks

47
CMakeLists.txt Normal file
View File

@@ -0,0 +1,47 @@
cmake_minimum_required(VERSION 3.30 FATAL_ERROR)
cmake_policy(VERSION 3.30)
project(c-template LANGUAGES C)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
option(BUILD_TESTS "Build tests" OFF)
option(BUILD_DOCS "Build documentation" OFF)
option(DISABLE_LOGGING "Disables all logging" OFF)
option(DO_NOT_INCREASE_VERSION "Disable custom target that automatically increases version" OFF)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
include(CheckCompileOptions)
include(FetchZlog)
include(FetchArgparse)
if(BUILD_TESTS)
enable_testing()
include(FetchGoogleTest)
add_subdirectory(tests)
endif()
if(DISABLE_LOGGING)
message(STATUS "Disabling all logs")
add_compile_definitions("PLOG_DISABLE_LOGGING=1")
endif()
if(BUILD_DOCS)
message(STATUS "Building documentation")
add_subdirectory(docs)
endif()
if(NOT DO_NOT_INCREASE_VERSION)
add_custom_target(
run_versioning_script
COMMAND ${CMAKE_COMMAND} -E echo "$$(date +%s)" > "${CMAKE_CURRENT_BINARY_DIR}/update_versioning_signal"
COMMAND ${PROJECT_SOURCE_DIR}/scripts/versioning.sh patch
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
COMMENT "Running versioning script")
add_dependencies(${PROJECT_NAME} run_versioning_script)
endif()
add_subdirectory(include)
add_subdirectory(src)

View File

@@ -0,0 +1,151 @@
include(CheckCompilerFlag)
include(CheckLinkerFlag)
set(COMPILE_FLAGS "")
set(LINK_FLAGS "")
function(check_and_add_compiler_flags flags_list)
set(supported_flags)
foreach(flag ${flags_list})
string(REPLACE ";" "_" flag_var ${flag})
check_compiler_flag(C "${flag}" "HAVE_FLAG_${flag_var}")
if(HAVE_FLAG_${flag_var})
list(APPEND supported_flags ${flag})
endif()
endforeach()
set(COMPILE_FLAGS
${supported_flags}
PARENT_SCOPE)
endfunction()
function(check_and_add_linker_flags flags_list)
set(supported_flags)
foreach(flag ${flags_list})
string(REPLACE ";" "_" flag_var ${flag})
check_linker_flag(C "${flag}" "HAVE_LINKER_FLAG_${flag_var}")
if(HAVE_LINKER_FLAG_${flag_var})
list(APPEND supported_flags ${flag})
endif()
endforeach()
set(LINK_FLAGS
${supported_flags}
PARENT_SCOPE)
endfunction()
set(GENERAL_COMPILE_FLAGS
# Enable warnings for constructs often associated with defects
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-additional-format-function-warnings
"-Wall"
"-Wextra"
# Enable additional format function warnings
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-additional-format-function-warnings
"-Wformat=2"
"-Wformat-security"
# Enable implicit conversion warnings
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-implicit-conversion-warnings
"-Wconversion"
"-Wsign-conversion"
# Enable warning about trampolines that require executable stacks
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-warning-about-trampolines-that-require-executable-stacks
"-Wtrampolines"
# Warn about implicit fallthrough in switch statements
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#warn-about-implicit-fallthrough-in-switch-statements
"-Wimplicit-fallthrough"
# Treat obsolete C constructs as errors
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#-Werror=implicit
"-Werror=implicit"
"-Werror=incompatible-pointer-types"
"-Werror=int-conversion"
"-g")
# Flags enabled only on Release Mode
set(RELEASE_COMPILE_FLAGS
# Keeps only relevant symbols available to the library users
"-fvisibility=hidden"
"-fvisibility-inlines-hidden"
"-ffunction-sections"
"-fdata-sections"
# Enable code instrumentation of control-flow transfers to increase program
# security by checking that target addresses of control-flow transfer
# instructions are valid
# https://gcc.gnu.org/onlinedocs/gcc/Instrumentation-Options.html#index-fcf-protection
"-fcf-protection=full"
# Enable run-time checks for stack-based buffer overflows
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-run-time-checks-for-stack-based-buffer-overflows
"-fstack-protector-strong"
# Build as position-independent code
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#build-as-position-independent-code
"-fPIE"
# Enable run-time checks for variable-size stack allocation validity
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-run-time-checks-for-variable-size-stack-allocation-validity
"-fstack-clash-protection"
# Enable strict flexible arrays
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-strict-flexible-arrays
"-fstrict-flex-arrays=3"
# Precondition checks for C++ standard library calls
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#precondition-checks-for-c-standard-library-calls
"-D_GLIBCXX_ASSERTIONS"
# Do not delete null pointer checks
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#do-not-delete-null-pointer-checks
"-fno-delete-null-pointer-checks"
# Integer overflow may occur
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#integer-overflow-may-occur
"-fno-strict-overflow"
# Do not assume strict aliasing
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#do-not-assume-strict-aliasing
"-fno-strict-aliasing"
# Perform trivial auto variable initialization
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#perform-trivial-auto-variable-initialization
"-ftrivial-auto-var-init=zero"
# Enable exception propagation to harden multi-threaded C code
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-exception-propagation-to-harden-multi-threaded-c-code
"-fexceptions"
# Fortify sources for unsafe libc usage and buffer overflows
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#fortify-sources-for-unsafe-libc-usage-and-buffer-overflows
"-U_FORTIFY_SOURCE"
"-D_FORTIFY_SOURCE=3"
"-flto")
set(RELEASE_LINKER_FLAGS
"-Wl,-z,relro,-z,now"
# Enable data execution prevention
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#enable-data-execution-prevention
"-Wl,-z,noexecstack"
# Restrict dlopen calls to shared objects
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#restrict-dlopen-calls-to-shared-objects
"-Wl,-z,nodlopen"
# Allow linker to omit libraries specified on the command line to link
# against if they are not used
# https://best.openssf.org/Compiler-Hardening-Guides/Compiler-Options-Hardening-Guide-for-C-and-C++.html#allow-linker-to-omit-libraries-specified-on-the-command-line-to-link-against-if-they-are-not-used
"-Wl,--as-needed"
"-Wl,--no-copy-dt-needed-entries"
"--strip-all"
"-pie")
# Flags enabled only on Debug Mode
set(DEBUG_COMPILE_FLAGS "-Og" "-fno-omit-frame-pointer"
"-fno-optimize-sibling-calls" "-fno-common")
set(DEBUG_LINKER_FLAGS "-rdynamic")
set(CONFIG_COMPILE_FLAGS ${GENERAL_COMPILE_FLAGS})
set(CONFIG_LINKER_FLAGS ${GENERAL_LINKER_FLAGS})
if(NOT CMAKE_BUILD_TYPE EQUAL "Debug")
list(APPEND CONFIG_COMPILE_FLAGS ${RELEASE_COMPILE_FLAGS})
list(APPEND CONFIG_LINKER_FLAGS ${RELEASE_LINKER_FLAGS})
elseif(CMAKE_BUILD_TYPE STREQUAL "Debug")
list(APPEND CONFIG_COMPILE_FLAGS ${DEBUG_COMPILE_FLAGS})
list(APPEND CONFIG_LINKER_FLAGS ${DEBUG_LINKER_FLAGS})
else()
message(
WARNING
"Unknown build type: ${CMAKE_BUILD_TYPE}. Using Debug flags by default.")
list(APPEND CONFIG_COMPILE_FLAGS ${DEBUG_COMPILE_FLAGS})
list(APPEND CONFIG_LINKER_FLAGS ${DEBUG_LINKER_FLAGS})
endif()
check_and_add_compiler_flags("${CONFIG_COMPILE_FLAGS}")
check_and_add_linker_flags("${CONFIG_LINKER_FLAGS}")
message(STATUS "Compile flags for ${CMAKE_BUILD_TYPE}: ${COMPILE_FLAGS}")
message(STATUS "Linker flags for ${CMAKE_BUILD_TYPE}: ${LINK_FLAGS}")

35
cmake/FetchArgparse.cmake Normal file
View File

@@ -0,0 +1,35 @@
include(FetchContent)
option(STATIC_ARGPARSE "Statically build and link argparse" ON)
if(NOT ARGPARSE_VERSION)
set(ARGPARSE_VERSION "682d4520b4bc2b646cdfcf078b2fed00b3d2da30")
endif()
message(STATUS "Fetching and configuring argparse version ${ARGPARSE_VERSION}")
set(FETCHCONTENT_QUIET TRUE)
if(STATIC_ARGPARSE)
set(ARGPARSE_STATIC ON CACHE STRING "" FORCE)
set(ARGPARSE_SHARED OFF CACHE STRING "" FORCE)
else()
set(ARGPARSE_STATIC OFF CACHE STRING "" FORCE)
set(ARGPARSE_SHARED ON CACHE STRING "" FORCE)
endif()
FetchContent_Declare(
argparse
GIT_REPOSITORY https://github.com/cofyc/argparse.git
GIT_TAG ${ARGPARSE_VERSION}
GIT_PROGRESS TRUE
OVERRIDE_FIND_PACKAGE)
FetchContent_MakeAvailable(argparse)
if(TARGET argparse_shared)
target_compile_options(argparse_shared PRIVATE ${COMPILE_FLAGS})
target_link_options(argparse_shared PRIVATE "${LINK_FLAGS}")
endif()
if(TARGET argparse_static)
target_compile_options(argparse_static PRIVATE ${COMPILE_FLAGS})
target_link_options(argparse_static PRIVATE "${LINK_FLAGS}")
endif()

View File

@@ -0,0 +1,14 @@
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.8.x # 1.8.x works with pré C++11 compilers, which allows us to compile tests for toolchains
GIT_SHALLOW TRUE
OVERRIDE_FIND_PACKAGE)
FetchContent_MakeAvailable(googletest)
# Workaround for warning treated as error in gtest
# https://stackoverflow.com/a/75379860
target_compile_options(gtest PRIVATE "-w")

25
cmake/FetchZlog.cmake Normal file
View File

@@ -0,0 +1,25 @@
include(FetchContent)
FetchContent_Declare(
zlog
GIT_REPOSITORY https://github.com/HardySimpson/zlog
GIT_TAG 1.2.18
GIT_SHALLOW TRUE
# This patch fixes leak: https://github.com/HardySimpson/zlog/issues/256
PATCH_COMMAND git fetch origin pull/285/head:pr285 && git merge pr285)
FetchContent_MakeAvailable(zlog)
target_compile_options(zlog PRIVATE "-fPIC")
target_compile_options(zlog_s PRIVATE "-fPIE")
# Install zlog automatically after build
set(zlog_INSTALL_DIR ${FETCHCONTENT_BASE_DIR}/zlog-install/)
add_custom_target(
zlog_copy_header ALL
COMMAND ${CMAKE_COMMAND} -E copy ${zlog_SOURCE_DIR}/src/zlog.h
${zlog_BINARY_DIR}/include/zlog.h
DEPENDS zlog
COMMENT "Installing zlog into ${zlog_INSTALL_DIR}")
# Add the install directory to include and link paths
target_include_directories(zlog_s PUBLIC ${zlog_BINARY_DIR}/include)
target_include_directories(zlog PUBLIC ${zlog_BINARY_DIR}/include)

48
scripts/versioning.sh Normal file
View File

@@ -0,0 +1,48 @@
#!/bin/bash
set -e
# Script to Bump Version Numbers and Update File metadata
# This script updates the version numbers of a C/C++ project, specifically in `version.hpp` or `version.h`,
#and also updates information about compilation commits and build timestamps.
VERSION_FILE="$(find "$PWD" \( -iname "version.hpp" -o -iname "version.h" \) -not -path "$PWD/build/*")"
MAJOR=$(grep -oP '([a-zA-Z]*)_VERSION_MAJOR (\K[0-9]+)' "$VERSION_FILE")
MINOR=$(grep -oP '([a-zA-Z]*)_VERSION_MINOR (\K[0-9]+)' "$VERSION_FILE")
PATCH=$(grep -oP '([a-zA-Z]*)_VERSION_PATCH (\K[0-9]+)' "$VERSION_FILE")
_update_version_file() {
sed -i "s/\([a-zA-Z]\+\)_VERSION_MAJOR \([0-9]\+\)$/\1_VERSION_MAJOR $MAJOR/" "$VERSION_FILE"
sed -i "s/\([a-zA-Z]\+\)_VERSION_MINOR \([0-9]\+\)$/\1_VERSION_MINOR $MINOR/" "$VERSION_FILE"
sed -i "s/\([a-zA-Z]\+\)_VERSION_PATCH \([0-9]\+\)$/\1_VERSION_PATCH $PATCH/" "$VERSION_FILE"
COMMIT_HASH=$(git rev-parse HEAD)
BUILD_TIMESTAMP=$(date +%s)
sed -i "s/\([a-zA-Z]\+\)_COMMIT_HASH \"[a-zA-Z0-9]\+\"/\1_COMMIT_HASH \"$COMMIT_HASH\"/" "$VERSION_FILE"
sed -i "s/\([a-zA-Z]\+\)_BUILD_TIMESTAMP [0-9]\+/\1_BUILD_TIMESTAMP $BUILD_TIMESTAMP/" "$VERSION_FILE"
}
_command() {
case "$1" in
major)
MAJOR=$((MAJOR + 1))
_update_version_file
;;
minor)
MINOR=$((MINOR + 1))
_update_version_file
;;
patch)
PATCH=$((PATCH + 1))
_update_version_file
;;
print)
printf "%s.%s.%s" "$MAJOR" "$MINOR" "$PATCH"
;;
*)
echo "Unknown version semantic $1" >&2
exit 124
;;
esac
}
[ "$#" -gt 0 ] && _command "$1"

19
src/CMakeLists.txt Normal file
View File

@@ -0,0 +1,19 @@
add_executable(c-template main.c)
set_target_properties(
c-template PROPERTIES ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib" LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
execute_process(COMMAND ${PROJECT_SOURCE_DIR}/scripts/versioning.sh print WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
OUTPUT_VARIABLE MULTIPERF_VERSION)
message(STATUS "Building [${PROJECT_NAME}] version ${MULTIPERF_VERSION}")
target_compile_options(multiperf PRIVATE "${COMPILE_FLAGS}")
target_link_options(multiperf PRIVATE "${LINK_FLAGS}")
file(GLOB C_FILES CONFIGURE_DEPENDS *.c)
file(GLOB H_FILES CONFIGURE_DEPENDS *.h)
target_sources(c-template PRIVATE ${C_FILES} PUBLIC ${H_FILES})
target_include_directories(c-template PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(c-template cargs zlog_s)

6
src/main.c Normal file
View File

@@ -0,0 +1,6 @@
#include <stdlib.h>
int main(int argc, char *argv[])
{
return EXIT_SUCCESS;
}