当前位置: 首页 > news >正文

webassembly003 whisper.cpp的项目结构CMakeLists.txt

注:带星号的为非重要部分

基础配置

cmake_minimum_required (VERSION 3.5)project(whisper.cpp VERSION 1.5.0)# Add path to modules
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
# 在\cmake文件夹下还有BuildTypes.cmake,DefaultTargetOptions.cmake,GitVars.cmake几个文件
# CMAKE_MODULE_PATH是供搜索第三方库用的路径变量,因此可在项目中引用自定义模块:
#include(BuildTypes) 在第13行
#include(DefaultTargetOptions) 在第425和478行,为指定的目标设置一些默认的编译特性和属性,以确保项目在编译和安装时的一致性和可靠性。
#include(GitVars) 在第12行
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) # 设置CMAKE_CURRENT_SOURCE_DIR变量,应该是可执行文件的输出目录# 如果当前的源目录等于根源目录
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)set(WHISPER_STANDALONE ON)  # 标志 WHISPER_STANDALONE 设置为 ONinclude(GitVars)  # 引用 GitVars 模块include(BuildTypes)  # 引用 BuildTypes 模块# 配置封装到其他语言的项目版本相关,详见Note1if (EXISTS "${CMAKE_SOURCE_DIR}/bindings/ios/Makefile-tmpl")configure_file(${CMAKE_SOURCE_DIR}/bindings/ios/Makefile-tmpl ${CMAKE_SOURCE_DIR}/bindings/ios/Makefile @ONLY)endif()configure_file(${CMAKE_SOURCE_DIR}/bindings/javascript/package-tmpl.json ${CMAKE_SOURCE_DIR}/bindings/javascript/package.json @ONLY)else() # 如果当前源目录不是根源目录set(WHISPER_STANDALONE OFF) # 则将 WHISPER_STANDALONE 标志设置为 OFF
endif()

DefaultTargetOptions

# Set the default compile features and properties for a target.if (NOT TARGET)message(FATAL_ERROR "TARGET not set before including DefaultTargetOptions")
endif()target_compile_features(${TARGET}PRIVATEcxx_std_11)set_target_properties(${TARGET}PROPERTIESEXPORT_COMPILE_COMMANDS ONRUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib"
)

GIT*

