Skip to content

Commit 2315fcf

Browse files
authored
Merge pull request #4 from predictivephenomics/bugfix/memory-safety-and-asan
Fix memory issues and add Address Sanitizer to Debug configuration.
2 parents 2f7a91f + 0bd9bb0 commit 2315fcf

15 files changed

Lines changed: 273 additions & 227 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
bld/
2222
[Bb]in/
2323
[Oo]bj/
24+
[Ii]nstall/
2425

2526
# Visual Studio 2015 cache/options directory
2627
.vs/

CMakeLists.txt

Lines changed: 87 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
cmake_minimum_required(VERSION 3.28)
22

3-
# Define the project
4-
project(cvutil VERSION "2.5.0" DESCRIPTION "Computer Vision UTILity Toolkit" LANGUAGES CXX)
5-
6-
set(CVUTIL_PROJECT "cvutil" CACHE STRING "CVUTIL project")
7-
8-
set(CMAKE_CXX_STANDARD 17)
9-
set(CMAKE_CXX_STANDARD_REQUIRED ON)
10-
11-
# Set the preferred compilers in order of priority
12-
if(NOT CMAKE_CXX_COMPILER)
3+
# Set the preferred compilers in order of priority (must be before project())
4+
if(NOT DEFINED CMAKE_CXX_COMPILER)
135
find_program(CLANG_COMPILER NAMES clang++ clang)
146
find_program(GCC_COMPILER NAMES g++ gcc)
157
find_program(MSVC_COMPILER NAMES cl)
168

179
if(CLANG_COMPILER)
18-
set(CMAKE_CXX_COMPILER ${CLANG_COMPILER})
10+
set(CMAKE_CXX_COMPILER ${CLANG_COMPILER} CACHE FILEPATH "C++ compiler")
1911
elseif(GCC_COMPILER)
20-
set(CMAKE_CXX_COMPILER ${GCC_COMPILER})
12+
set(CMAKE_CXX_COMPILER ${GCC_COMPILER} CACHE FILEPATH "C++ compiler")
2113
elseif(MSVC_COMPILER)
22-
set(CMAKE_CXX_COMPILER ${MSVC_COMPILER})
14+
set(CMAKE_CXX_COMPILER ${MSVC_COMPILER} CACHE FILEPATH "C++ compiler")
2315
else()
2416
message(FATAL_ERROR "No suitable compiler found")
2517
endif()
2618
endif()
2719

20+
# Define the project
21+
project(cvutil VERSION "2.5.0" DESCRIPTION "Computer Vision UTILity Toolkit" LANGUAGES CXX)
22+
23+
set(CVUTIL_PROJECT "cvutil" CACHE STRING "CVUTIL project")
24+
25+
set(CMAKE_CXX_STANDARD 17)
26+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
27+
2828
# Options to enable or disable AVX-512 and AVX2/FMA support
2929
option(ENABLE_AVX512 "Enable AVX-512 support" OFF) # To be enabled on x86_64 server processors
3030
option(ENABLE_AVX2_FMA "Enable AVX2 and FMA support" ON) # Default support for x86_64 desktop processors
@@ -40,58 +40,62 @@ endif()
4040

4141
message(STATUS "Using ${CMAKE_CXX_COMPILER_ID} as the C++ compiler")
4242

