Skip to content

Commit b518946

Browse files
committed
Make: Harden builds
1 parent 78e1f3d commit b518946

File tree

7 files changed

+193
-84
lines changed

7 files changed

+193
-84
lines changed

.github/workflows/prerelease.yml

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,9 @@ jobs:
4747
CXX: g++
4848

4949
steps:
50-
- uses: actions/checkout@v4
51-
- run: git submodule update --init --recursive
50+
- name: Checkout
51+
uses: actions/checkout@v4
5252

53-
# C/C++
5453
- name: Build C/C++
5554
run: |
5655
sudo apt update
@@ -62,7 +61,6 @@ jobs:
6261
build_artifacts/fork_union_test_cpp17
6362
build_artifacts/fork_union_test_cpp20
6463
65-
# Rust
6664
- name: Set up Rust
6765
run: |
6866
rustup update stable
@@ -81,8 +79,8 @@ jobs:
8179
CXX: clang++
8280

8381
steps:
84-
- uses: actions/checkout@v4
85-
- run: git submodule update --init --recursive
82+
- name: Checkout
83+
uses: actions/checkout@v4
8684

8785
# C/C++
8886
# Clang 16 isn't available from default repos on Ubuntu 22.04, so we have to install it manually
@@ -97,7 +95,6 @@ jobs:
9795
build_artifacts/fork_union_test_cpp17
9896
build_artifacts/fork_union_test_cpp20
9997
100-
# Rust
10198
- name: Set up Rust
10299
run: |
103100
rustup update stable
@@ -113,10 +110,9 @@ jobs:
113110
runs-on: macos-14
114111

115112
steps:
116-
- uses: actions/checkout@v4
117-
- run: git submodule update --init --recursive
113+
- name: Checkout
114+
uses: actions/checkout@v4
118115

119-
# C/C++
120116
- name: Build C/C++
121117
run: |
122118
brew update
@@ -128,7 +124,6 @@ jobs:
128124
build_artifacts/fork_union_test_cpp17
129125
build_artifacts/fork_union_test_cpp20
130126
131-
# Rust
132127
- name: Set up Rust
133128
run: |
134129
rustup update stable
@@ -143,10 +138,9 @@ jobs:
143138
name: Windows
144139
runs-on: windows-2022
145140
steps:
146-
- uses: actions/checkout@v4
147-
- run: git submodule update --init --recursive
141+
- name: Checkout
142+
uses: actions/checkout@v4
148143

149-
# C/C++
150144
- name: Build C/C++
151145
run: |
152146
choco install cmake
@@ -159,7 +153,6 @@ jobs:
159153
.\build_artifacts\fork_union_test_cpp17.exe
160154
.\build_artifacts\fork_union_test_cpp20.exe
161155
162-
# Rust
163156
- name: Set up Rust
164157
run: |
165158
rustup update stable

.github/workflows/release.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ jobs:
7777
- uses: actions/checkout@v4
7878
with:
7979
ref: "main"
80-
- run: git submodule update --init --recursive
80+
8181
- uses: actions-rs/toolchain@v1
8282
with:
8383
toolchain: nightly

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
# Build directories
3535
build/
36+
build_test/
3637
build_debug/
3738
build_release/
3839
Testing/

CMakeLists.txt

Lines changed: 137 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,16 @@
11
cmake_minimum_required(VERSION 3.14)
22