find_package(Git)# the commit's SHA1
execute_process(COMMAND"${GIT_EXECUTABLE}" describe --match=NeVeRmAtCh --always --abbrev=8WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"OUTPUT_VARIABLE GIT_SHA1ERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)# the date of the commit
execute_process(COMMAND"${GIT_EXECUTABLE}" log -1 --format=%ad --date=localWORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"OUTPUT_VARIABLE GIT_DATEERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)# the subject of the commit
execute_process(COMMAND"${GIT_EXECUTABLE}" log -1 --format=%sWORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"OUTPUT_VARIABLE GIT_COMMIT_SUBJECTERROR_QUIET OUTPUT_STRIP_TRAILING_WHITESPACE)

BuildTypes*

# Add new build types# ReleaseGG - Release with enabled assertsSET(CMAKE_CXX_FLAGS_RELEASEGG"-O3"CACHE STRING "Flags used by the c++ compiler during release builds with enabled asserts."FORCE )
SET(CMAKE_C_FLAGS_RELEASEGG"-O3"CACHE STRING "Flags used by the compiler during release builds with enabled asserts."FORCE )
SET(CMAKE_EXE_LINKER_FLAGS_RELEASEGG""CACHE STRING "Flags used for linking binaries during release builds with enabled asserts."FORCE )
SET(CMAKE_SHARED_LINKER_FLAGS_RELEASEGG""CACHE STRING "Flags used by the shared libraries linker during release builds with enabled asserts."FORCE )
MARK_AS_ADVANCED(CMAKE_CXX_FLAGS_RELEASEGGCMAKE_C_FLAGS_RELEASEGGCMAKE_EXE_LINKER_FLAGS_RELEASEGGCMAKE_SHARED_LINKER_FLAGS_RELEASEGG )# RelWithDebInfoGG - RelWithDebInfo with enabled assertsSET(CMAKE_CXX_FLAGS_RELWITHDEBINFOGG"-O2 -g"CACHE STRING "Flags used by the c++ compiler during release builds with debug symbols and enabled asserts."FORCE )
SET(CMAKE_C_FLAGS_RELWITHDEBINFOGG"-O2 -g"CACHE STRING "Flags used by the compiler during release builds with debug symbols and enabled asserts."FORCE )
SET(CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFOGG""CACHE STRING "Flags used for linking binaries during release builds with debug symbols and enabled asserts."FORCE )
SET(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFOGG""CACHE STRING "Flags used by the shared libraries linker during release builds with debug symbols and enabled asserts."FORCE )
MARK_AS_ADVANCED(CMAKE_CXX_FLAGS_RELWITHDEBINFOGGCMAKE_C_FLAGS_RELWITHDEBINFOGGCMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFOGGCMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFOGG )if (NOT XCODE AND NOT MSVC AND NOT CMAKE_BUILD_TYPE)set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "MinSizeRel" "RelWithDebInfo" "ReleaseGG" "RelWithDebInfoGG")
endif()

WASM配置*

# 检查是否使用 Emscripten 工具链进行交叉编译
if (EMSCRIPTEN)# 如果是 Emscripten,设置默认值为不构建共享库set(BUILD_SHARED_LIBS_DEFAULT OFF)# 添加选项,用于指定是否将 WASM 嵌入到生成的 whisper.js 文件中option(WHISPER_WASM_SINGLE_FILE "whisper: embed WASM inside the generated whisper.js" ON)
else()# 如果不是 Emscripten,进一步检查是否使用 MinGW 工具链if (MINGW)# 如果是 MinGW,设置默认值为不构建共享库set(BUILD_SHARED_LIBS_DEFAULT OFF)else()# 如果不是 Emscripten 且不是 MinGW,设置默认值为构建共享库set(BUILD_SHARED_LIBS_DEFAULT ON)endif()
endif()

options编译选项

# 如果目标平台是苹果 (Apple)
if (APPLE)set(WHISPER_METAL_DEFAULT ON)  # 设置 WHISPER_METAL_DEFAULT 为 ON,Metal是苹果发布的一套操作GPU的编程API
else()set(WHISPER_METAL_DEFAULT OFF)# 否则设置 WHISPER_METAL_DEFAULT 为 OFF
endif()# 定义构建共享库的选项,并设置默认值为 BUILD_SHARED_LIBS_DEFAULT
option(BUILD_SHARED_LIBS              "whisper: build shared libs" ${BUILD_SHARED_LIBS_DEFAULT})# 编译器选项
# 编译器警告的选项
option(WHISPER_ALL_WARNINGS           "whisper: enable all compiler warnings"                   ON)# 定义启用所有编译器警告的选项
option(WHISPER_ALL_WARNINGS_3RD_PARTY "whisper: enable all compiler warnings in 3rd party libs" OFF)# 定义启用所有第三方库中编译器警告的选项
# 编译器自带的调试工具sanitizers选项:
option(WHISPER_SANITIZE_THREAD        "whisper: enable thread sanitizer"    OFF)# 定义启用线程 Sanitizer 的选项
option(WHISPER_SANITIZE_ADDRESS       "whisper: enable address sanitizer"   OFF)# 定义启用地址 Sanitizer 的选项 ASan 是一种结合编译器插桩和运行时的一种快速内存检测工具,主要用于检测代码中的部分 内存安全 问题
option(WHISPER_SANITIZE_UNDEFINED     "whisper: enable undefined sanitizer" OFF)# 定义启用未定义行为 Sanitizer 的选项# 是否构建示例和测试
option(WHISPER_BUILD_TESTS            "whisper: build tests"    ${WHISPER_STANDALONE})# 定义构建测试的选项
option(WHISPER_BUILD_EXAMPLES         "whisper: build examples" ${WHISPER_STANDALONE})# 定义构建示例的选项# 定义支持 libSDL2 的选项,Simple DirectMedia Layer是一个跨平台开发库,旨在通过OpenGL和Direct3D提供对音频、键盘、鼠标、操纵杆和图形硬件的低级别访问。https://github.com/libsdl-org/SDL
option(WHISPER_SDL2                   "whisper: support for libSDL2" OFF)# 定义禁用 AVX 指令集的选项
option(WHISPER_NO_AVX                 "whisper: disable AVX"  OFF)
# 定义禁用 AVX2 指令集的选项
option(WHISPER_NO_AVX2                "whisper: disable AVX2" OFF)
# 定义禁用 FMA 指令集的选项, FMA指令集是128位元和256位元的流式單指令流多資料流擴充集( SSE )指令集
option(WHISPER_NO_FMA                 "whisper: disable FMA"  OFF)
# 定义禁用 F16c 指令集的选项,F16C指令就是AMD的CVT16指令,Intel换了一个名称,随后AMD也接收了这一称呼。Intel 首次在 2012 年的 Ivy Bridge 微架构处理器上使用。
option(WHISPER_NO_F16C                "whisper: disable F16c" OFF)# 定义支持 OpenVINO 的选项
option(WHISPER_OPENVINO               "whisper: support for OpenVINO" OFF)# 如果目标平台是苹果 (Apple)
if (APPLE)# 定义禁用 Accelerate framework 的选项option(WHISPER_NO_ACCELERATE         "whisper: disable Accelerate framework" OFF)# 定义使用 Metal 的选项,并设置默认值为 WHISPER_METAL_DEFAULToption(WHISPER_METAL                 "whisper: use Metal"                    ${WHISPER_METAL_DEFAULT})# 定义禁用 Metal 调试的选项option(WHISPER_METAL_NDEBUG          "whisper: disable Metal debugging"      OFF)# 定义启用 Core ML framework 的选项option(WHISPER_COREML                "whisper: enable Core ML framework"     OFF)# 定义允许使用非-CoreML的回退的选项option(WHISPER_COREML_ALLOW_FALLBACK "whisper: allow non-CoreML fallback"    OFF)
else()# 如果不是苹果,则定义使用 BLAS 库的选项option(WHISPER_BLAS                  "whisper: use BLAS libraries"  OFF)# 定义 BLAS 库的供应商选项option(WHISPER_BLAS_VENDOR           "whisper: BLAS library vendor" Generic)# 定义优先使用 OpenBLAS 的选项option(WHISPER_OPENBLAS              "whisper: prefer OpenBLAS"     OFF)# 定义支持 cuBLAS 的选项option(WHISPER_CUBLAS                "whisper: support for cuBLAS"  OFF)# 定义支持 hipBLAS 的选项option(WHISPER_HIPBLAS               "whisper: support for hipBLAS" OFF)# 定义使用 CLBlast 的选项option(WHISPER_CLBLAST               "whisper: use CLBlast"         OFF)
endif()# 定义启用性能分析的选项
option(WHISPER_PERF "whisper: enable perf timings" OFF)
# sanitizers# 如果不是使用 MSVC 编译器
if (NOT MSVC)# 如果启用 Thread Sanitizerif (WHISPER_SANITIZE_THREAD)# 添加线程 Sanitizer 的编译选项set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   -fsanitize=thread")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread")endif()# 如果启用 Address Sanitizerif (WHISPER_SANITIZE_ADDRESS)# 添加地址 Sanitizer 的编译选项,并保留函数调用栈信息set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}     -fsanitize=address -fno-omit-frame-pointer")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address -fno-omit-frame-pointer")endif()# 如果启用 Undefined Behavior Sanitizerif (WHISPER_SANITIZE_UNDEFINED)# 添加未定义行为 Sanitizer 的编译选项set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}     -fsanitize=undefined")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")endif()
endif()# 以下两行是注释掉的代码,未启用
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffast-math")
#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -march=native")

dependencies依赖

# 使用 find_package 查找 Threads 库,找到 Threads 库后,可以使用 Threads::Threads 在后续的目标中链接该库
find_package(Threads REQUIRED)

if (APPLE)*

# on APPLE
if (APPLE)# include Accelerate frameworkif (NOT WHISPER_NO_ACCELERATE)find_library(ACCELERATE_FRAMEWORK Accelerate)if (ACCELERATE_FRAMEWORK)message(STATUS "Accelerate framework found")set(WHISPER_EXTRA_LIBS  ${WHISPER_EXTRA_LIBS}  ${ACCELERATE_FRAMEWORK})set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_ACCELERATE)else()message(FATAL_ERROR "Accelerate framework not found")endif()endif()if (WHISPER_METAL)find_library(FOUNDATION_LIBRARY         Foundation              REQUIRED)find_library(METAL_FRAMEWORK            Metal                   REQUIRED)find_library(METALKIT_FRAMEWORK         MetalKit                REQUIRED)if (METAL_FRAMEWORK)message(STATUS "Metal framework found")set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS}${FOUNDATION_LIBRARY}${METAL_FRAMEWORK}${METALKIT_FRAMEWORK})set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_METAL)if (WHISPER_METAL_NDEBUG)set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_METAL_NDEBUG)endif()else()message(FATAL_ERROR "Metal framework not found")endif()set(GGML_SOURCES_METAL ggml-metal.m ggml-metal.h)# copy ggml-metal.metal to bin directoryconfigure_file(ggml-metal.metal bin/ggml-metal.metal COPYONLY)endif()if (WHISPER_COREML)find_library(FOUNDATION_FRAMEWORK Foundation)find_library(COREML_FRAMEWORK CoreML)if (COREML_FRAMEWORK)message(STATUS "CoreML framework found")set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DWHISPER_USE_COREML)else()message(FATAL_ERROR "CoreML framework not found")endif()if (WHISPER_COREML_ALLOW_FALLBACK)set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DWHISPER_COREML_ALLOW_FALLBACK)endif()endif()
endif()

if (WHISPER_OPENBLAS)*

if (WHISPER_OPENBLAS)set(WHISPER_BLAS_VENDOR "OpenBLAS")set(WHISPER_BLAS ON)
endif()if (WHISPER_BLAS)if (WIN32)if(DEFINED ENV{OPENBLAS_PATH})set(BLAS_LIBRARIES $ENV{OPENBLAS_PATH}/lib/libopenblas.dll.a)message(STATUS "Libraries ${BLAS_LIBRARIES}")set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_OPENBLAS)include_directories($ENV{OPENBLAS_PATH}/include)set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} ${BLAS_LIBRARIES})else ()message(FATAL_ERROR "BLAS library was not found. Environment variable OPENBLAS_PATH not defined.")endif ()else ()set(BLA_STATIC 1)set(BLA_VENDOR ${WHISPER_BLAS_VENDOR})set(BLA_SIZEOF_INTEGER 8)set(BLA_PREFER_PKGCONFIG 1)find_package(BLAS)if(BLAS_FOUND)message(STATUS "BLAS compatible library found")message(STATUS "Libraries ${BLAS_LIBRARIES}")find_path(BLAS_INCLUDE_DIRS cblas.h /usr/include/openblas /usr/local/include/openblas $ENV{BLAS_HOME}/include)set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_USE_OPENBLAS)include_directories(${BLAS_INCLUDE_DIRS})set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} ${BLAS_LIBRARIES})else()message(FATAL_ERROR "BLAS library was not found")endif()endif ()
endif ()if (WHISPER_CUBLAS)cmake_minimum_required(VERSION 3.17)find_package(CUDAToolkit)if (CUDAToolkit_FOUND)message(STATUS "cuBLAS found")enable_language(CUDA)set(GGML_SOURCES_CUDA ggml-cuda.cu ggml-cuda.h)add_compile_definitions(GGML_USE_CUBLAS)if (WHISPER_STATIC)set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} CUDA::cudart_static CUDA::cublas_static CUDA::cublasLt_static)else()set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} CUDA::cudart CUDA::cublas CUDA::cublasLt)endif()else()message(FATAL_ERROR "cuBLAS not found")endif()
endif()if (WHISPER_HIPBLAS)list(APPEND CMAKE_PREFIX_PATH /opt/rocm)if (NOT ${CMAKE_C_COMPILER_ID} MATCHES "Clang")message(WARNING "Only LLVM is supported for HIP, hint: CC=/opt/rocm/llvm/bin/clang")endif()if (NOT ${CMAKE_CXX_COMPILER_ID} MATCHES "Clang")message(WARNING "Only LLVM is supported for HIP, hint: CXX=/opt/rocm/llvm/bin/clang++")endif()find_package(hip)find_package(hipblas)find_package(rocblas)if (${hipblas_FOUND} AND ${hip_FOUND})message(STATUS "HIP and hipBLAS found")add_compile_definitions(GGML_USE_HIPBLAS GGML_USE_CUBLAS)add_library(ggml-rocm OBJECT ggml-cuda.cu ggml-cuda.h)set_property(TARGET ggml-rocm PROPERTY POSITION_INDEPENDENT_CODE ON)set_source_files_properties(ggml-cuda.cu PROPERTIES LANGUAGE CXX)target_link_libraries(ggml-rocm PRIVATE hip::device PUBLIC hip::host roc::rocblas roc::hipblas)if (WHISPER_STATIC)message(FATAL_ERROR "Static linking not supported for HIP/ROCm")endif()set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} ggml-rocm)else()message(FATAL_ERROR "hipBLAS or HIP not found. Try setting CMAKE_PREFIX_PATH=/opt/rocm")endif()
endif()if (WHISPER_CLBLAST)find_package(CLBlast)if (CLBlast_FOUND)message(STATUS "CLBlast found")set(GGML_SOURCES_OPENCL ggml-opencl.cpp ggml-opencl.h)add_compile_definitions(GGML_USE_CLBLAST)set(WHISPER_EXTRA_LIBS ${WHISPER_EXTRA_LIBS} clblast)else()message(FATAL_ERROR "CLBlast not found")endif()
endif()if( WHISPER_OPENVINO )find_package(OpenVINO REQUIRED COMPONENTS Runtime)
endif()