43-
# Set global CMake build options
44-
if(MSVC) # OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
43+
# Create an interface library for compiler flags (modern CMake approach)
44+
add_library(cvutil_compiler_flags INTERFACE)
45+
4546
# MSVC-specific flags
46-
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd /Zi /Ob0 /Od /RTC1 /DDEBUG /D_CRT_SECURE_NO_WARNINGS")
47-
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /DEBUG /INCREMENTAL")
48-
49-
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /Ox /DNDEBUG")
50-
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS_RELEASE} /OPT:REF /OPT:ICF")
51-
52-
# Enable AVX-512 and AVX2/FMA support
53-
if(ENABLE_AVX512)
54-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX512")
55-
endif()
56-
if(ENABLE_AVX2_FMA)
57-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
58-
endif()
59-
60-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /fp:precise /fp:strict")
61-
62-
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
63-
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -DDEBUG -D_DEBUG -O0")
64-
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG")
65-
66-
# Enable AVX-512 and AVX2/FMA support
67-
if(ENABLE_AVX512)
68-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512")
69-
endif()
70-
if(ENABLE_AVX2_FMA)
71-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2 -mfma")
72-
endif()
73-
74-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-fast-math -frounding-math")
75-
76-
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
77-
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -DDEBUG -D_DEBUG -O0")
78-
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -DNDEBUG")
79-
80-
# Enable AVX-512 and AVX2/FMA support
81-
if(ENABLE_AVX512)
82-
message(STATUS "Enabling AVX-512 support")
83-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx512")
84-
endif()
85-
if(ENABLE_AVX2_FMA)
86-
message(STATUS "Enabling AVX2 and FMA support")
87-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2 -mfma")
88-
endif()
89-
90-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-fast-math -frounding-math")
91-
92-
else()
93-
message(FATAL_ERROR "Unsupported compiler")
94-
endif()
47+
target_compile_options(cvutil_compiler_flags INTERFACE
48+
$<$<CXX_COMPILER_ID:MSVC>:
49+
$<$<CONFIG:Debug>:/MDd /Zi /Ob0 /Od /RTC1 /fsanitize=address>
50+
$<$<CONFIG:Release>:/MD /Ox>
51+
/fp:precise /fp:strict
52+
$<$<BOOL:${ENABLE_AVX512}>:/arch:AVX512>
53+
$<$<BOOL:${ENABLE_AVX2_FMA}>:/arch:AVX2>
54+
>
55+
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
56+
$<$<CONFIG:Debug>:-g -O0 -fsanitize=address>
57+
$<$<CONFIG:Release>:-O3>
58+
-fno-fast-math -frounding-math
59+
$<$<BOOL:${ENABLE_AVX512}>:-mavx512f>
60+
$<$<BOOL:${ENABLE_AVX2_FMA}>:-mavx2 -mfma>
61+
>
62+
)
63+
64+
target_compile_definitions(cvutil_compiler_flags INTERFACE
65+
$<$<CXX_COMPILER_ID:MSVC>:
66+
$<$<CONFIG:Debug>:DEBUG;_CRT_SECURE_NO_WARNINGS>
67+
$<$<CONFIG:Release>:NDEBUG>
68+
>
69+
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
70+
$<$<CONFIG:Debug>:DEBUG;_DEBUG>
71+
$<$<CONFIG:Release>:NDEBUG>
72+
>
73+
)
74+
75+
target_link_options(cvutil_compiler_flags INTERFACE
76+
$<$<CXX_COMPILER_ID:MSVC>:
77+
$<$<CONFIG:Debug>:/DEBUG /INCREMENTAL> # /INFERASANLIBS:NO
78+
$<$<CONFIG:Release>:/OPT:REF /OPT:ICF>
79+
>
80+
$<$<OR:$<CXX_COMPILER_ID:Clang>,$<CXX_COMPILER_ID:GNU>>:
81+
$<$<CONFIG:Debug>:-fsanitize=address>
82+
>
83+
)
84+
85+
# # Find and link the ASAN runtime library for Debug builds with MSVC
86+
# if(MSVC)
87+
# # Find the ASAN import library
88+
# get_filename_component(COMPILER_DIR ${CMAKE_CXX_COMPILER} DIRECTORY)
89+
# file(GLOB ASAN_LIB "${COMPILER_DIR}/clang_rt.asan_dynamic-x86_64.lib")
90+
# if(ASAN_LIB)
91+
# target_link_libraries(cvutil_compiler_flags INTERFACE
92+
# $<$<CONFIG:Debug>:${ASAN_LIB}>
93+
# )
94+
# message(STATUS "Found ASAN import library: ${ASAN_LIB}")
95+
# else()
96+
# message(WARNING "ASAN import library not found in ${COMPILER_DIR}")
97+
# endif()
98+
# endif()
9599

96100
# Find OpenCV
97101
find_package(OpenCV REQUIRED)
@@ -125,6 +129,25 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
125129
foreach(qt_lib Qt6::Core Qt6::Widgets Qt6::Gui Qt6::Charts Qt6::OpenGL Qt6::OpenGLWidgets)
126130
install(FILES $<TARGET_FILE:${qt_lib}> CONFIGURATIONS Debug Release DESTINATION bin)
127131
endforeach()
132+
133+
if(MSVC)
134+
# Get the compiler directory and construct paths dynamically
135+
get_filename_component(COMPILER_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY)
136+
137+
# Find and install ASAN DLL for Debug builds
138+
find_file(ASAN_DLL "clang_rt.asan_dynamic-x86_64.dll"
139+
PATHS "${COMPILER_DIR}"
140+
"${COMPILER_DIR}/../../../bin"
141+
"${COMPILER_DIR}/../../bin"
142+
"C:/Program Files/Microsoft Visual Studio/2022/Community/VC/Tools/Llvm/x64/bin"
143+
NO_DEFAULT_PATH)
144+
if(ASAN_DLL)
145+
install(FILES ${ASAN_DLL} CONFIGURATIONS Debug DESTINATION bin)
146+
else()
147+
message(WARNING "AddressSanitizer DLL not found. Debug builds may fail to run.")
148+
endif()
149+
endif()
150+
128151
elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux")
129152
# Set RPATH to include our bundled libraries
130153
# set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/cvutil;\$ORIGIN/../lib;/usr/lib/x86_64-linux-gnu;/lib/x86_64-linux-gnu")

