Files
2026-07-13 12:47:05 +08:00

236 lines
9.6 KiB
CMake
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
cmake_minimum_required(VERSION 3.15)
# ============================================================================
# STALE MAKEFILE DETECTION AND CLEANUP
# ============================================================================
# CMake's progress tracking can become inconsistent when template-generated
# files change between builds, causing build failures with "No rule to make target"
# This check forces a clean reconfiguration if stale Makefiles are detected
if(EXISTS "${CMAKE_BINARY_DIR}/CMakeFiles/progress.marks")
file(READ "${CMAKE_BINARY_DIR}/CMakeFiles/progress.marks" PROGRESS_MARKS)
string(STRIP "${PROGRESS_MARKS}" PROGRESS_MARKS)
# If progress marks is suspiciously low (99 or less), force reconfiguration
# Real builds should have much higher counts with template instantiations
if(PROGRESS_MARKS LESS 200)
message(STATUS "⚠️ Detected stale CMake progress tracking (only ${PROGRESS_MARKS} marks)")
message(STATUS " Forcing clean reconfiguration to fix Makefile consistency...")
# Delete all CMake-generated Makefiles and progress files
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/CMakeFiles/Makefile2")
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/CMakeFiles/progress.marks")
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/CMakeFiles/nd4jcpu_object.dir/progress.make")
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/CMakeFiles/nd4jcpu_object.dir/build.make")
file(REMOVE_RECURSE "${CMAKE_BINARY_DIR}/CMakeCache.txt")
message(FATAL_ERROR "Stale Makefiles deleted. Please re-run cmake to regenerate build system.")
endif()
endif()
# ============================================================================
# CCACHE SETUP - Must be before project() for proper compiler launcher setup
# ============================================================================
# NOTE: ccache is DISABLED for debug and functrace builds due to poor hit rates
# Debug/functrace flags (-finstrument-functions, -fdebug-info-for-profiling, etc.)
# cause constant cache invalidation, making ccache overhead > benefit
# See: Build 265 analysis - 32% hit rate with 55% slower builds
find_program(CCACHE_PROGRAM ccache)
if(CCACHE_PROGRAM)
# Check if this is a debug or functrace build
set(CCACHE_SKIP_REASON "")
# Note: CMAKE_BUILD_TYPE might not be set yet, so check cache variables too
if(DEFINED SD_GCC_FUNCTRACE AND SD_GCC_FUNCTRACE)
set(CCACHE_SKIP_REASON "functrace build (instrumentation flags hurt cache hit rate)")
elseif(CMAKE_BUILD_TYPE MATCHES "Debug" OR CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo")
set(CCACHE_SKIP_REASON "debug build (debug info flags hurt cache hit rate)")
endif()
if(CCACHE_SKIP_REASON)
message(STATUS "⚠️ Ccache DISABLED for ${CCACHE_SKIP_REASON}")
message(STATUS " Reason: Debug/functrace flags cause 60-70% cache miss rate, making ccache slower than no cache")
set(CMAKE_C_COMPILER_LAUNCHER "" CACHE STRING "C compiler launcher" FORCE)
set(CMAKE_CXX_COMPILER_LAUNCHER "" CACHE STRING "C++ compiler launcher" FORCE)
else()
message(STATUS "✅ Found ccache: ${CCACHE_PROGRAM}")
# Configure ccache to avoid race conditions with directory creation
execute_process(COMMAND ${CCACHE_PROGRAM} --set-config=compiler_check=mtime ERROR_QUIET)
execute_process(COMMAND ${CCACHE_PROGRAM} --set-config=sloppiness=include_file_mtime,include_file_ctime ERROR_QUIET)
# Use FORCE to ensure cache is always updated and avoid inconsistent builds
set(CMAKE_C_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "C compiler launcher" FORCE)
set(CMAKE_CXX_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "C++ compiler launcher" FORCE)
# CUDA launcher will be set after project() if needed
message(STATUS "✅ Ccache enabled - builds will be significantly faster after first compilation")
endif()
else()
message(STATUS "️ Ccache not found - install with: sudo apt-get install ccache (or brew install ccache)")
# Explicitly unset launcher if ccache not found
set(CMAKE_C_COMPILER_LAUNCHER "" CACHE STRING "C compiler launcher" FORCE)
set(CMAKE_CXX_COMPILER_LAUNCHER "" CACHE STRING "C++ compiler launcher" FORCE)
endif()
if(WIN32 AND SD_CUDA)
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS OFF)
set(CMAKE_VERBOSE_MAKEFILE OFF)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CUDA_STANDARD_REQUIRED ON)
# Disable response files and dependencies
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_OBJECTS OFF CACHE BOOL "" FORCE)
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_INCLUDES OFF CACHE BOOL "" FORCE)
set(CMAKE_CUDA_USE_RESPONSE_FILE_FOR_LIBRARIES OFF CACHE BOOL "" FORCE)
set(CMAKE_CUDA_DEPFILE_FORMAT "" CACHE STRING "" FORCE)
set(CMAKE_CUDA_DEPENDS_USE_COMPILER OFF CACHE BOOL "" FORCE)
set(CMAKE_CUDA_COMPILE_OBJECT
"<CMAKE_CUDA_COMPILER> <DEFINES> <INCLUDES> <FLAGS> -o <OBJECT> -c <SOURCE> --compiler-options \"/bigobj /EHsc /MD /D_ALLOW_COMPILER_AND_STL_VERSION_MISMATCH\""
CACHE STRING "" FORCE)
endif()
if(SD_CUDA)
project(libnd4j LANGUAGES C CXX CUDA)
else()
project(libnd4j LANGUAGES C CXX)
endif()
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Configure ccache for CUDA if available
if(CCACHE_PROGRAM AND SD_CUDA AND CMAKE_CUDA_COMPILER)
set(CMAKE_CUDA_COMPILER_LAUNCHER "${CCACHE_PROGRAM}" CACHE STRING "CUDA compiler launcher" FORCE)
message(STATUS "✅ Enabled ccache for CUDA compilation")
# Configure ccache settings for optimal performance
execute_process(COMMAND ${CCACHE_PROGRAM} --max-size=10G ERROR_QUIET)
execute_process(COMMAND ${CCACHE_PROGRAM} --set-config=compression=true ERROR_QUIET)
execute_process(COMMAND ${CCACHE_PROGRAM} --set-config=compression_level=6 ERROR_QUIET)
# Show ccache statistics
execute_process(
COMMAND ${CCACHE_PROGRAM} --show-stats
OUTPUT_VARIABLE CCACHE_STATS
ERROR_QUIET
)
message(STATUS "📊 Ccache statistics:\n${CCACHE_STATS}")
endif()
if(NOT SD_CUDA)
if(NOT SD_CPU)
set(SD_CUDA FALSE)
set(SD_CPU TRUE)
endif()
endif()
if(SD_CUDA)
set(DEFAULT_ENGINE "samediff::ENGINE_CUDA")
add_compile_definitions(DEFAULT_ENGINE=samediff::ENGINE_CUDA)
else()
set(DEFAULT_ENGINE "samediff::ENGINE_CPU")
add_compile_definitions(DEFAULT_ENGINE=samediff::ENGINE_CPU)
endif()
if(NOT DEFINED SD_LIBRARY_NAME)
if(SD_CUDA)
set(SD_LIBRARY_NAME nd4jcuda)
else()
set(SD_LIBRARY_NAME nd4jcpu)
endif()
endif()
include(PrintingUtilities)
include(Options)
include(PlatformDetection)
include(TypeSystem)
include(TypeCombinationEngine)
include(TypeValidation)
include(TypeProfiles)
include(SemanticTypeFiltering)
include(SelectiveRenderingIntegration)
include(Dependencies)
include(CompilerOptimizations)
include(PlatformOptimizations)
LIBND4J_SETUP_TYPE_VALIDATION()
message(STATUS "=== TYPE SETUP VERIFICATION ===")
if(DEFINED SD_TYPES_LIST AND SD_TYPES_LIST)
message(STATUS "SD_TYPES_LIST: ${SD_TYPES_LIST}")
list(LENGTH SD_TYPES_LIST type_count)
message(STATUS "Type count: ${type_count}")
else()
message(STATUS "SD_TYPES_LIST: Not defined (ALL TYPES mode)")
endif()
if(DEFINED SD_TYPES_LIST_COUNT)
message(STATUS "SD_TYPES_LIST_COUNT: ${SD_TYPES_LIST_COUNT}")
endif()
get_directory_property(COMPILE_DEFS COMPILE_DEFINITIONS)
message(STATUS "Some compile definitions: ${COMPILE_DEFS}")
message(STATUS "==============================")
# Include JNI configuration BEFORE MainBuildFlow so JVM_LIBRARY is available for linking
include(cmake/JNIConfiguration.cmake)
include(cmake/MainBuildFlow.cmake)
if(SD_CUDA)
include(cmake/CudaConfiguration.cmake)
setup_cuda_build()
else()
setup_cpu_environment()
endif()
if(WIN32 AND SD_CUDA)
function(apply_cuda_target_fixes)
get_property(all_targets DIRECTORY PROPERTY BUILDSYSTEM_TARGETS)
foreach(target ${all_targets})
if(TARGET ${target})
get_target_property(target_type ${target} TYPE)
if(target_type STREQUAL "OBJECT_LIBRARY" OR target_type STREQUAL "SHARED_LIBRARY")
get_target_property(compile_options ${target} COMPILE_OPTIONS)
if(compile_options)
list(FILTER compile_options EXCLUDE REGEX "/FS")
list(FILTER compile_options EXCLUDE REGEX "/Fd")
set_target_properties(${target} PROPERTIES COMPILE_OPTIONS "${compile_options}")
endif()
set_property(TARGET ${target} PROPERTY CUDA_FLAGS "")
set_target_properties(${target} PROPERTIES
CUDA_RESOLVE_DEVICE_SYMBOLS ON
CUDA_SEPARABLE_COMPILATION ON
MSVC_RUNTIME_LIBRARY "MultiThreadedDLL"
)
endif()
endif()
endforeach()
endfunction()
apply_cuda_target_fixes()
endif()
if(NOT TARGET analyze_types)
add_custom_target(analyze_types
COMMAND ${CMAKE_COMMAND} -E echo "Analyzing type usage..."
COMMENT "Analyzing type usage patterns in codebase"
VERBATIM
)
endif()
add_custom_target(verify_types
COMMAND ${CMAKE_COMMAND} -E echo "Verifying type configuration..."
COMMAND ${CMAKE_COMMAND} -E echo "Check build logs above for type setup verification"
COMMENT "Verify that type definitions are properly set"
VERBATIM
)
if(BUILD_PPSTEP)
include(cmake/Ppstep.cmake)
endif()