编译器选项

构建类型,如 Debug、Release*

# compiler flags# 如果没有设置 CMAKE_BUILD_TYPE(用于指定构建类型,如 Debug、Release)且没有配置 CMAKE_CONFIGURATION_TYPES(多配置构建的情况下),则进行以下设置
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)# 设置构建类型为 Release,并将其缓存set(CMAKE_BUILD_TYPE Release CACHE STRING "Build type" FORCE)# 设置 CMAKE_BUILD_TYPE 的可选值为 "Debug""Release""RelWithDebInfo"set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release" "RelWithDebInfo")
endif ()

warning*

if (WHISPER_ALL_WARNINGS)if (NOT MSVC)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} \-Wall                           \-Wextra                         \-Wpedantic                      \-Wshadow                        \-Wcast-qual                     \-Wstrict-prototypes             \-Wpointer-arith                 \-Wno-unused-function            \")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} \-Wall                           \-Wextra                         \-Wpedantic                      \-Wcast-qual                     \")else()# todo : msvcendif()
endif()

MSVC*

if (NOT MSVC)# 如果不是使用 MSVC 编译器,则添加编译选项 -Werror=vla,将变长数组 (VLA) 的警告视为错误set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Werror=vla")# 下面两行是注释掉的代码,可以用于进一步设置编译选项(未启用)#set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-math-errno -ffinite-math-only -funsafe-math-optimizations")
endif()# 输出 CMAKE_SYSTEM_PROCESSOR 的信息到状态消息
message(STATUS "CMAKE_SYSTEM_PROCESSOR: ${CMAKE_SYSTEM_PROCESSOR}")