PluginManager/CMakeLists.txt

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ target_include_directories(PluginManager
5151
# Link libraries (PluginManager depends on Qt)
5252
target_link_libraries(PluginManager
5353
PRIVATE
54+
cvutil_compiler_flags
5455
Qt6::Core
5556
Qt6::Widgets
5657
Qt6::Charts
@@ -65,29 +66,29 @@ set(PUBLIC_HEADERS
6566
include/PluginManager.h
6667
)
6768

68-
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/bin)
69-
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/include)
70-
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/lib)
69+
# file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/bin)
70+
# file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/include)
71+
# file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/lib)
7172

72-
# Set the output directories for the built targets
73-
set_target_properties(cvutil PROPERTIES
74-
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/bin/
75-
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/bin/
73+
# # Set the output directories for the built targets
74+
# set_target_properties(cvutil PROPERTIES
75+
# RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/bin/
76+
# RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/bin/
7677

77-
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/lib/
78-
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/lib/
78+
# LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/lib/
79+
# LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/lib/
7980

80-
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/lib/
81-
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/lib/
82-
)
81+
# ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/lib/
82+
# ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/lib/
83+
# )
8384

84-
# Post-build commands (copy the library to the correct directories)
85-
add_custom_command(TARGET PluginManager POST_BUILD
86-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
87-
${CMAKE_CURRENT_SOURCE_DIR}/include/PluginInterfaces.h ${CMAKE_BINARY_DIR}/library/include/
88-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
89-
${CMAKE_CURRENT_SOURCE_DIR}/include/PluginManager.h ${CMAKE_BINARY_DIR}/library/include/
90-
)
85+
# # Post-build commands (copy the library to the correct directories)
86+
# add_custom_command(TARGET PluginManager POST_BUILD
87+
# COMMAND ${CMAKE_COMMAND} -E copy_if_different
88+
# ${CMAKE_CURRENT_SOURCE_DIR}/include/PluginInterfaces.h ${CMAKE_BINARY_DIR}/library/include/
89+
# COMMAND ${CMAKE_COMMAND} -E copy_if_different
90+
# ${CMAKE_CURRENT_SOURCE_DIR}/include/PluginManager.h ${CMAKE_BINARY_DIR}/library/include/
91+
# )
9192

9293
# # Install the PluginManager library
9394
# install(TARGETS PluginManager
@@ -154,17 +155,17 @@ if (MSVC)
154155
install(FILES $<TARGET_PDB_FILE:PluginManager> CONFIGURATIONS Debug DESTINATION bin COMPONENT development)
155156
endif()
156157

157-
# For the PluginManager target
158-
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
159-
add_custom_command(TARGET PluginManager POST_BUILD
160-
COMMAND ${CMAKE_COMMAND}
161-
-D TARGET_FILE=$<TARGET_FILE:PluginManager>
162-
-D INSTALL_BIN=${CMAKE_INSTALL_PREFIX}/$<IF:$<BOOL:${WIN32}>,bin,lib/cvutil>
163-
-D SEARCH_DIRS=${DEP_PATH}
164-
-D BUILD_CONFIG=$<CONFIG>
165-
-D BINARY_DIR=${CMAKE_BINARY_DIR}
166-
-P "${CMAKE_CURRENT_SOURCE_DIR}/../CMake/find_runtime_deps.cmake"
167-
COMMENT "Copying runtime dependencies for PluginManager"
168-
)
169-
endif()
158+
# # For the PluginManager target
159+
# if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
160+
# add_custom_command(TARGET PluginManager POST_BUILD
161+
# COMMAND ${CMAKE_COMMAND}
162+
# -D TARGET_FILE=$<TARGET_FILE:PluginManager>
163+
# -D INSTALL_BIN=${CMAKE_INSTALL_PREFIX}/$<IF:$<BOOL:${WIN32}>,bin,lib/cvutil>
164+
# -D SEARCH_DIRS=${DEP_PATH}
165+
# -D BUILD_CONFIG=$<CONFIG>
166+
# -D BINARY_DIR=${CMAKE_BINARY_DIR}
167+
# -P "${CMAKE_CURRENT_SOURCE_DIR}/../CMake/find_runtime_deps.cmake"
168+
# COMMENT "Copying runtime dependencies for PluginManager"
169+
# )
170+
# endif()
170171