3+
# Set modern CMake policies for better compatibility
4+
if (POLICY CMP0077)
5+
cmake_policy(SET CMP0077 NEW) # option() honors normal variables
6+
endif ()
7+
if (POLICY CMP0079)
8+
cmake_policy(SET CMP0079 NEW) # target_link_libraries() allows use with targets in other directories
9+
endif ()
10+
if (POLICY CMP0091)
11+
cmake_policy(SET CMP0091 NEW) # MSVC runtime library flags are selected by an abstraction
12+
endif ()
13+
314
project(
415
fork_union
516
VERSION 2.2.0
@@ -18,11 +29,78 @@ target_include_directories(
1829
fork_union INTERFACE $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>
1930
)
2031

21-
# Strict compilation flags
32+
# Set C++17 requirement and features properly for library consumers
33+
target_compile_features(fork_union INTERFACE cxx_std_17)
34+
set_target_properties(
35+
fork_union
36+
PROPERTIES CXX_STANDARD 17
37+
CXX_STANDARD_REQUIRED ON
38+
CXX_EXTENSIONS OFF
39+
)
40+
41+
# Strictest possible compilation flags with fatal warnings
2242
target_compile_options(
23-
fork_union INTERFACE
24-
$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall -Wextra -Wpedantic -Wconversion -Wcast-qual -Wcast-align -Wunused -Wno-unused-parameter -Wno-unknown-pragmas -Wno-sign-conversion -Wno-unused-function>
25-
$<$<CXX_COMPILER_ID:MSVC>:/W4 /permissive->
43+
fork_union
44+
INTERFACE # GCC/Clang: Maximum warnings + treat warnings as errors + security hardening
45+
$<$<CXX_COMPILER_ID:GNU,Clang>:-Wall
46+
-Wextra
47+
-Wpedantic
48+
-Werror
49+
-Wconversion
50+
-Wcast-qual
51+
-Wcast-align
52+
-Wunused
53+
-Wno-unused-parameter
54+
-Wno-unknown-pragmas
55+
-Wno-sign-conversion
56+
-Wno-unused-function
57+
-Wshadow
58+
-Wnon-virtual-dtor
59+
-Wold-style-cast
60+
-Woverloaded-virtual
61+
-Wsign-promo
62+
-Wduplicated-cond
63+
-Wduplicated-branches
64+
-Wlogical-op
65+
-Wno-null-dereference
66+
-Wuseless-cast
67+
-Wdouble-promotion>
68+
$<$<AND:$<CXX_COMPILER_ID:GNU,Clang>,$<CONFIG:Release,RelWithDebInfo>>:-Wno-unused-variable>
69+
# Additional GCC-specific warnings
70+
$<$<CXX_COMPILER_ID:GNU>:-Wmisleading-indentation
71+
-Wduplicated-cond
72+
-Wduplicated-branches
73+
-Wlogical-op
74+
-Wno-null-dereference
75+
-Wuseless-cast>
76+
# Additional Clang-specific warnings
77+
$<$<CXX_COMPILER_ID:Clang>:-Wmost
78+
-Wthread-safety
79+
-Wthread-safety-negative>
80+
# MSVC: Maximum warnings + treat warnings as errors
81+
$<$<CXX_COMPILER_ID:MSVC>:/W4
82+
/WX
83+
/permissive-
84+
/w14242
85+
/w14254
86+
/w14263
87+
/w14265
88+
/w14287
89+
/we4289
90+
/w14296
91+
/w14311
92+
/w14545
93+
/w14546
94+
/w14547
95+
/w14549
96+
/w14555
97+
/w14619
98+
/w14640
99+
/w14826
100+
/w14905
101+
/w14906
102+
/w14928>
103+
$<$<AND:$<CXX_COMPILER_ID:MSVC>,$<CONFIG:Release,RelWithDebInfo>>:/wd4101>
26104
)
27105

28106
# Pre-compiled libraries built from `c/lib.cpp`
@@ -41,6 +119,47 @@ set_target_properties(
41119
target_link_libraries(fork_union_dynamic PUBLIC fork_union)
42120
target_link_libraries(fork_union_static PUBLIC fork_union)
43121

122+
# Security hardening flags for compiled libraries
123+
target_compile_options(
124+
fork_union_dynamic
125+
PRIVATE # Stack protection and buffer overflow detection
126+
$<$<CXX_COMPILER_ID:GNU,Clang>:-fstack-protector-strong
127+
-D_FORTIFY_SOURCE=2>
128+
# Control flow integrity and stack clash protection
129+
$<$<CXX_COMPILER_ID:GNU>:-fcf-protection=full
130+
-fstack-clash-protection>
131+
$<$<CXX_COMPILER_ID:Clang>:-fcf-protection=full>
132+
# MSVC security features
133+
$<$<CXX_COMPILER_ID:MSVC>:/GS
134+
/guard:cf>
135+
)
136+
target_compile_options(
137+
fork_union_static
138+
PRIVATE $<$<CXX_COMPILER_ID:GNU,Clang>:-fstack-protector-strong
139+
-D_FORTIFY_SOURCE=2>
140+
$<$<CXX_COMPILER_ID:GNU>:-fcf-protection=full
141+
-fstack-clash-protection>
142+
$<$<CXX_COMPILER_ID:Clang>:-fcf-protection=full>
143+
$<$<CXX_COMPILER_ID:MSVC>:/GS
144+
/guard:cf>
145+
)
146+
147+
# Hardened linking flags
148+
target_link_options(
149+
fork_union_dynamic
150+
PRIVATE
151+
# Enable RELRO, stack canaries, and NX bit
152+
$<$<PLATFORM_ID:Linux>:-Wl,-z,relro,-z,now,-z,noexecstack>
153+
# MSVC hardened linking
154+
$<$<CXX_COMPILER_ID:MSVC>:/DYNAMICBASE
155+
/NXCOMPAT
156+
/guard:cf>
157+
)
158+
target_link_options(
159+
fork_union_static PRIVATE $<$<PLATFORM_ID:Linux>:-Wl,-z,relro,-z,now,-z,noexecstack>
160+
$<$<CXX_COMPILER_ID:MSVC>:/guard:cf>
161+
)
162+
44163
# Set the output directory for all executables - on Windows requires more boilerplate:
45164
# https://stackoverflow.com/a/25328001
46165
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
@@ -51,47 +170,31 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL ${CMAKE_BINARY_DIR})
51170

52171
# Static analysis tools
53172
find_program(CPPCHECK_EXECUTABLE cppcheck)
54-
if(CPPCHECK_EXECUTABLE)
173+
if (CPPCHECK_EXECUTABLE)
55174
add_custom_target(
56175
cppcheck
57-
COMMAND ${CPPCHECK_EXECUTABLE}
58-
--enable=all
59-
--std=c++17
60-
--verbose
61-
--quiet
62-
--error-exitcode=1
63-
--suppress=missingIncludeSystem
64-
--suppress=unusedFunction
65-
--suppress=unmatchedSuppression
66-
--suppress=ConfigurationNotChecked
67-
--suppress=knownConditionTrueFalse
68-
--suppress=shadowFunction
69-
--suppress=shadowVariable
70-
--suppress=useStlAlgorithm
71-
--suppress=noExplicitConstructor
72-
-I${CMAKE_CURRENT_SOURCE_DIR}/include
73-
-DFU_ENABLE_NUMA=1
74-
${CMAKE_CURRENT_SOURCE_DIR}/include
176+
COMMAND
177+
${CPPCHECK_EXECUTABLE} --enable=all --std=c++17 --verbose --quiet --error-exitcode=1
178+
--suppress=missingIncludeSystem --suppress=unusedFunction --suppress=unmatchedSuppression
179+
--suppress=ConfigurationNotChecked --suppress=knownConditionTrueFalse --suppress=shadowFunction
180+
--suppress=shadowVariable --suppress=useStlAlgorithm --suppress=noExplicitConstructor
181+
-I${CMAKE_CURRENT_SOURCE_DIR}/include -DFU_ENABLE_NUMA=1 ${CMAKE_CURRENT_SOURCE_DIR}/include
75182
${CMAKE_CURRENT_SOURCE_DIR}/c
76183
COMMENT "Running cppcheck static analysis"
77184
)
78-
endif()
185+
endif ()
79186

80187
find_program(CLANG_TIDY_EXECUTABLE clang-tidy)
81-
if(CLANG_TIDY_EXECUTABLE)
188+
if (CLANG_TIDY_EXECUTABLE)
82189
add_custom_target(
83190
clang-tidy
84-
COMMAND ${CLANG_TIDY_EXECUTABLE}
85-
--config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy
86-
--quiet
87-
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp
88-
${CMAKE_CURRENT_SOURCE_DIR}/c/*.cpp
89-
--
90-
-I${CMAKE_CURRENT_SOURCE_DIR}/include
91-
-std=c++17
191+
COMMAND
192+
${CLANG_TIDY_EXECUTABLE} --config-file=${CMAKE_CURRENT_SOURCE_DIR}/.clang-tidy --quiet
193+
${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp ${CMAKE_CURRENT_SOURCE_DIR}/c/*.cpp --
194+
-I${CMAKE_CURRENT_SOURCE_DIR}/include -std=c++17
92195
COMMENT "Running clang-tidy static analysis"
93196
)
94-
endif()
197+
endif ()
95198

96199
# Tests & benchmarking scripts
97200
include(CTest)

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ Then, include the header in your C++ code:
120120
namespace fu = ashvardanian::fork_union;
121121

122122
int main() {
123-
fu::basic_pool_t pool;
123+
alignas(fu::default_alignment_k) fu::basic_pool_t pool;
124124
if (!pool.try_spawn(std::thread::hardware_concurrency())) {
125125
std::fprintf(stderr, "Failed to fork the threads\n");
126126
return EXIT_FAILURE;

0 commit comments

Comments
 (0)