硬件设置(AVX之类的)

if (${CMAKE_SYSTEM_PROCESSOR} MATCHES "arm" OR ${CMAKE_SYSTEM_PROCESSOR} MATCHES "aarch64")message(STATUS "ARM detected")
elseif(${CMAKE_SYSTEM_PROCESSOR} MATCHES "ppc64le")message(STATUS "PowerPC detected")
else()message(STATUS "x86 detected")if (MSVC)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /utf-8")set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /utf-8")if(NOT WHISPER_NO_AVX2)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /arch:AVX2")set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:AVX2")else()if(NOT WHISPER_NO_AVX)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX")set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /arch:AVX")set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /arch:AVX")endif()endif()else()if (EMSCRIPTEN)set(CMAKE_C_FLAGS   "${CMAKE_C_FLAGS}   -pthread")set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")else()if(NOT WHISPER_NO_AVX)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx")endif()if(NOT WHISPER_NO_AVX2)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mavx2")endif()if(NOT WHISPER_NO_FMA)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mfma")endif()if(NOT WHISPER_NO_F16C)set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mf16c")endif()endif()endif()
endif()

配置 可移植操作系统接口POSIX 兼容性

  • POSIX:可移植操作系统接口(Portable Operating System Interface of UNIX,缩写为 POSIX )
#
# POSIX conformance
## clock_gettime came in POSIX.1b (1993)
# CLOCK_MONOTONIC came in POSIX.1-2001 / SUSv3 as optional
# posix_memalign came in POSIX.1-2001 / SUSv3
# M_PI is an XSI extension since POSIX.1-2001 / SUSv3, came in XPG1 (1985)
add_compile_definitions(_XOPEN_SOURCE=600) # 通过 add_compile_definitions 命令(Note2),将预处理宏 _XOPEN_SOURCE 的定义设置为 600。这个宏用于启用或禁用一些特定于 UNIX 系统的功能。在这里,设置为 600 表示支持 POSIX.1-2001 / SUSv3 标准及更早的版本。# Somehow in OpenBSD whenever POSIX conformance is specified
# some string functions rely on locale_t availability,
# which was introduced in POSIX.1-2008, forcing us to go higher
if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD") # OpenBSD 系统,Linux 和 BSD 都是免费的,开源的,类Unix系统。OpenBSD的目标系统类型是服务器、NAS、工作站和嵌入式系统。remove_definitions(-D_XOPEN_SOURCE=600)# 移除先前的 -D_XOPEN_SOURCE=600 定义add_compile_definitions(_XOPEN_SOURCE=700)# 设置 _XOPEN_SOURCE 的定义为 700
endif()# Data types, macros and functions related to controlling CPU affinity
# are available on Linux through GNU extensions in libc
if (CMAKE_SYSTEM_NAME MATCHES "Linux")# Linux 系统add_compile_definitions(_GNU_SOURCE)# 添加 _GNU_SOURCE 的编译定义,这个宏是为了启用 GNU C 库(glibc)中的一些特定功能和扩展,包括与 CPU 亲和性相关的数据类型、宏和函数。
endif()# RLIMIT_MEMLOCK came in BSD, is not specified in POSIX.1,
# and on macOS its availability depends on enabling Darwin extensions
# similarly on DragonFly, enabling BSD extensions is necessary
if (CMAKE_SYSTEM_NAME MATCHES "Darwin") # 如果系统是 Darwin(Apple现在的主要操作系统,无论是macOS、iOS还是iPadOS,甚至是HomePod和Apple TV(TvOS)都是建立在Darwin的基础上),则添加 _DARWIN_C_SOURCE 的编译定义add_compile_definitions(_DARWIN_C_SOURCE)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "DragonFly")# 如果系统是 DragonFly,则添加 _DARWIN_C_SOURCE 的编译定义add_compile_definitions(_DARWIN_C_SOURCE)
endif()# alloca is a non-standard interface that is not visible on BSDs when
# POSIX conformance is specified, but not all of them provide a clean way
# to enable it in such cases
if (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")# 如果系统是 FreeBSD,则添加 __BSD_VISIBLE 的编译定义add_compile_definitions(__BSD_VISIBLE)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "NetBSD")# 如果系统是 NetBSD,则添加 _NETBSD_SOURCE 的编译定义add_compile_definitions(_NETBSD_SOURCE)
endif()
if (CMAKE_SYSTEM_NAME MATCHES "OpenBSD")# 如果系统是 OpenBSD,则添加 _BSD_SOURCE 的编译定义add_compile_definitions(_BSD_SOURCE)
endif()
# perf性能测试相关,暂时不是很重要
if (WHISPER_PERF)set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DGGML_PERF)
endif()