RoiManager/CMakeLists.txt

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ target_include_directories(RoiManager
4343
# Link Qt6 and OpenCV libraries, along with other dependencies
4444
target_link_libraries(RoiManager
4545
PRIVATE
46+
cvutil_compiler_flags
4647
${OpenCV_LIBS}
4748
Qt6::Core
4849
Qt6::Widgets
@@ -57,27 +58,27 @@ set(PUBLIC_HEADERS
5758
include/RoiManager.h
5859
)
5960

60-
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/bin)
61-
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/include)
62-
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/lib)
61+
# file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/bin)
62+
# file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/include)
63+
# file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/library/lib)
6364

64-
# Set the output directories for the built targets
65-
set_target_properties(cvutil PROPERTIES
66-
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/bin/
67-
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/bin/
65+
# # Set the output directories for the built targets
66+
# set_target_properties(cvutil PROPERTIES
67+
# RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/bin/
68+
# RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/bin/
6869

69-
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/lib/
70-
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/lib/
70+
# LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/lib/
71+
# LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/lib/
7172

72-
ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/lib/
73-
ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/lib/
74-
)
73+
# ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/library/lib/
74+
# ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/library/lib/
75+
# )
7576

76-
# Post-build events to copy DLL, lib, and headers to appropriate directories
77-
add_custom_command(TARGET RoiManager POST_BUILD
78-
COMMAND ${CMAKE_COMMAND} -E copy_if_different
79-
${CMAKE_CURRENT_SOURCE_DIR}/include/RoiManager.h ${CMAKE_BINARY_DIR}/library/include/
80-
)
77+
# # Post-build events to copy DLL, lib, and headers to appropriate directories
78+
# add_custom_command(TARGET RoiManager POST_BUILD
79+
# COMMAND ${CMAKE_COMMAND} -E copy_if_different
80+
# ${CMAKE_CURRENT_SOURCE_DIR}/include/RoiManager.h ${CMAKE_BINARY_DIR}/library/include/
81+
# )
8182

8283
# # Install the RoiManager library for Debug configuration
8384
# install(TARGETS RoiManager
@@ -146,16 +147,16 @@ endif()
146147

147148
message(STATUS "Dependency path: ${DEP_PATH}")
148149

149-
# For the RoiManager target
150-
if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
151-
add_custom_command(TARGET RoiManager POST_BUILD
152-
COMMAND ${CMAKE_COMMAND}
153-
-D TARGET_FILE=$<TARGET_FILE:RoiManager>
154-
-D INSTALL_BIN=${CMAKE_INSTALL_PREFIX}/$<IF:$<BOOL:${WIN32}>,bin,lib/cvutil>
155-
-D SEARCH_DIRS=${DEP_PATH}
156-
-D BUILD_CONFIG=$<CONFIG>
157-
-D BINARY_DIR=${CMAKE_BINARY_DIR}
158-
-P "${CMAKE_CURRENT_SOURCE_DIR}/../CMake/find_runtime_deps.cmake"
159-
COMMENT "Copying runtime dependencies for RoiManager"
160-
)
161-
endif()
150+
# # For the RoiManager target
151+
# if (CMAKE_SYSTEM_NAME STREQUAL "Windows")
152+
# add_custom_command(TARGET RoiManager POST_BUILD
153+
# COMMAND ${CMAKE_COMMAND}
154+
# -D TARGET_FILE=$<TARGET_FILE:RoiManager>
155+
# -D INSTALL_BIN=${CMAKE_INSTALL_PREFIX}/$<IF:$<BOOL:${WIN32}>,bin,lib/cvutil>
156+
# -D SEARCH_DIRS=${DEP_PATH}
157+
# -D BUILD_CONFIG=$<CONFIG>
158+
# -D BINARY_DIR=${CMAKE_BINARY_DIR}
159+
# -P "${CMAKE_CURRENT_SOURCE_DIR}/../CMake/find_runtime_deps.cmake"
160+
# COMMENT "Copying runtime dependencies for RoiManager"
161+
# )
162+
# endif()

0 commit comments

Comments
 (0)