Skip to content

Commit a231ec1

Browse files
committed
Refine CMake with install targets and add_subdirectory support
1 parent 6b0db57 commit a231ec1

File tree

3 files changed

+108
-16
lines changed

3 files changed

+108
-16
lines changed

CMakeLists.txt

Lines changed: 82 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,39 +4,112 @@ if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
44
message(FATAL_ERROR "Do not build in-source. Please remove CMakeCache.txt and the CMakeFiles/ directory. Then build out-of-source.")
55
endif()
66

7-
project(BadAccessGuards C CXX)
7+
project(BadAccessGuards LANGUAGES C CXX VERSION 1.0.0)
88

99
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
10-
set(BAGUARDS_IS_ROOT_PROJECT TRUE)
10+
set(${PROJECT_NAME}_IS_ROOT_PROJECT TRUE)
1111
endif()
1212

13-
option(BAGUARDS_EXAMPLES "Build the examples" ${BAGUARDS_IS_ROOT_PROJECT})
14-
option(BAGUARDS_BENCH "Build the benchmarks" ${BAGUARDS_IS_ROOT_PROJECT})
15-
option(BAGUARDS_FORCE_ENABLE "Build with BAD_ACCESS_GUARDS_ENABLE=1 defined." ${BAGUARDS_IS_ROOT_PROJECT})
13+
############################
14+
## Modules and scripts ##
15+
############################
1616

17+
include(GNUInstallDirs) # This will define the default values for installation directories (all platforms even if named GNU)
18+
#include(InstallRequiredSystemLibraries) # Tell CMake that the `install` target needs to install required system libraries (eg: Windows SDK)
19+
include(CMakePackageConfigHelpers) # Helper to create relocatable packages
20+
21+
###############
22+
## OPTIONS ##
23+
###############
24+
25+
option(${PROJECT_NAME}_EXAMPLES "Build the examples" ${${PROJECT_NAME}_IS_ROOT_PROJECT})
26+
option(${PROJECT_NAME}_BENCH "Build the benchmarks" ${${PROJECT_NAME}_IS_ROOT_PROJECT})
27+
option(${PROJECT_NAME}_FORCE_ENABLE "Build with BAD_ACCESS_GUARDS_ENABLE=1 defined." ${${PROJECT_NAME}_IS_ROOT_PROJECT})
28+
option(${PROJECT_NAME}_INSTALL "Should ${PROJECT_NAME} be added to the install list? Useful if included using add_subdirectory." ${${PROJECT_NAME}_IS_ROOT_PROJECT})
29+
30+
###############
31+
## PROJECT ##
32+
###############
1733

1834
add_library(BadAccessGuards
1935
src/BadAccessGuards.cpp
2036
src/BadAccessGuards.h
2137
)
22-
target_include_directories(BadAccessGuards INTERFACE src)
38+
target_include_directories(${PROJECT_NAME}
39+
PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/src> # Due to the way installation work, we only want this path set when building, not once installed
40+
)
41+
set_target_properties(${PROJECT_NAME}
42+
PROPERTIES
43+
PUBLIC_HEADER ${CMAKE_CURRENT_LIST_DIR}/src/BadAccessGuards.h
44+
DEBUG_POSTFIX d
45+
)
46+
2347
target_compile_features(BadAccessGuards PUBLIC cxx_std_11)
48+
add_library(${PROJECT_NAME}::BadAccessGuards ALIAS BadAccessGuards)
2449

25-
if(BAGUARDS_FORCE_ENABLE)
50+
if(${PROJECT_NAME}_FORCE_ENABLE)
2651
target_compile_definitions(BadAccessGuards PUBLIC BAD_ACCESS_GUARDS_ENABLE=1)
2752
endif()
2853

29-
if(BAGUARDS_EXAMPLES)
54+
#############################
55+
## Examples and benchmarks ##
56+
#############################
57+
58+
if(${PROJECT_NAME}_EXAMPLES)
3059
add_executable(BasicExample examples/Basic.cpp)
3160
target_link_libraries(BasicExample PRIVATE BadAccessGuards)
3261
target_compile_features(BasicExample PUBLIC cxx_std_14) # chrono_literals
62+
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT BasicExample)
3363

3464
add_executable(GuardedVectorExample examples/GuardedVectorExample.cpp examples/GuardedVectorExample.h)
3565
target_link_libraries(GuardedVectorExample PRIVATE BadAccessGuards)
3666
target_compile_features(GuardedVectorExample PUBLIC cxx_std_14) # chrono_literals
3767
endif()
3868

