diff --git a/CMake/find_runtime_deps.cmake b/CMake/find_runtime_deps.cmake index db52395..9171073 100644 --- a/CMake/find_runtime_deps.cmake +++ b/CMake/find_runtime_deps.cmake @@ -87,3 +87,23 @@ if(unresolved) endif() endforeach() endif() + +# Add any additional runtime dependencies that weren't auto-detected +# This is passed as EXTRA_RUNTIME_DEPS variable +if(DEFINED EXTRA_RUNTIME_DEPS) + foreach(extra_dep IN LISTS EXTRA_RUNTIME_DEPS) + if(EXISTS "${extra_dep}") + get_filename_component(dep_name "${extra_dep}" NAME) + set(dest "${INSTALL_BIN}/${dep_name}") + if(NOT EXISTS "${dest}") + file(INSTALL "${extra_dep}" DESTINATION "${INSTALL_BIN}") + message(STATUS "Copied extra dependency: ${dep_name}") + else() + message(STATUS "Extra dependency already exists: ${dep_name}") + endif() + # Add to the runtime dependencies list + file(APPEND "${BINARY_DIR}/cvutil_runtime_dependencies-${BUILD_CONFIG}.cmake" + "set(CVUTIL_RUNTIME_DEPENDENCIES \"\${CVUTIL_RUNTIME_DEPENDENCIES};\${CMAKE_CURRENT_LIST_DIR}/../../../bin/${dep_name}\")\n") + endif() + endforeach() +endif() diff --git a/CMakeLists.txt b/CMakeLists.txt index 8ac2be2..e5ca2d9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -29,6 +29,9 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) option(ENABLE_AVX512 "Enable AVX-512 support" OFF) # To be enabled on x86_64 server processors option(ENABLE_AVX2_FMA "Enable AVX2 and FMA support" ON) # Default support for x86_64 desktop processors +# Option to enable mimalloc for Release builds +option(USE_MIMALLOC "Use mimalloc allocator for Release builds" ON) + # Detect the OS if(WIN32) message(STATUS "Configuring for Windows") @@ -43,7 +46,7 @@ message(STATUS "Using ${CMAKE_CXX_COMPILER_ID} as the C++ compiler") # Create an interface library for compiler flags (modern CMake approach) add_library(cvutil_compiler_flags INTERFACE) - # MSVC-specific flags +# MSVC-specific flags target_compile_options(cvutil_compiler_flags INTERFACE $<$: $<$:/MDd /Zi /Ob0 /Od /RTC1 /fsanitize=address> @@ -97,6 +100,66 @@ target_link_options(cvutil_compiler_flags INTERFACE # endif() # endif() +# Build mimalloc for both Debug and Release builds using ExternalProject +if(USE_MIMALLOC) + include(ExternalProject) + + message(STATUS "Building mimalloc as external project (will be linked for Release configuration)...") + + # Determine build directory for mimalloc + set(MIMALLOC_PREFIX ${CMAKE_BINARY_DIR}/_external/mimalloc) + set(MIMALLOC_INSTALL_DIR ${MIMALLOC_PREFIX}/install) + + # Use ExternalProject_Add for complete control - this excludes mimalloc from install + # Build for both Debug (with ASAN tracking) and Release (without ASAN) + ExternalProject_Add( + mimalloc_external + GIT_REPOSITORY https://github.com/microsoft/mimalloc.git + GIT_TAG v2.2.4 + PREFIX ${MIMALLOC_PREFIX} + CMAKE_ARGS + -DCMAKE_BUILD_TYPE=Release + -DMI_BUILD_SHARED=ON + -DMI_BUILD_STATIC=OFF + -DMI_BUILD_TESTS=OFF + -DMI_BUILD_OBJECT=OFF + -DMI_OVERRIDE=ON + # $<$:-DMI_TRACK_ASAN=ON> + # $<$:-DMI_SHOW_ERRORS=ON> + -DCMAKE_INSTALL_PREFIX=${MIMALLOC_INSTALL_DIR} + BUILD_BYPRODUCTS + $<$:${MIMALLOC_INSTALL_DIR}/bin/mimalloc.dll> + $<$:${MIMALLOC_INSTALL_DIR}/bin/mimalloc-redirect.dll> + $<$:${MIMALLOC_INSTALL_DIR}/lib/mimalloc.dll.lib> + $<$:${MIMALLOC_INSTALL_DIR}/lib/mimalloc.so> + $<$:${MIMALLOC_INSTALL_DIR}/lib/mimalloc.dylib> + ) + + # Create imported target for linking + add_library(mimalloc SHARED IMPORTED GLOBAL) + add_dependencies(mimalloc mimalloc_external) + set_target_properties(mimalloc PROPERTIES + IMPORTED_LOCATION + $<$:${MIMALLOC_INSTALL_DIR}/bin/mimalloc.dll> + $<$:${MIMALLOC_INSTALL_DIR}/lib/mimalloc.so> + $<$:${MIMALLOC_INSTALL_DIR}/lib/mimalloc.dylib> + IMPORTED_IMPLIB + $<$:${MIMALLOC_INSTALL_DIR}/lib/mimalloc.dll.lib> + ) + + # Create imported target for mimalloc-redirect + add_library(mimalloc-redirect SHARED IMPORTED GLOBAL) + add_dependencies(mimalloc-redirect mimalloc_external) + set_target_properties(mimalloc-redirect PROPERTIES + IMPORTED_LOCATION + $<$:${MIMALLOC_INSTALL_DIR}/bin/mimalloc-redirect.dll> + $<$:${MIMALLOC_INSTALL_DIR}/lib/mimalloc-redirect.so> + $<$:${MIMALLOC_INSTALL_DIR}/lib/mimalloc-redirect.dylib> + ) + + message(STATUS "mimalloc external project configured") +endif() + # Find OpenCV find_package(OpenCV REQUIRED) @@ -175,6 +238,17 @@ if (CMAKE_SYSTEM_NAME STREQUAL "Windows") endif() endif() + # Install mimalloc DLLs if used (only runtime DLLs, no headers/cmake files) + if(USE_MIMALLOC) + install(FILES + ${MIMALLOC_INSTALL_DIR}/bin/mimalloc.dll + ${MIMALLOC_INSTALL_DIR}/bin/mimalloc-redirect.dll + CONFIGURATIONS Release + DESTINATION bin + COMPONENT runtime + ) + endif() + elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") # Set RPATH to include our bundled libraries # set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib/cvutil;\$ORIGIN/../lib;/usr/lib/x86_64-linux-gnu;/lib/x86_64-linux-gnu") @@ -329,6 +403,10 @@ install(EXPORT cvutilTargets COMPONENT development ) +# Note: mimalloc is NOT exported in cvutilTargets +# It's an internal dependency that gets loaded automatically via DLL dependencies +# Applications should NOT link to cvutil::mimalloc - it doesn't exist + # Add to your root CMakeLists.txt configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/CMake/copy_runtime_dependencies.cmake diff --git a/PluginManager/CMakeLists.txt b/PluginManager/CMakeLists.txt index e9f998e..10242bc 100644 --- a/PluginManager/CMakeLists.txt +++ b/PluginManager/CMakeLists.txt @@ -59,6 +59,17 @@ target_link_libraries(PluginManager Qt6::OpenGL ) +# Link mimalloc for Release builds only +if(USE_MIMALLOC) + if(TARGET mimalloc) + target_link_libraries(PluginManager PRIVATE $<$:mimalloc>) + target_link_options(PluginManager PRIVATE $<$:/INCLUDE:mi_version>) + message(STATUS "PluginManager will use mimalloc shared library for Release configuration") + else() + message(WARNING "USE_MIMALLOC is ON but mimalloc target not found!") + endif() +endif() + target_compile_definitions(PluginManager PRIVATE PLUGINMANAGER_SOURCE) set(PUBLIC_HEADERS diff --git a/RoiManager/CMakeLists.txt b/RoiManager/CMakeLists.txt index fd1ff7c..4efa2ba 100644 --- a/RoiManager/CMakeLists.txt +++ b/RoiManager/CMakeLists.txt @@ -52,6 +52,17 @@ target_link_libraries(RoiManager Qt6::OpenGL ) +# Link mimalloc for Release builds only +if(USE_MIMALLOC) + if(TARGET mimalloc) + target_link_libraries(RoiManager PRIVATE $<$:mimalloc>) + target_link_options(RoiManager PRIVATE $<$:/INCLUDE:mi_version>) + message(STATUS "RoiManager will use mimalloc shared library for Release configuration") + else() + message(WARNING "USE_MIMALLOC is ON but mimalloc target not found!") + endif() +endif() + target_compile_definitions(RoiManager PRIVATE ROIMANAGER_SOURCE) set(PUBLIC_HEADERS diff --git a/cvutil/CMakeLists.txt b/cvutil/CMakeLists.txt index 9697577..077ea84 100644 --- a/cvutil/CMakeLists.txt +++ b/cvutil/CMakeLists.txt @@ -120,6 +120,18 @@ target_link_libraries(cvutil RoiManager ) +# Link mimalloc for Release builds only +if(USE_MIMALLOC) + if(TARGET mimalloc) + target_link_libraries(cvutil PRIVATE $<$:mimalloc>) + # Force the linker to include mimalloc.dll as a dependency + target_link_options(cvutil PRIVATE $<$,$>:/INCLUDE:mi_version>) + message(STATUS "cvutil will use mimalloc shared library for Release configuration") + else() + message(WARNING "USE_MIMALLOC is ON but mimalloc target not found!") + endif() +endif() + target_compile_definitions(cvutil PRIVATE CVUTIL_SOURCE) set(PUBLIC_HEADERS @@ -233,11 +245,17 @@ endif() if (CMAKE_SYSTEM_NAME STREQUAL "Windows") # Build search directories list for runtime dependency detection set(RUNTIME_SEARCH_DIRS ${DEP_PATH}) + if(USE_MIMALLOC AND TARGET mimalloc) + # Add mimalloc install directory to search paths + list(APPEND RUNTIME_SEARCH_DIRS ${MIMALLOC_INSTALL_DIR}/bin) + endif() + add_custom_command(TARGET cvutil POST_BUILD COMMAND ${CMAKE_COMMAND} -D TARGET_FILE=$ -D INSTALL_BIN=${CMAKE_INSTALL_PREFIX}/$,bin,lib/cvutil> -D SEARCH_DIRS="${RUNTIME_SEARCH_DIRS}" + -D EXTRA_RUNTIME_DEPS="$,$>,${MIMALLOC_INSTALL_DIR}/bin/mimalloc.dll;${MIMALLOC_INSTALL_DIR}/bin/mimalloc-redirect.dll,>" -D BUILD_CONFIG=$ -D BINARY_DIR=${CMAKE_BINARY_DIR} -P "${CMAKE_CURRENT_SOURCE_DIR}/../CMake/find_runtime_deps.cmake"