Core ML framework和OPENVINO*

  • Core ML 是一个 Apple 框架,允许开发人员轻松集成 机器学习 (ML) 模型到应用中。Core ML 可在 iOS、iPadOS、 watchOS、macOS 和 Apple tvOS。Core ML 引入了公共文件格式 (.mlmodel) 适用于广泛的 ML 方法,包括深度神经网络(卷积 和循环)、树集成(提升树、随机森林、决策树)、 和广义线性模型。Core ML 模型可直接集成到 Xcode 中的 App。 Core ML 通过利用 Apple 硬件并最大限度地减少内存占用和功耗,针对各种型号类型的设备端性能进行了优化。 Core ML 旨在通过利用其 CPU、GPU 和神经网络引擎来优化设备性能,同时将内存和功耗降至最低。应用程序使用 CoreML 应用程序编程接口 (API) 在每个用户拥有的所有设备上进行预测和微调模型。可以转换为Core ML的模型格式有Caffe、Keras、XGBoost、 Scikit-learn 、MXNet 、 LibSVM 和 Torch7。
  • 英特尔的OpenVINO™ 工具套件:一款可轻松实现“一次写入,处处部署”的开源工具套件
#
# whisper.coreml - Core ML support
#
if (WHISPER_COREML)set(TARGET whisper.coreml)add_library(${TARGET}coreml/whisper-encoder.hcoreml/whisper-encoder.mmcoreml/whisper-encoder-impl.hcoreml/whisper-encoder-impl.m)include(DefaultTargetOptions)target_include_directories(${TARGET} PUBLIC.)target_link_libraries(${TARGET} PRIVATE ${FOUNDATION_FRAMEWORK} ${COREML_FRAMEWORK})set_target_properties(${TARGET} PROPERTIESCOMPILE_FLAGS "-fobjc-arc")
endif()if (WHISPER_OPENVINO)set(TARGET whisper.openvino)add_library(${TARGET} OBJECTopenvino/whisper-openvino-encoder.hopenvino/whisper-openvino-encoder.cpp)target_include_directories(${TARGET} PUBLIC.)set_property(TARGET ${TARGET} PROPERTY POSITION_INDEPENDENT_CODE ON)set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -DWHISPER_USE_OPENVINO)target_link_libraries(${TARGET} PRIVATE openvino::runtime)
endif()

whisper库

#
# whisper - this is the main library of the project
#set(TARGET whisper)
# 生成库文件
add_library(${TARGET}ggml.hggml.cggml-alloc.hggml-alloc.cggml-backend.hggml-backend.cggml-quants.hggml-quants.c${GGML_SOURCES_METAL}${GGML_SOURCES_CUDA}${GGML_SOURCES_OPENCL}whisper.hwhisper.cpp)include(DefaultTargetOptions)target_include_directories(${TARGET} PUBLIC.)# 为TARGET添加头文件搜索路径
  • 非重要代码
if (WHISPER_COREML)target_link_libraries(${TARGET} PRIVATE whisper.coreml)
endif()if (WHISPER_OPENVINO)target_link_libraries(${TARGET} PRIVATE whisper.openvino)
endif()if (MSVC)target_link_libraries(${TARGET} PRIVATE ${WHISPER_EXTRA_LIBS} ${CMAKE_THREAD_LIBS_INIT})set(WHISPER_EXTRA_FLAGS ${WHISPER_EXTRA_FLAGS} -D_CRT_SECURE_NO_WARNINGS)
else()target_link_libraries(${TARGET} PRIVATE m ${WHISPER_EXTRA_LIBS} ${CMAKE_THREAD_LIBS_INIT})
endif()
  • 构建共享库
# 根据构建类型设置库目标的链接和编译定义
if (BUILD_SHARED_LIBS) # 默认为ON# 设置目标链接的库target_link_libraries(${TARGET} PUBLIC${CMAKE_DL_LIBS} # ${CMAKE_DL_LIBS} is the Name of library containing dlopen and dlclose,在 Unix/Linux 系统中用于动态加载共享库的函数.)# 为库目标添加编译定义(宏定义,见Note3)target_compile_definitions(${TARGET} PUBLICWHISPER_SHAREDGGML_SHARED)# 设置库目标的私有编译定义target_compile_definitions(${TARGET} PRIVATEWHISPER_BUILDGGML_BUILD)if (WHISPER_METAL)# 如果使用 苹果的Metal,则将 ggml-metal.m.metal 文件添加到资源# TODO: 我认为这应该使 ggml-metal.m "看到" "bin" 目录下的 ggml-metal.metal 文件#       但由于某种原因,在这里的工作方式与 llama.cpp 中的不同set_target_properties(${TARGET} PROPERTIES RESOURCE "${CMAKE_CURRENT_SOURCE_DIR}/ggml-metal.metal")endif()
endif()
  • 非重要代码
if (GGML_SOURCES_CUDA)message(STATUS "GGML CUDA sources found, configuring CUDA architecture")set_property(TARGET whisper PROPERTY CUDA_ARCHITECTURES OFF)set_property(TARGET whisper PROPERTY CUDA_SELECT_NVCC_ARCH_FLAGS "Auto")
endif()if (EMSCRIPTEN)set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS "-msimd128")
endif()# 使用了 target_compile_definitions 命令,将 WHISPER_EXTRA_FLAGS 中的内容添加到目标(${TARGET})的公共编译定义中。公共编译定义是指在编译目标时可见于整个项目的定义,通常是宏定义。
target_compile_definitions(${TARGET} PUBLIC${WHISPER_EXTRA_FLAGS})

install

# 设置目标属性,指定库的公共头文件
set_target_properties(${TARGET} PROPERTIES PUBLIC_HEADER "whisper.h")# 包含GNUInstallDirs模块,该模块定义了一些标准的安装目录变量
include(GNUInstallDirs)# 安装目标文件到指定目录
install(TARGETS ${TARGET}           # 目标名称LIBRARY DESTINATION lib     # 库文件的安装目录ARCHIVE DESTINATION lib/static  # 静态库文件的安装目录RUNTIME DESTINATION bin     # 可执行文件的安装目录RESOURCE DESTINATION bin    # 资源文件的安装目录PUBLIC_HEADER DESTINATION include  # 公共头文件的安装目录
)

绑定和测试*

#
# bindings
#add_subdirectory(bindings)#
# programs, examples and tests
#if (WHISPER_BUILD_TESTS AND NOT CMAKE_JS_VERSION)enable_testing()add_subdirectory(tests)
endif ()if (WHISPER_BUILD_EXAMPLES)add_subdirectory(examples)
endif()

构建的过程