39-
if(BAGUARDS_BENCH)
69+
if(${PROJECT_NAME}_BENCH)
4070
add_subdirectory(benchmarks)
4171
endif()
4272

73+
#############
74+
## Install ##
75+
#############
76+
77+
if(${PROJECT_NAME}_INSTALL)
78+
set(${PROJECT_NAME}_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" CACHE STRING "Path to ${PROJECT_NAME} cmake files")
79+
80+
# Use version checking boilerplate
81+
write_basic_package_version_file(
82+
${PROJECT_NAME}ConfigVersion.cmake
83+
COMPATIBILITY SameMajorVersion
84+
)
85+
86+
configure_package_config_file(
87+
${CMAKE_CURRENT_LIST_DIR}/cmake/${PROJECT_NAME}Config.cmake.in
88+
${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
89+
INSTALL_DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKEDIR}
90+
# Imported targets do not require the following macros
91+
NO_SET_AND_CHECK_MACRO
92+
NO_CHECK_REQUIRED_COMPONENTS_MACRO
93+
)
94+
95+
install(
96+
TARGETS BadAccessGuards
97+
EXPORT ${PROJECT_NAME}_Targets
98+
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
99+
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
100+
)
101+
102+
install(
103+
EXPORT ${PROJECT_NAME}_Targets
104+
NAMESPACE ${PROJECT_NAME}::
105+
FILE ${PROJECT_NAME}Targets.cmake
106+
DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKEDIR}
107+
)
108+
109+
install(FILES
110+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake
111+
${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake
112+
DESTINATION ${${PROJECT_NAME}_INSTALL_CMAKEDIR}
113+
)
114+
endif()
115+

README.md

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -54,17 +54,27 @@ As a bonus, we also get detection of memory use-after-free and corruption for fr
5454

5555
# Usage
5656

57-
1. Define `BAD_ACCESS_GUARDS_ENABLE=1` for your **in-house** builds (you probably want it off in production...)
58-
2. Declare the shadow memory that will hold the state and pointer to stack with `BA_GUARD_DECL(varname)`
59-
3. For all (relevant) read operations of the container / object, use the scope guard `BA_GUARD_READ(varname)`.
60-
4. For all (relevant) write operations of the container / object, use the scope guard `BA_GUARD_WRITE(varname)`.
61-
Do this only if it always writes! For example, don't use it on `operator[]` even though it returns a reference, use `BA_GUARD_READ` instead.
62-
5. Add `BA_GUARD_DESTROY(varname)` at the beginning of the destructor.
63-
6. Enjoy!
57+
1. Add `BadAccessGuards.h` and `BadAccessGuards.cpp` to your project. (Via CMake, or copy the files)
58+
2. Define `BAD_ACCESS_GUARDS_ENABLE=1` for your **in-house** builds (you probably want it off in production...)
59+
3. Declare the shadow memory that will hold the state and pointer to stack with `BA_GUARD_DECL(varname)`
60+
4. For all (relevant) read operations of the container / object, use the scope guard `BA_GUARD_READ(varname)`.
61+
. For all (relevant) write operations of the container / object, use the scope guard `BA_GUARD_WRITE(varname)`.
62+
5 Do this only if it always writes! For example, don't use it on `operator[]` even though it returns a reference, use `BA_GUARD_READ` instead.
63+
6. Add `BA_GUARD_DESTROY(varname)` at the beginning of the destructor.
64+
7. Enjoy!
6465

6566
# Examples
6667

6768
Examples are available in [./examples](./examples).
69+
You may build and run them easily using CMake:
70+
71+
```sh
72+
cmake -B build # Generate the project
73+
# Open the project in your IDE (if supported by your generator)
74+
cmake --open build
75+
# Or build it
76+
cmake --build build
77+
```
6878

6979
Here is how it looks in Visual Studio(error caught in production, we were appending decoded frames to a collection while reading it):
7080

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
@PACKAGE_INIT@
2+
3+
# Required so that on windows Release and RelWithDebInfo can be used instead of default fallback which is Debug
4+
# See https://gitlab.kitware.com/cmake/cmake/-/issues/20319
5+
set(CMAKE_MAP_IMPORTED_CONFIG_MINSIZEREL MinSizeRel RelWithDebInfo Release Debug)
6+
set(CMAKE_MAP_IMPORTED_CONFIG_RELWITHDEBINFO RelWithDebInfo Release MinSizeRel Debug)
7+
set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE Release RelWithDebInfo MinSizeRel Debug)
8+
9+
include("${CMAKE_CURRENT_LIST_DIR}/@[email protected]")

0 commit comments

Comments
 (0)