/bin/cmake/linux/bin/cmake --build /home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug --target bench -- -j 8
gmake[1]: 进入目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
gmake[2]: 进入目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
gmake[3]: 进入目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
Scanning dependencies of target whisper # 构建 `whisper` 库
gmake[3]: 离开目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
gmake[3]: 进入目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
[ 12%] Building C object CMakeFiles/whisper.dir/ggml.c.o
[ 25%] Building C object CMakeFiles/whisper.dir/ggml-alloc.c.o
[ 37%] Building C object CMakeFiles/whisper.dir/ggml-backend.c.o
[ 50%] Building C object CMakeFiles/whisper.dir/ggml-quants.c.o
[ 62%] Building CXX object CMakeFiles/whisper.dir/whisper.cpp.o
/home/pdd/le/whisper.cpp-1.5.0/whisper.cpp: In function ‘ggml_backend* whisper_backend_init(const whisper_context_params&)’:
/home/pdd/le/whisper.cpp-1.5.0/whisper.cpp:1059:75: warning: unused parameter ‘params’ [-Wunused-parameter]1059 | static ggml_backend_t whisper_backend_init(const whisper_context_params & params) {|                                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~
/home/pdd/le/whisper.cpp-1.5.0/whisper.cpp: At global scope:
/home/pdd/le/whisper.cpp-1.5.0/whisper.cpp:205:29: warning: ‘ggml_tensor* ggml_mul_mat_pad(ggml_context*, ggml_tensor*, ggml_tensor*, int)’ defined but not used [-Wunused-function]205 | static struct ggml_tensor * ggml_mul_mat_pad(struct ggml_context * ctx, struct ggml_tensor * x, struct ggml_tensor * y, int pad = 32) {|                             ^~~~~~~~~~~~~~~~
[ 75%] Linking CXX shared library libwhisper.so # 链接 `whisper` 库(`libwhisper.so`)
gmake[3]: 离开目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
[ 75%] Built target whisper
gmake[3]: 进入目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
Scanning dependencies of target bench
gmake[3]: 离开目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
gmake[3]: 进入目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
[ 87%] Building CXX object examples/bench/CMakeFiles/bench.dir/bench.cpp.o
[100%] Linking CXX executable ../../bin/bench 
gmake[3]: 离开目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
[100%] Built target bench # 创建 `bench` 可执行文件
gmake[2]: 离开目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”
gmake[1]: 离开目录“/home/pdd/le/whisper.cpp-1.5.0/cmake-build-debug”Build finished

CG

  • 有关cmake和CMakeLists.txt

Note1:configure_file

configure_file 是 CMake 中用于在构建过程中生成文件的命令。它的主要作用是将源文件的内容复制到目标文件中,并在复制的过程中进行一些文本替换,替换操作依赖于 CMake 变量和配置。

语法如下:

configure_file(<input> <output> [@ONLY] [ESCAPE_QUOTES] [NEWLINE_STYLE [UNIX|DOS|WIN32|LF|CRLF|CR]])

其中:

  • <input> 是源文件的路径。
  • <output> 是目标文件的路径。
  • @ONLY 可选参数表示仅在 @ 符号引导的变量上执行替换。不提供 @ONLY 时,所有变量都将替换。
  • ESCAPE_QUOTES 可选参数表示在替换时转义引号。
  • NEWLINE_STYLE 可选参数指定换行符的风格,可以是 UNIXDOSWIN32LFCRLFCR

例子:

# CMakeLists.txtset(VERSION_MAJOR 1)
set(VERSION_MINOR 0)configure_file(config.h.in config.h @ONLY)
// config.h.in#define VERSION_MAJOR @VERSION_MAJOR@
#define VERSION_MINOR @VERSION_MINOR@

在这个例子中,config.h.in 是一个模板文件,其中使用了 @VERSION_MAJOR@@VERSION_MINOR@ 这样的占位符。通过 configure_file 命令,CMake 将替换这些占位符为相应的变量的值,并生成 config.h 文件。在这个过程中,@ONLY 表示仅替换由 @ 符号引导的变量。这个生成的 config.h 文件可以被项目的源代码使用。

此外,configure_file 还允许在配置时执行一些 CMake 脚本,进一步扩展了其功能。通过这种方式,可以在构建时生成一些特定于构建配置的文件,例如根据不同平台生成不同的配置文件。

// https://github1s.com/ggerganov/whisper.cpp/blob/v1.5.0/bindings/javascript/package-tmpl.json
{"name": "whisper.cpp","version": "@PROJECT_VERSION@","description": "Whisper speech recognition","main": "whisper.js","scripts": {"test": "echo \"todo: add tests\" && exit 0"},"repository": {"type": "git","url": "git+https://github.com/ggerganov/whisper.cpp"},"keywords": ["openai","whisper","speech-to-text","speech-recognition","transformer"],"author": "Georgi Gerganov","license": "MIT","bugs": {"url": "https://github.com/ggerganov/whisper.cpp/issues"},"homepage": "https://github.com/ggerganov/whisper.cpp#readme"
}
// https://github1s.com/ggerganov/whisper.cpp/blob/v1.5.0/bindings/javascript/package.json
{"name": "whisper.cpp","version": "1.5.0","description": "Whisper speech recognition","main": "whisper.js","scripts": {"test": "echo \"todo: add tests\" && exit 0"},"repository": {"type": "git","url": "git+https://github.com/ggerganov/whisper.cpp"},"keywords": ["openai","whisper","speech-to-text","speech-recognition","transformer"],"author": "Georgi Gerganov","license": "MIT","bugs": {"url": "https://github.com/ggerganov/whisper.cpp/issues"},"homepage": "https://github.com/ggerganov/whisper.cpp#readme"
}

Note2:add_compile_definitions

add_compile_definitions 是 CMake 中用于向目标添加编译定义(宏定义)的命令。它用于在编译时向源代码中注入预定义的宏,从而影响代码的编译行为。在上下文中,这些宏通常用于控制特定平台或编译器的特定行为。

语法如下:

add_compile_definitions(definition1 [definition2 ...])
  • definition1, definition2, …: 要添加的编译定义,可以是一个或多个。

例如,如果要向编译过程中添加一个名为 ENABLE_FEATURE_X 的宏定义,可以使用如下命令:

add_compile_definitions(ENABLE_FEATURE_X)

在你提供的代码片段中,add_compile_definitions 用于添加一些特定平台的编译定义,以启用或禁用某些非标准的接口或特性。这样,可以根据操作系统的类型为代码选择性地启用或禁用特定的功能或扩展。

Note3:target_compile_definitions

  • source.cpp:
#include <iostream>#ifdef DEBUG_MODE
#define LOG(message) std::cout << "[DEBUG] " << message << std::endl;
#else
#define LOG(message) std::cout << "[RELEASE] " << message << std::endl;
#endifint main() {LOG("Hello, world!");return 0;
}
  • CMakeLists.txt
# CMakeLists.txtcmake_minimum_required(VERSION 3.12)
project(MyProject)# 添加可执行文件目标
add_executable(my_executable my_source.cpp)# 在目标上添加 DEBUG_MODE 宏定义
target_compile_definitions(my_executable PUBLIC DEBUG_MODE)

相关文章:

webassembly003 whisper.cpp的项目结构CMakeLists.txt

注&#xff1a;带星号的为非重要部分 基础配置 cmake_minimum_required (VERSION 3.5)project(whisper.cpp VERSION 1.5.0)# Add path to modules list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") # 在\cmake文件夹下还有BuildTypes.cmake&a…...

克魔助手工具详解、数据包抓取分析、使用教程

目录 摘要 引言 克魔助手界面 克魔助手查看数据捕获列表 数据包解析窗口 数据包数据窗口 克魔助手过滤器表达式的规则 抓包过滤器实例 总结 参考资料 摘要 本文介绍了克魔助手工具的界面和功能&#xff0c;包括数据包的捕获和分析&#xff0c;以及抓包过滤器的使用方…...

【Docker】contos7安装 Nacos容器部署单个部署集群

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是平顶山大师&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的博客专栏《Docker】contos7安装 Nacos容器部署单个&…...

UML-通信图和交互概览图(通信图和顺序图的区别与联系)

UML-通信图和交互概览图&#xff08;通信图和顺序图的区别与联系&#xff09; 一、通信图简介1.消息2.链接 二、通信图和[顺序图](https://blog.csdn.net/weixin_65032328/article/details/135587782)的联系与区别三、交互概览图四、顺序图转化为通信图练习 一、通信图简介 通…...

Linux 使用PS命令掌握进程管理

在Linux系统中&#xff0c;进程管理是系统管理员和开发人员必备的技能之一。而PS命令作为进程管理的重要工具&#xff0c;可以帮助我们查看和监控系统中运行的进程。本文将详细解析PS命令的使用方法和输出结果&#xff0c;帮助读者全面掌握进程管理的利器。 PS命令概述&#xf…...

Debian 10.13.0 安装图解

引导和开始安装 这里直接回车确认即可&#xff0c;选择图形化安装方式。 选择语言 这里要区分一下&#xff0c;当前选中的语言作为安装过程中安装器所使用的语言&#xff0c;这里我们选择中文简体。不过细心的同学可能发现&#xff0c;当你选择安装器语言之后&#xff0c;后续安…...

SQLite 3.45.0 发布!

SQLite 开发团队于 2024 年 01 月 18 日发布了 SQLite 3.45.0 版本&#xff0c;带来了一些 JSON 和优化器增强&#xff0c;让我们一睹为快&#xff01; JSON 函数 SQLite 3.45.0 版本开始&#xff0c;所有的 JSON 函数将会使用全新的内部格式存储 JSON 数据&#xff0c;也就是…...

MongoDB聚合:$set

聚合$set阶段可以为文档添加新的字段。$set输出的文档包含输入文档中的所有现有字段和新添加的字段。$set是$addFields的别名&#xff0c;从MongoDB4.2开始支持。$set和$addFields等价于$project阶段&#xff0c;这两个阶段都等同于 $project 阶段&#xff0c;后者明确指定输入…...

《Python数据分析技术栈》第01章 02 Jupyter入门(Getting started with Jupyter notebooks)

02 Jupyter入门&#xff08;Getting started with Jupyter notebooks&#xff09; 《Python数据分析技术栈》第01章 02 Jupyter入门&#xff08;Getting started with Jupyter notebooks&#xff09; Before we discuss the essentials of Jupyter notebooks, let us discuss…...

【征服redis5】redis的Redisson客户端

目录 1 Redisson介绍 2. 与其他Java Redis客户端的比较 3.基本的配置与连接池 3.1 依赖和SDK 3.2 配置内容解析 4 实战案例&#xff1a;优雅的让Hash的某个Field过期 5 Redisson的强大功能 1 Redisson介绍 Redisson 最初由 GitHub 用户 “mrniko” 创建&#xff0c;并在…...

React16源码: React中的beginWork的源码实现

beginWork 1 &#xff09;概述 在 renderRoot 之后&#xff0c;要对我们的 Fiber 树每一个节点进行对应的更新更新节点的一个入口方法&#xff0c;就是 beginWork这个入口方法会有帮助我们去优化整棵树的更新过程 react 它的节点其实是非常多的&#xff0c;如果每一次子节点的…...

5-微信小程序语法参考

1. 数据绑定 官网传送门 WXML 中的动态数据均来自对应 Page 的 data。 数据绑定使用 Mustache 语法&#xff08;双大括号&#xff09;将变量包起来 ts Page({data: {info: hello wechart!,msgList: [{ msg: hello }, { msg: wechart }]}, })WXML <view class"vie…...

数组练习 Leetcode 566.重塑矩阵

在 MATLAB 中&#xff0c;有一个非常有用的函数 reshape &#xff0c;它可以将一个 m x n 矩阵重塑为另一个大小不同&#xff08;r x c&#xff09;的新矩阵&#xff0c;但保留其原始数据。 给你一个由二维数组 mat 表示的 m x n 矩阵&#xff0c;以及两个正整数 r 和 c &#…...

Linux centos中find命令的多种用途:按照具体应用来详细说明find的用法举例

目录 一、find命令 二、find命令的语法 &#xff08;一&#xff09;语法格式 &#xff08;二&#xff09;选项 1、选项(option)介绍 2、控制符号链接的option 3、调试选项debugopts 4、优化选项 &#xff08;三&#xff09;表达式expression 1、选项options 2、测试…...

服务器数据恢复—OceanStor存储raid5热备盘同步数据失败的数据恢复案例

服务器数据恢复环境&#xff1a; 华为OceanStor某型号存储&#xff0c;存储内有一组由24块硬盘组建的raid5阵列&#xff0c;配置1块热备盘。 服务器故障&#xff1a; 该存储raid5阵列中有一块硬盘离线&#xff0c;热备盘自动激活并开始同步数据&#xff0c;在热备盘同步数据的…...

Xline v0.6.1: 一个用于元数据管理的分布式KV存储

Xline是什么&#xff1f;我们为什么要做Xline&#xff1f; Xline是一个基于Curp协议的&#xff0c;用于管理元数据的分布式KV存储。现有的分布式KV存储大多采用Raft共识协议&#xff0c;需要两次RTT才能完成一次请求。当部署在单个数据中心时&#xff0c;节点之间的延迟较低&a…...

【CSS】解决height = line-height 文字不垂直居中(偏上、偏下)的问题

解决办法1&#xff1a; 查看 font-family 属性&#xff0c;确认是否是因为字体而导致的不垂直居中问题。 其他小知识&#xff1a; 基线就是小写x字母的下边缘(线) 就是我们常说的 基线。line-height 属性设置的行高也就是定义的两行文字基线之间的距离! 参考文章&#xff1a;…...

天津想转行学python培训班靠谱吗?

现在的职业如此繁多&#xff0c;很多人把高薪当成衡量工作好坏的重要标准&#xff0c;因此IT行业以超出其他行业几倍薪资水平成为不错的选择&#xff0c;而Python又以其简单易学好上手成为大家所青睐的学习目标。 Python发展前景如何 Python语言就业发展方向广泛&#xff1a;…...

(C语言)冒泡排序

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//实现buble_sort函数&#xff1b; void buble_sort(int arr[], int sz) {//初始化变量值&#xff1b;int i 0;//嵌套循环冒泡排序&#xff1b;//外层循环&…...

怎么样的布局是符合可制造性的PCB布局?

满足可制造性、可装配性、可维修性要求&#xff0c;方便调试的时候于检测和返修&#xff0c;能够方便的拆卸器件&#xff1a; 1&#xff09;极性器件的方向不要超过2种&#xff0c;最好都进行统一方向等要求&#xff0c;如图1-1所示&#xff1b; 图1-1 极性器件方向统一摆放 2…...

第28关 k8s监控实战之Prometheus(九)

------> 课程视频同步分享在今日头条和B站 大家好&#xff0c;我是博哥爱运维。早期我们经常用邮箱接收报警邮件&#xff0c;但是报警不及时&#xff0c;而且目前各云平台对邮件发送限制还比较严格&#xff0c;所以目前在生产中用得更为多的是基于webhook来转发报警内容到企…...

安全防御之可信计算技术

可信计算技术是一种计算机安全体系结构&#xff0c;旨在提高计算机系统在面临各种攻击和威胁时的安全性和保密性。它通过包括硬件加密、受限访问以及计算机系统本身的完整性验证等技术手段&#xff0c;确保计算机系统在各种攻击和威胁下保持高度安全和保密性。 一、可信计算基…...

FPGA引脚物理电平(内部资源,Select IO)-认知2

引脚电平 The SelectIO pins can be configured to various I/O standards, both single-ended and differential. • Single-ended I/O standards (e.g., LVCMOS, LVTTL, HSTL, PCI, and SSTL) • Differential I/O standards (e.g., LVDS, Mini_LVDS, RSDS, PPDS, BLVDS, and…...

PBR材质纹理下载

03:10 按照视频里的顺序 我们从第6个网站开始倒数 点击本行文字或下方链接 进入查看 6大网站地址 网址查看链接&#xff1a; http://www.uzing.net/community_show-1962-48-48-35.html 06 Tectures Wood Fence 001 | 3D TEXTURES 简介&#xff1a;最大的纹理网站之一&#x…...

mac PyCharm 使用conda环境

1 使用conda创建虚拟环境 conda create -n test6 python3.9 -y conda activate test62 选择conda环境 本地 选择已经存在的conda环境 右下角会显示现在的环境。...

10个常用的正则表达式

1 电话号码 let r1 /^1[3-9]\d{9}$/g console.log(r1.exec(18596932371)) 2 qq号 let r2 /^[1-9][0-9]{4,9}$/g console.log(r2.exec(123456)) 3 十六进制的方式表示颜色 let r3 /^#([0-9a-fA-F]{6}|[0-9a-fA-F]{3})$/g // # 可能可有可无&#xff0c;如果不需要#&a…...

对一手游的自定义 luajit 字节码的研究

对一手游的自定义 luajit 字节码的研究 前言 最近闲下来之后无聊研究起了一个unity手游 大量使用了 lua &#xff08;或者说就是 lua 写的 &#xff09; 看到网上已有的一些针对方案 都觉得太不方便 于是深入研究了一下 他自定义的 luajit 情况研究 首先 这是一个 unity的 传…...

1125. 牛的旅行 (Floyd算法,最短路)

1125. 牛的旅行 - AcWing题库 农民John的农场里有很多牧区&#xff0c;有的路径连接一些特定的牧区。 一片所有连通的牧区称为一个牧场。 但是就目前而言&#xff0c;你能看到至少有两个牧区不连通。 现在&#xff0c;John想在农场里添加一条路径&#xff08;注意&#xff…...

oracle “Interested Transaction List”(ITL)的概念

“Interested Transaction List”&#xff08;ITL&#xff09;的概念。让我们逐点理解&#xff1a; 块头和ITL&#xff1a; 每个数据库段块的块头都包含一个Interested Transaction List&#xff08;ITL&#xff09;。ITL用于确定数据库开始修改块时某个事务是否未提交。 ITL的…...

kali下-MSF-ftp_login模块破解FTP账号及密码

一、环境准备 两台设备在同一个网络内 一台kali系统&#xff1a;192.168.10.128 一台winserver2016&#xff1a;192.168.10.132 二、MSF介绍 metasploit 全称是The Metasploit Framework&#xff0c;又称MSF&#xff0c;是Kali 内置的一款渗透测试框架&#xff0c;也是全球…...