[MNN:Feature] add podspec generate from CMake.

- Add cmake/generate_podspec.cmake to auto-generate MNN.podspec from CMake targets
- Add tools/script/generate_podspec.sh with --validate, --validate-full, --check, --ci options
- Add docs/tools/podspec.md with detailed usage guide
- Update docs/compile/cmake.md with MNN_GENERATE_PODSPEC macro definition
- Add error validation for prerequisites (source dir, required dirs, LICENSE, MNN_TARGETS, version)

Discussed-in: Merge-Request 25705117 , URL: https://code.alibaba-inc.com/AliNN/AliNNPrivate/codereview/25705117
GitOrigin-RevId: cd795b54b0cd159a12f65a51ac20df8727f2c5d6
This commit is contained in:
MNNSyncBot
2026-01-28 10:48:31 +08:00
parent d79be7f94d
commit 6f49e8b11d
24 changed files with 1817 additions and 96 deletions
+6
View File
@@ -81,6 +81,7 @@ option(MNN_CPU_WEIGHT_DEQUANT_GEMM "Build MNN CPU weight dequant related gemm ke
option(MNN_BUILD_AUDIO "Build audio api in MNN." OFF)
option(MNN_SME2 "Use Arm sme2 instructions" ON)
option(MNN_METAL_TENSOR "Use Metal4 tensor instructions" ON)
option(MNN_GENERATE_PODSPEC "Generate iOS podspec file from CMake configuration" OFF)
if (MNN_BUILD_MINI)
set(MNN_SKIPBUILD_GEOMETRY ON CACHE BOOL "<docstring>" FORCE)
@@ -1085,3 +1086,8 @@ ENDIF()
if (MNN_JNI)
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/source/jni/)
endif()
if (MNN_GENERATE_PODSPEC)
include(${CMAKE_CURRENT_LIST_DIR}/cmake/generate_podspec.cmake)
generate_mnn_podspec_from_targets()
endif()
+854 -64
View File
@@ -1,79 +1,869 @@
# =============================================================================
# MNN.podspec
# Auto-generated by CMake, DO NOT EDIT!
# Command: cmake .. -DMNN_GENERATE_PODSPEC=ON
# =============================================================================
Pod::Spec.new do |s|
s.name = "MNN"
s.version = "2.2.0"
s.summary = "MNN"
s.version = "3.5.0"
s.summary = "MNN - A lightweight deep neural network inference framework"
s.description = <<-DESC
MNN is a lightweight deep neural network inference framework. It loads models and do inference on devices.
MNN is a blazing fast, lightweight deep neural network inference engine.
Auto-generated from CMake configuration.
DESC
s.homepage = "https://github.com/alibaba/MNN"
s.license = {
:type => 'Apache License, Version 2.0',
:text => <<-LICENSE
Copyright © 2018, Alibaba Group Holding Limited
s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' }
s.author = { "MNN" => "mnn@alibaba-inc.com" }
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
s.platform = :ios
s.ios.deployment_target = '11.0'
http://www.apache.org/licenses/LICENSE-2.0
# .mm files require ARC
s.requires_arc = [
'source/backend/metal/MNNMetalContext.mm',
'source/backend/metal/MetalArgMax.mm',
'source/backend/metal/MetalAttention.mm',
'source/backend/metal/MetalBackend.mm',
'source/backend/metal/MetalBinary.mm',
'source/backend/metal/MetalCast.mm',
'source/backend/metal/MetalConvolution.mm',
'source/backend/metal/MetalConvolution1x1.mm',
'source/backend/metal/MetalConvolutionCommon.mm',
'source/backend/metal/MetalConvolutionDepthwise.mm',
'source/backend/metal/MetalConvolutionWinograd.mm',
'source/backend/metal/MetalDeconvolution.mm',
'source/backend/metal/MetalEltwise.mm',
'source/backend/metal/MetalExecution.mm',
'source/backend/metal/MetalFuse.mm',
'source/backend/metal/MetalGridSample.mm',
'source/backend/metal/MetalInterp.mm',
'source/backend/metal/MetalKVCacheManager.mm',
'source/backend/metal/MetalLayerNorm.mm',
'source/backend/metal/MetalLinearAttention.mm',
'source/backend/metal/MetalLoop.mm',
'source/backend/metal/MetalMatMul.mm',
'source/backend/metal/MetalOPRegister.mm',
'source/backend/metal/MetalPReLU.mm',
'source/backend/metal/MetalPooling.mm',
'source/backend/metal/MetalROIPooling.mm',
'source/backend/metal/MetalRaster.mm',
'source/backend/metal/MetalReLU6.mm',
'source/backend/metal/MetalReduction.mm',
'source/backend/metal/MetalScale.mm',
'source/backend/metal/MetalSoftmax.mm',
'source/backend/metal/MetalTopKV2.mm',
'source/backend/metal/MetalUnary.mm'
]
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
LICENSE
s.source = { :git => "https://github.com/alibaba/MNN.git", :tag => "#{s.version}" }
s.frameworks = 'Metal', 'Accelerate', 'CoreVideo', 'Foundation'
s.weak_frameworks = 'MetalPerformanceShaders'
s.libraries = 'c++'
# =============================================================================
# Source files - Auto-extracted from CMake targets
# Total 656 files
# =============================================================================
s.source_files = [
# Public headers
'include/MNN/*.{h,hpp}',
'include/MNN/expr/*.{h,hpp}',
'schema/current/*.{h}',
'3rd_party/flatbuffers/include/flatbuffers/*.{h}',
'3rd_party/half/*.{hpp}',
# Source files extracted from CMake targets
'source/core/AutoStorage.h',
'source/core/AutoTime.cpp',
'source/core/Backend.cpp',
'source/core/Backend.hpp',
'source/core/BufferAllocator.cpp',
'source/core/BufferAllocator.hpp',
'source/core/Command.hpp',
'source/core/CommonCompute.hpp',
'source/core/Concurrency.h',
'source/core/ConvolutionCommon.cpp',
'source/core/ConvolutionCommon.hpp',
'source/core/Execution.cpp',
'source/core/Execution.hpp',
'source/core/FileLoader.cpp',
'source/core/FileLoader.hpp',
'source/core/IDSTEncoder.hpp',
'source/core/Interpreter.cpp',
'source/core/KVCacheManager.cpp',
'source/core/KVCacheManager.hpp',
'source/core/KVMeta.hpp',
'source/core/MNNFileUtils.cpp',
'source/core/MNNFileUtils.h',
'source/core/MNNMemoryUtils.cpp',
'source/core/MNNMemoryUtils.h',
'source/core/Macro.h',
'source/core/MemoryFormater.h',
'source/core/NonCopyable.hpp',
'source/core/OpCommonUtils.cpp',
'source/core/OpCommonUtils.hpp',
'source/core/Pipeline.cpp',
'source/core/Pipeline.hpp',
'source/core/RuntimeFactory.cpp',
'source/core/RuntimeFactory.hpp',
'source/core/Schedule.cpp',
'source/core/Schedule.hpp',
'source/core/Session.cpp',
'source/core/Session.hpp',
'source/core/SimdHeader.h',
'source/core/Tensor.cpp',
'source/core/TensorUtils.cpp',
'source/core/TensorUtils.hpp',
'source/core/WinogradInt8Attr.hpp',
'source/core/WorkerThread.cpp',
'source/core/WorkerThread.hpp',
'source/core/WrapExecution.cpp',
'source/core/WrapExecution.hpp',
'source/cv/ImageProcess.cpp',
'source/cv/ImageProcessUtils.cpp',
'source/cv/ImageProcessUtils.hpp',
'source/cv/Matrix_CV.cpp',
'source/cv/SkNx.h',
'source/cv/SkNx_neon.h',
'source/math/Matrix.cpp',
'source/math/Matrix.hpp',
'source/math/Vec.hpp',
'source/math/WingoradGenerater.cpp',
'source/math/WingoradGenerater.hpp',
'source/geometry/ConvertUtils.cpp',
'source/geometry/ConvertUtils.hpp',
'source/geometry/GeometryBatchMatMul.cpp',
'source/geometry/GeometryBinary.cpp',
'source/geometry/GeometryBroadcastTo.cpp',
'source/geometry/GeometryComputer.cpp',
'source/geometry/GeometryComputer.hpp',
'source/geometry/GeometryComputerUtils.cpp',
'source/geometry/GeometryComputerUtils.hpp',
'source/geometry/GeometryConcat.cpp',
'source/geometry/GeometryConv2D.cpp',
'source/geometry/GeometryConv2DBackPropFilter.cpp',
'source/geometry/GeometryConv3D.cpp',
'source/geometry/GeometryConvUtils.cpp',
'source/geometry/GeometryConvUtils.hpp',
'source/geometry/GeometryConvert.cpp',
'source/geometry/GeometryCosineSimilarity.cpp',
'source/geometry/GeometryCrop.cpp',
'source/geometry/GeometryCumSum.cpp',
'source/geometry/GeometryDepthToSpace.cpp',
'source/geometry/GeometryDet.cpp',
'source/geometry/GeometryDilation2D.cpp',
'source/geometry/GeometryELU.cpp',
'source/geometry/GeometryFill.cpp',
'source/geometry/GeometryGather.cpp',
'source/geometry/GeometryImageOp.cpp',
'source/geometry/GeometryInnerProduct.cpp',
'source/geometry/GeometryLRN.cpp',
'source/geometry/GeometryLSTM.cpp',
'source/geometry/GeometryLayernorm.cpp',
'source/geometry/GeometryOPRegister.cpp',
'source/geometry/GeometryPermute.cpp',
'source/geometry/GeometryPoolGrad.cpp',
'source/geometry/GeometryPooling3D.cpp',
'source/geometry/GeometryReduce.cpp',
'source/geometry/GeometryReshape.cpp',
'source/geometry/GeometryReverseSequence.cpp',
'source/geometry/GeometryScatter.cpp',
'source/geometry/GeometrySelect.cpp',
'source/geometry/GeometryShape.cpp',
'source/geometry/GeometrySlice.cpp',
'source/geometry/GeometrySpaceToBatchND.cpp',
'source/geometry/GeometrySpatialProduct.cpp',
'source/geometry/GeometryStridedSlice.cpp',
'source/geometry/GeometryTensorArray.cpp',
'source/geometry/GeometryThreshold.cpp',
'source/geometry/GeometryTile.cpp',
'source/geometry/GeometryTopK.cpp',
'source/geometry/GeometryUnary.cpp',
'source/shape/ShapeArgMax.cpp',
'source/shape/ShapeAttention.cpp',
'source/shape/ShapeBatchToSpaceND.cpp',
'source/shape/ShapeBinaryOp.cpp',
'source/shape/ShapeBroadcastTo.cpp',
'source/shape/ShapeCast.cpp',
'source/shape/ShapeConcat.cpp',
'source/shape/ShapeConvTranspose3D.cpp',
'source/shape/ShapeConvolution.cpp',
'source/shape/ShapeConvolution3D.cpp',
'source/shape/ShapeCosineSimilarity.cpp',
'source/shape/ShapeCrop.cpp',
'source/shape/ShapeCropAndResize.cpp',
'source/shape/ShapeDeconvolution.cpp',
'source/shape/ShapeDepthToSpace.cpp',
'source/shape/ShapeDequantize.cpp',
'source/shape/ShapeDet.cpp',
'source/shape/ShapeDetectionOutput.cpp',
'source/shape/ShapeDetectionPostProcess.cpp',
'source/shape/ShapeDynamicQuant.cpp',
'source/shape/ShapeExpandDims.cpp',
'source/shape/ShapeFill.cpp',
'source/shape/ShapeGatherND.cpp',
'source/shape/ShapeGatherV2.cpp',
'source/shape/ShapeGridSample.cpp',
'source/shape/ShapeHistogram.cpp',
'source/shape/ShapeInnerProduct.cpp',
'source/shape/ShapeInterp.cpp',
'source/shape/ShapeLSTM.cpp',
'source/shape/ShapeLinSpace.cpp',
'source/shape/ShapeMatMul.cpp',
'source/shape/ShapeMoments.cpp',
'source/shape/ShapeNonMaxSuppressionV2.cpp',
'source/shape/ShapeOneHot.cpp',
'source/shape/ShapePack.cpp',
'source/shape/ShapePadding.cpp',
'source/shape/ShapePermute.cpp',
'source/shape/ShapePlugin.cpp',
'source/shape/ShapePool.cpp',
'source/shape/ShapePool3D.cpp',
'source/shape/ShapePriorbox.cpp',
'source/shape/ShapeProposal.cpp',
'source/shape/ShapeQuantizedAvgPool.cpp',
'source/shape/ShapeQuantizedMaxPool.cpp',
'source/shape/ShapeRNNSequenceGRU.cpp',
'source/shape/ShapeROIAlign.cpp',
'source/shape/ShapeROIPooling.cpp',
'source/shape/ShapeRandomUniform.cpp',
'source/shape/ShapeRange.cpp',
'source/shape/ShapeReduction.cpp',
'source/shape/ShapeRegister.cpp',
'source/shape/ShapeReshape.cpp',
'source/shape/ShapeResize.cpp',
'source/shape/ShapeScatterNd.cpp',
'source/shape/ShapeSegmentMean.cpp',
'source/shape/ShapeSelect.cpp',
'source/shape/ShapeSetDiff1D.cpp',
'source/shape/ShapeShape.cpp',
'source/shape/ShapeSize.cpp',
'source/shape/ShapeSlice.cpp',
'source/shape/ShapeSliceTf.cpp',
'source/shape/ShapeSpaceToBatchND.cpp',
'source/shape/ShapeSpaceToDepth.cpp',
'source/shape/ShapeSplitGelu.cpp',
'source/shape/ShapeSqueeze.cpp',
'source/shape/ShapeStft.cpp',
'source/shape/ShapeStridedSlice.cpp',
'source/shape/ShapeSvd.cpp',
'source/shape/ShapeTensorArray.cpp',
'source/shape/ShapeTensorConvert.cpp',
'source/shape/ShapeTile.cpp',
'source/shape/ShapeTopKV2.cpp',
'source/shape/ShapeTranspose.cpp',
'source/shape/ShapeUnique.cpp',
'source/shape/ShapeUnpack.cpp',
'source/shape/ShapeUnravelIndex.cpp',
'source/shape/ShapeWhere.cpp',
'source/shape/SizeComputer.cpp',
'source/shape/SizeComputer.hpp',
'source/shape/render/ShapeRasterAndInterpolate.cpp',
'source/utils/InitNet.cpp',
'source/utils/InitNet.hpp',
'source/utils/JNIHelper.cpp',
'source/utils/JNIHelper.hpp',
'source/backend/cpu/BinaryUtils.hpp',
'source/backend/cpu/CPUArgMax.cpp',
'source/backend/cpu/CPUArgMax.hpp',
'source/backend/cpu/CPUAttention.cpp',
'source/backend/cpu/CPUAttention.hpp',
'source/backend/cpu/CPUBackend.cpp',
'source/backend/cpu/CPUBackend.hpp',
'source/backend/cpu/CPUBinary.cpp',
'source/backend/cpu/CPUBinary.hpp',
'source/backend/cpu/CPUBinaryInt8.cpp',
'source/backend/cpu/CPUBinaryInt8.hpp',
'source/backend/cpu/CPUCast.cpp',
'source/backend/cpu/CPUCast.hpp',
'source/backend/cpu/CPUConvolution.cpp',
'source/backend/cpu/CPUConvolution.hpp',
'source/backend/cpu/CPUConvolutionDepthwise.cpp',
'source/backend/cpu/CPUConvolutionDepthwise.hpp',
'source/backend/cpu/CPUCropAndResize.cpp',
'source/backend/cpu/CPUCropAndResize.hpp',
'source/backend/cpu/CPUDeconvolution.cpp',
'source/backend/cpu/CPUDeconvolution.hpp',
'source/backend/cpu/CPUDeconvolutionDepthwise.cpp',
'source/backend/cpu/CPUDeconvolutionDepthwise.hpp',
'source/backend/cpu/CPUDepthwiseConvInt8.cpp',
'source/backend/cpu/CPUDepthwiseConvInt8.hpp',
'source/backend/cpu/CPUDequantize.cpp',
'source/backend/cpu/CPUDequantize.hpp',
'source/backend/cpu/CPUDet.cpp',
'source/backend/cpu/CPUDet.hpp',
'source/backend/cpu/CPUDetectionOutput.cpp',
'source/backend/cpu/CPUDetectionOutput.hpp',
'source/backend/cpu/CPUDetectionPostProcess.cpp',
'source/backend/cpu/CPUDetectionPostProcess.hpp',
'source/backend/cpu/CPUDynamicQuant.cpp',
'source/backend/cpu/CPUDynamicQuant.hpp',
'source/backend/cpu/CPUEltwise.cpp',
'source/backend/cpu/CPUEltwise.hpp',
'source/backend/cpu/CPUEltwiseInt8.cpp',
'source/backend/cpu/CPUEltwiseInt8.hpp',
'source/backend/cpu/CPUExternalConst.cpp',
'source/backend/cpu/CPUFixedPoint.hpp',
'source/backend/cpu/CPUFloatToInt8.cpp',
'source/backend/cpu/CPUFloatToInt8.hpp',
'source/backend/cpu/CPUGridSample.cpp',
'source/backend/cpu/CPUGridSample.hpp',
'source/backend/cpu/CPUHistogram.cpp',
'source/backend/cpu/CPUHistogram.hpp',
'source/backend/cpu/CPUImageProcess.cpp',
'source/backend/cpu/CPUImageProcess.hpp',
'source/backend/cpu/CPUInstanceNorm.cpp',
'source/backend/cpu/CPUInstanceNorm.hpp',
'source/backend/cpu/CPUInt8ToFloat.cpp',
'source/backend/cpu/CPUInt8ToFloat.hpp',
'source/backend/cpu/CPUInterp.cpp',
'source/backend/cpu/CPUInterp.hpp',
'source/backend/cpu/CPUInterp3D.cpp',
'source/backend/cpu/CPUInterp3D.hpp',
'source/backend/cpu/CPUKVCacheManager.cpp',
'source/backend/cpu/CPUKVCacheManager.hpp',
'source/backend/cpu/CPULayerNorm.cpp',
'source/backend/cpu/CPULayerNorm.hpp',
'source/backend/cpu/CPULinSpace.cpp',
'source/backend/cpu/CPULinSpace.hpp',
'source/backend/cpu/CPULinearAttention.cpp',
'source/backend/cpu/CPULinearAttention.hpp',
'source/backend/cpu/CPUMatMul.cpp',
'source/backend/cpu/CPUMatMul.hpp',
'source/backend/cpu/CPUMatrixBandPart.cpp',
'source/backend/cpu/CPUMatrixBandPart.hpp',
'source/backend/cpu/CPUMoments.cpp',
'source/backend/cpu/CPUMoments.hpp',
'source/backend/cpu/CPUNonMaxSuppressionV2.cpp',
'source/backend/cpu/CPUNonMaxSuppressionV2.hpp',
'source/backend/cpu/CPUOPRegister.cpp',
'source/backend/cpu/CPUOneHot.cpp',
'source/backend/cpu/CPUOneHot.hpp',
'source/backend/cpu/CPUPlugin.cpp',
'source/backend/cpu/CPUPool.cpp',
'source/backend/cpu/CPUPool.hpp',
'source/backend/cpu/CPUPoolInt8.cpp',
'source/backend/cpu/CPUPoolInt8.hpp',
'source/backend/cpu/CPUProposal.cpp',
'source/backend/cpu/CPUProposal.hpp',
'source/backend/cpu/CPUQuanConvolutionDepthwise.cpp',
'source/backend/cpu/CPUQuanConvolutionDepthwise.hpp',
'source/backend/cpu/CPUQuantizationUtils.hpp',
'source/backend/cpu/CPUQuantizedAdd.cpp',
'source/backend/cpu/CPUQuantizedAdd.hpp',
'source/backend/cpu/CPUQuantizedAvgPool.cpp',
'source/backend/cpu/CPUQuantizedAvgPool.hpp',
'source/backend/cpu/CPUQuantizedLogistic.cpp',
'source/backend/cpu/CPUQuantizedLogistic.hpp',
'source/backend/cpu/CPUQuantizedMaxPool.cpp',
'source/backend/cpu/CPUQuantizedMaxPool.hpp',
'source/backend/cpu/CPUQuantizedSoftmax.cpp',
'source/backend/cpu/CPUQuantizedSoftmax.hpp',
'source/backend/cpu/CPURNNSequenceGRU.cpp',
'source/backend/cpu/CPURNNSequenceGRU.hpp',
'source/backend/cpu/CPUROIAlign.cpp',
'source/backend/cpu/CPUROIAlign.hpp',
'source/backend/cpu/CPUROIPooling.cpp',
'source/backend/cpu/CPUROIPooling.hpp',
'source/backend/cpu/CPURandomUniform.cpp',
'source/backend/cpu/CPURandomUniform.hpp',
'source/backend/cpu/CPURange.cpp',
'source/backend/cpu/CPURange.hpp',
'source/backend/cpu/CPURaster.cpp',
'source/backend/cpu/CPURaster.hpp',
'source/backend/cpu/CPUReduction.cpp',
'source/backend/cpu/CPUReduction.hpp',
'source/backend/cpu/CPURelu.cpp',
'source/backend/cpu/CPURelu.hpp',
'source/backend/cpu/CPUResize.cpp',
'source/backend/cpu/CPUResize.hpp',
'source/backend/cpu/CPUResizeCache.cpp',
'source/backend/cpu/CPUResizeCache.hpp',
'source/backend/cpu/CPURuntime.cpp',
'source/backend/cpu/CPURuntime.hpp',
'source/backend/cpu/CPUScale.cpp',
'source/backend/cpu/CPUScale.hpp',
'source/backend/cpu/CPUScaleInt8.cpp',
'source/backend/cpu/CPUScaleInt8.hpp',
'source/backend/cpu/CPUSegmentMean.cpp',
'source/backend/cpu/CPUSelect.cpp',
'source/backend/cpu/CPUSelect.hpp',
'source/backend/cpu/CPUSetDiff1D.cpp',
'source/backend/cpu/CPUSetDiff1D.hpp',
'source/backend/cpu/CPUSoftmax.cpp',
'source/backend/cpu/CPUSoftmax.hpp',
'source/backend/cpu/CPUStft.cpp',
'source/backend/cpu/CPUStft.hpp',
'source/backend/cpu/CPUSvd.cpp',
'source/backend/cpu/CPUSvd.hpp',
'source/backend/cpu/CPUTFQuantizedConv2D.cpp',
'source/backend/cpu/CPUTFQuantizedConv2D.hpp',
'source/backend/cpu/CPUTensorConvert.cpp',
'source/backend/cpu/CPUTensorConvert.hpp',
'source/backend/cpu/CPUTopKV2.cpp',
'source/backend/cpu/CPUTopKV2.hpp',
'source/backend/cpu/CPUUnary.cpp',
'source/backend/cpu/CPUUnary.hpp',
'source/backend/cpu/CPUUnique.cpp',
'source/backend/cpu/CPUUnique.hpp',
'source/backend/cpu/CPUUnravelIndex.cpp',
'source/backend/cpu/CPUUnravelIndex.hpp',
'source/backend/cpu/CPUWhere.cpp',
'source/backend/cpu/CPUWhere.hpp',
'source/backend/cpu/GridSampler.hpp',
'source/backend/cpu/OneDNNConvInt8.cpp',
'source/backend/cpu/OneDNNConvInt8.hpp',
'source/backend/cpu/OneDNNConvolution.cpp',
'source/backend/cpu/OneDNNConvolution.hpp',
'source/backend/cpu/ThreadPool.cpp',
'source/backend/cpu/ThreadPool.hpp',
'source/backend/cpu/UnaryUtils.hpp',
'source/backend/cpu/compute/CommonOptFunction.cpp',
'source/backend/cpu/compute/CommonOptFunction.h',
'source/backend/cpu/compute/ConvInt8TiledExecutor.cpp',
'source/backend/cpu/compute/ConvInt8TiledExecutor.hpp',
'source/backend/cpu/compute/ConvInt8Winograd.cpp',
'source/backend/cpu/compute/ConvInt8Winograd.hpp',
'source/backend/cpu/compute/ConvOpt.cpp',
'source/backend/cpu/compute/ConvOpt.h',
'source/backend/cpu/compute/Convolution1x1Strassen.cpp',
'source/backend/cpu/compute/Convolution1x1Strassen.hpp',
'source/backend/cpu/compute/ConvolutionFloatFactory.cpp',
'source/backend/cpu/compute/ConvolutionFloatFactory.h',
'source/backend/cpu/compute/ConvolutionGroup.cpp',
'source/backend/cpu/compute/ConvolutionGroup.hpp',
'source/backend/cpu/compute/ConvolutionIntFactory.cpp',
'source/backend/cpu/compute/ConvolutionIntFactory.hpp',
'source/backend/cpu/compute/ConvolutionPackFreeWinograd.cpp',
'source/backend/cpu/compute/ConvolutionPackFreeWinograd.hpp',
'source/backend/cpu/compute/ConvolutionPackWinograd.cpp',
'source/backend/cpu/compute/ConvolutionPackWinograd.hpp',
'source/backend/cpu/compute/ConvolutionTiledExecutor.cpp',
'source/backend/cpu/compute/ConvolutionTiledExecutor.hpp',
'source/backend/cpu/compute/ConvolutionWinogradBridge.cpp',
'source/backend/cpu/compute/ConvolutionWinogradBridge.hpp',
'source/backend/cpu/compute/ConvolutionWinogradImpl.cpp',
'source/backend/cpu/compute/ConvolutionWinogradImpl.hpp',
'source/backend/cpu/compute/DenseConvolutionTiledExecutor.cpp',
'source/backend/cpu/compute/DenseConvolutionTiledExecutor.hpp',
'source/backend/cpu/compute/IdstConvolutionInt8.cpp',
'source/backend/cpu/compute/IdstConvolutionInt8.hpp',
'source/backend/cpu/compute/ImageProcessFunction.cpp',
'source/backend/cpu/compute/ImageProcessFunction.hpp',
'source/backend/cpu/compute/Int8FunctionsOpt.cpp',
'source/backend/cpu/compute/Int8FunctionsOpt.h',
'source/backend/cpu/compute/OptimizedComputer.cpp',
'source/backend/cpu/compute/OptimizedComputer.hpp',
'source/backend/cpu/compute/ResizeFunction.cpp',
'source/backend/cpu/compute/ResizeFunction.h',
'source/backend/cpu/compute/SparseConvInt8TiledExecutor.cpp',
'source/backend/cpu/compute/SparseConvInt8TiledExecutor.hpp',
'source/backend/cpu/compute/SparseConvolutionTiledExecutor.cpp',
'source/backend/cpu/compute/SparseConvolutionTiledExecutor.hpp',
'source/backend/cpu/compute/StrassenMatmulComputor.cpp',
'source/backend/cpu/compute/StrassenMatmulComputor.hpp',
'source/backend/cpu/compute/TurboQuant.hpp',
'source/backend/cpu/compute/WinogradOptFunction.cpp',
'source/backend/cpu/compute/WinogradOptFunction.hpp',
'source/backend/cpu/arm/arm64/MNNAddC4WithStride.S',
'source/backend/cpu/arm/arm64/MNNAvgPoolInt8.S',
'source/backend/cpu/arm/arm64/MNNAxByClampBroadcastC4.S',
'source/backend/cpu/arm/arm64/MNNBGRAToBGR.S',
'source/backend/cpu/arm/arm64/MNNBGRAToGRAY.S',
'source/backend/cpu/arm/arm64/MNNBGRToBGR555.S',
'source/backend/cpu/arm/arm64/MNNBGRToBGR565.S',
'source/backend/cpu/arm/arm64/MNNBGRToGRAY.S',
'source/backend/cpu/arm/arm64/MNNBilinearLineC8.S',
'source/backend/cpu/arm/arm64/MNNBilinearSampleC8.S',
'source/backend/cpu/arm/arm64/MNNBinaryAddInt8.S',
'source/backend/cpu/arm/arm64/MNNBinaryMaxInt8.S',
'source/backend/cpu/arm/arm64/MNNBinaryMinInt8.S',
'source/backend/cpu/arm/arm64/MNNBinaryMulInt8.S',
'source/backend/cpu/arm/arm64/MNNBinarySqdInt8.S',
'source/backend/cpu/arm/arm64/MNNBinarySubInt8.S',
'source/backend/cpu/arm/arm64/MNNBlitC1ToFloatRGBA.S',
'source/backend/cpu/arm/arm64/MNNBlitC3ToFloatRGBA.S',
'source/backend/cpu/arm/arm64/MNNC3ToC4Fast.S',
'source/backend/cpu/arm/arm64/MNNC3ToXYZFast.S',
'source/backend/cpu/arm/arm64/MNNC3ToYUVFast.S',
'source/backend/cpu/arm/arm64/MNNConvDwF23MulTransUnit.S',
'source/backend/cpu/arm/arm64/MNNConvDwF23SourceTransUnit.S',
'source/backend/cpu/arm/arm64/MNNConvRunForLineDepthWiseInt8.S',
'source/backend/cpu/arm/arm64/MNNConvRunForLineDepthWiseUint8.S',
'source/backend/cpu/arm/arm64/MNNConvRunForLineDepthwise.S',
'source/backend/cpu/arm/arm64/MNNConvRunForUnitDepthWiseUint8.S',
'source/backend/cpu/arm/arm64/MNNCopyC4WithStride.S',
'source/backend/cpu/arm/arm64/MNNCubicLineC16.S',
'source/backend/cpu/arm/arm64/MNNCubicSampleC16.S',
'source/backend/cpu/arm/arm64/MNNDeconvRunForUnitDepthWise.S',
'source/backend/cpu/arm/arm64/MNNDepthwiseConvFastKernel.S',
'source/backend/cpu/arm/arm64/MNNFloat2Int8.S',
'source/backend/cpu/arm/arm64/MNNGRAYToC3Fast.S',
'source/backend/cpu/arm/arm64/MNNGRAYToC4Fast.S',
'source/backend/cpu/arm/arm64/MNNGelu.S',
'source/backend/cpu/arm/arm64/MNNGemmInt8AddBiasScale_16x4_Unit.S',
'source/backend/cpu/arm/arm64/MNNGemmInt8AddBiasScale_16x4_Unit_FAST.S',
'source/backend/cpu/arm/arm64/MNNGemmInt8AddBiasScale_ARMV82_Unit.S',
'source/backend/cpu/arm/arm64/MNNGemmInt8AddBiasScale_ARMV86_Unit.S',
'source/backend/cpu/arm/arm64/MNNGemmint8to32_8x4_Unit.S',
'source/backend/cpu/arm/arm64/MNNInt8ScaleToFloat.S',
'source/backend/cpu/arm/arm64/MNNLineDepthWiseInt8AddBiasScaleUnit.S',
'source/backend/cpu/arm/arm64/MNNLineDepthWiseInt8AddBiasScale_ARMV82_Unit3X3.S',
'source/backend/cpu/arm/arm64/MNNLoadU8AndSum.S',
'source/backend/cpu/arm/arm64/MNNLocalMinMaxFP32_Pack4.S',
'source/backend/cpu/arm/arm64/MNNLocalMinMaxFP32_Pack8.S',
'source/backend/cpu/arm/arm64/MNNMatrixAdd.S',
'source/backend/cpu/arm/arm64/MNNMatrixMax.S',
'source/backend/cpu/arm/arm64/MNNMatrixProd.S',
'source/backend/cpu/arm/arm64/MNNMatrixSub.S',
'source/backend/cpu/arm/arm64/MNNMaxFloat.S',
'source/backend/cpu/arm/arm64/MNNMaxPoolInt8.S',
'source/backend/cpu/arm/arm64/MNNMinFloat.S',
'source/backend/cpu/arm/arm64/MNNNV21ToBGRAUnit.S',
'source/backend/cpu/arm/arm64/MNNNV21ToBGRUnit.S',
'source/backend/cpu/arm/arm64/MNNNV21ToRGBAUnit.S',
'source/backend/cpu/arm/arm64/MNNNV21ToRGBUnit.S',
'source/backend/cpu/arm/arm64/MNNPackC2.S',
'source/backend/cpu/arm/arm64/MNNPackC4.S',
'source/backend/cpu/arm/arm64/MNNPackC4ForMatMul_A.S',
'source/backend/cpu/arm/arm64/MNNPackC4Int8ForMatMulA_ARM82.S',
'source/backend/cpu/arm/arm64/MNNPackC4Int8ForMatMulA_ARM86.S',
'source/backend/cpu/arm/arm64/MNNPackC4Int8ForMatMulA_SME2.S',
'source/backend/cpu/arm/arm64/MNNPackC4Int8ForMatMulA_SME2_Hp64.S',
'source/backend/cpu/arm/arm64/MNNPackC8.S',
'source/backend/cpu/arm/arm64/MNNPackedMatMul.S',
'source/backend/cpu/arm/arm64/MNNPackedMatMulRemain.S',
'source/backend/cpu/arm/arm64/MNNPackedSparseMatMulEpx1.S',
'source/backend/cpu/arm/arm64/MNNPackedSparseMatMulEpx4.S',
'source/backend/cpu/arm/arm64/MNNPackedSparseQuantMatMulEpx1.S',
'source/backend/cpu/arm/arm64/MNNPackedSparseQuantMatMulEpx4.S',
'source/backend/cpu/arm/arm64/MNNPermuteSumWeightInt4Arm82.S',
'source/backend/cpu/arm/arm64/MNNPermuteSumWeightInt4Arm86.S',
'source/backend/cpu/arm/arm64/MNNPowC8.S',
'source/backend/cpu/arm/arm64/MNNQuanToDestUint8.S',
'source/backend/cpu/arm/arm64/MNNRGBAToBGRAFast.S',
'source/backend/cpu/arm/arm64/MNNRGBAToBGRFast.S',
'source/backend/cpu/arm/arm64/MNNRGBAToGRAYFast.S',
'source/backend/cpu/arm/arm64/MNNRGBToBGR.S',
'source/backend/cpu/arm/arm64/MNNRGBToBGR555.S',
'source/backend/cpu/arm/arm64/MNNRGBToBGR565.S',
'source/backend/cpu/arm/arm64/MNNRGBToGRAYFast.S',
'source/backend/cpu/arm/arm64/MNNRankOneUpdate.S',
'source/backend/cpu/arm/arm64/MNNReluInt8.S',
'source/backend/cpu/arm/arm64/MNNReluWithSlopeChannel.S',
'source/backend/cpu/arm/arm64/MNNReluWithSlopeChannelInt8.S',
'source/backend/cpu/arm/arm64/MNNSamplerC1BilinearOpt.S',
'source/backend/cpu/arm/arm64/MNNSamplerC1NearestOpt.S',
'source/backend/cpu/arm/arm64/MNNSamplerC3BilinearOpt.S',
'source/backend/cpu/arm/arm64/MNNSamplerC4BilinearOpt.S',
'source/backend/cpu/arm/arm64/MNNSamplerC4NearestOpt.S',
'source/backend/cpu/arm/arm64/MNNScaleAddInt8.S',
'source/backend/cpu/arm/arm64/MNNScaleAndAddBias.S',
'source/backend/cpu/arm/arm64/MNNScaleAndAddBiasInt8.S',
'source/backend/cpu/arm/arm64/MNNStrassenMergeCFunction.S',
'source/backend/cpu/arm/arm64/MNNSumWeightInt8Arm82.S',
'source/backend/cpu/arm/arm64/MNNSumWeightInt8Arm86.S',
'source/backend/cpu/arm/arm64/MNNTranspose16Bit8x8.S',
'source/backend/cpu/arm/arm64/MNNTranspose32Bit4x4.S',
'source/backend/cpu/arm/arm64/MNNUInt8ToInt16WithOffsetC4Common.S',
'source/backend/cpu/arm/arm64/MNNUInt8ToInt16WithOffsetC4Fast.S',
'source/backend/cpu/arm/arm64/MNNUnPackC4.S',
'source/backend/cpu/arm/arm64/MNNVectorTop1Float.S',
'source/backend/cpu/arm/arm64/MNNVectorTop1Int32.S',
'source/backend/cpu/arm/arm64/low_memory/MNNAbsMaxFP32_Pack4.S',
'source/backend/cpu/arm/arm64/low_memory/MNNAbsMaxFP32_Pack8.S',
'source/backend/cpu/arm/arm64/low_memory/MNNDynamicQuantFP32_Pack4.S',
'source/backend/cpu/arm/arm64/low_memory/MNNDynamicQuantFP32_Pack8.S',
'source/backend/cpu/arm/arm64/low_memory/MNNDynamicUpdateConvBiasScale.S',
'source/backend/cpu/arm/arm64/low_memory/MNNGemmInt8AddBiasScale_16x4_w4_Unit.S',
'source/backend/cpu/arm/arm64/low_memory/MNNGemmInt8AddBiasScale_ARMV82_w4_Unit.S',
'source/backend/cpu/arm/arm64/low_memory/MNNGemmInt8AddBiasScale_ARMV86_w4_Unit.S',
'source/backend/cpu/arm/arm64/low_memory/MNNGeneralIm2col_Fp16Sme2.S',
'source/backend/cpu/arm/arm64/low_memory/MNNGeneralIm2col_Fp32Arm82.S',
'source/backend/cpu/arm/arm64/low_memory/MNNGeneralIm2col_Fp32Arm86.S',
'source/backend/cpu/arm/arm64/low_memory/MNNGeneralIm2col_Fp32Sme2.S',
'source/backend/cpu/arm/arm64/low_memory/MNNQuantScaleFP32.S',
'source/backend/cpu/arm/CommonOptFunctionNeon.cpp',
'source/backend/metal/AllShader.cpp',
'source/backend/metal/AllShader.hpp',
'source/backend/metal/ConvSimdGroupShader.hpp',
'source/backend/metal/LayerNormSimdGroupShader.hpp',
'source/backend/metal/MNNMetalContext.h',
'source/backend/metal/MNNMetalContext.mm',
'source/backend/metal/MetalArgMax.mm',
'source/backend/metal/MetalAttention.hpp',
'source/backend/metal/MetalAttention.mm',
'source/backend/metal/MetalAttentionShader.hpp',
'source/backend/metal/MetalBackend.hpp',
'source/backend/metal/MetalBackend.mm',
'source/backend/metal/MetalBinary.hpp',
'source/backend/metal/MetalBinary.mm',
'source/backend/metal/MetalCache_generated.h',
'source/backend/metal/MetalCast.hpp',
'source/backend/metal/MetalCast.mm',
'source/backend/metal/MetalConvolution.hpp',
'source/backend/metal/MetalConvolution.mm',
'source/backend/metal/MetalConvolution1x1.hpp',
'source/backend/metal/MetalConvolution1x1.mm',
'source/backend/metal/MetalConvolutionCommon.hpp',
'source/backend/metal/MetalConvolutionCommon.mm',
'source/backend/metal/MetalConvolutionDepthwise.hpp',
'source/backend/metal/MetalConvolutionDepthwise.mm',
'source/backend/metal/MetalConvolutionWinograd.hpp',
'source/backend/metal/MetalConvolutionWinograd.mm',
'source/backend/metal/MetalDeconvolution.hpp',
'source/backend/metal/MetalDeconvolution.mm',
'source/backend/metal/MetalDefine.h',
'source/backend/metal/MetalEltwise.hpp',
'source/backend/metal/MetalEltwise.mm',
'source/backend/metal/MetalExecution.hpp',
'source/backend/metal/MetalExecution.mm',
'source/backend/metal/MetalFuse.hpp',
'source/backend/metal/MetalFuse.mm',
'source/backend/metal/MetalGridSample.hpp',
'source/backend/metal/MetalGridSample.mm',
'source/backend/metal/MetalInterp.hpp',
'source/backend/metal/MetalInterp.mm',
'source/backend/metal/MetalKVCacheManager.hpp',
'source/backend/metal/MetalKVCacheManager.mm',
'source/backend/metal/MetalLayerNorm.hpp',
'source/backend/metal/MetalLayerNorm.mm',
'source/backend/metal/MetalLinearAttention.hpp',
'source/backend/metal/MetalLinearAttention.mm',
'source/backend/metal/MetalLinearAttentionShader.hpp',
'source/backend/metal/MetalLoop.mm',
'source/backend/metal/MetalMatMul.hpp',
'source/backend/metal/MetalMatMul.mm',
'source/backend/metal/MetalOPRegister.mm',
'source/backend/metal/MetalPReLU.hpp',
'source/backend/metal/MetalPReLU.mm',
'source/backend/metal/MetalPooling.hpp',
'source/backend/metal/MetalPooling.mm',
'source/backend/metal/MetalROIPooling.hpp',
'source/backend/metal/MetalROIPooling.mm',
'source/backend/metal/MetalRaster.hpp',
'source/backend/metal/MetalRaster.mm',
'source/backend/metal/MetalReLU6.hpp',
'source/backend/metal/MetalReLU6.mm',
'source/backend/metal/MetalReduction.hpp',
'source/backend/metal/MetalReduction.mm',
'source/backend/metal/MetalScale.hpp',
'source/backend/metal/MetalScale.mm',
'source/backend/metal/MetalSoftmax.hpp',
'source/backend/metal/MetalSoftmax.mm',
'source/backend/metal/MetalTopKV2.mm',
'source/backend/metal/MetalUnary.hpp',
'source/backend/metal/MetalUnary.mm',
'source/backend/metal/ShaderMap.cpp',
'source/backend/metal/ShaderMap.hpp',
'express/CMakeLists.txt',
'express/Executor.cpp',
'express/ExecutorScope.cpp',
'express/Expr.cpp',
'express/MathOp.cpp',
'express/NeuralNetWorkOp.cpp',
'express/Optimizer.cpp',
'express/RuntimeAttr.hpp',
'express/Utils.cpp',
'express/Utils.hpp',
'express/module/IfModule.cpp',
'express/module/IfModule.hpp',
'express/module/MoEModule.cpp',
'express/module/MoEModule.hpp',
'express/module/Module.cpp',
'express/module/ModuleInside.hpp',
'express/module/NMSModule.cpp',
'express/module/NMSModule.hpp',
'express/module/PipelineModule.cpp',
'express/module/PipelineModule.hpp',
'express/module/StaticModule.cpp',
'express/module/StaticModule.hpp',
'express/module/WhileModule.cpp',
'express/module/WhileModule.hpp',
'tools/cv/source/imgproc/color.cpp',
'tools/cv/include/cv/imgproc/color.hpp',
'tools/cv/source/imgproc/geometric.cpp',
'tools/cv/include/cv/imgproc/geometric.hpp',
'tools/cv/source/imgproc/draw.cpp',
'tools/cv/include/cv/imgproc/draw.hpp',
'tools/cv/source/imgproc/filter.cpp',
'tools/cv/include/cv/imgproc/filter.hpp',
'tools/cv/source/imgproc/miscellaneous.cpp',
'tools/cv/include/cv/imgproc/miscellaneous.hpp',
'tools/cv/source/imgproc/structural.cpp',
'tools/cv/include/cv/imgproc/structural.hpp',
'tools/cv/source/imgproc/histograms.cpp',
'tools/cv/include/cv/imgproc/histograms.hpp',
'tools/cv/include/cv/calib3d.hpp',
'tools/cv/source/calib3d/calib3d.cpp',
'tools/cv/include/cv/core.hpp',
'tools/cv/source/core/core.cpp',
'transformers/llm/engine/src/diskembedding.cpp',
'transformers/llm/engine/src/diskembedding.hpp',
'transformers/llm/engine/src/embedding.cpp',
'transformers/llm/engine/src/httplib.h',
'transformers/llm/engine/src/kvmeta.hpp',
'transformers/llm/engine/src/llm.cpp',
'transformers/llm/engine/src/llmconfig.cpp',
'transformers/llm/engine/src/llmconfig.hpp',
'transformers/llm/engine/src/omni.cpp',
'transformers/llm/engine/src/omni.hpp',
'transformers/llm/engine/src/prompt_cache_utils.hpp',
'transformers/llm/engine/src/sampler.cpp',
'transformers/llm/engine/src/sampler.hpp',
'transformers/llm/engine/src/speculative_decoding/eagle.cpp',
'transformers/llm/engine/src/speculative_decoding/generate.cpp',
'transformers/llm/engine/src/speculative_decoding/generate.hpp',
'transformers/llm/engine/src/speculative_decoding/lookahead.cpp',
'transformers/llm/engine/src/speculative_decoding/lookahead.hpp',
'transformers/llm/engine/src/speculative_decoding/mtp.cpp',
'transformers/llm/engine/src/speculative_decoding/ngram.hpp',
'transformers/llm/engine/src/speculative_decoding/tokentree.hpp',
'transformers/llm/engine/src/tokenizer/TOKENIZER_ARTICLE.md',
'transformers/llm/engine/src/tokenizer/TOKENIZER_OPT.md',
'transformers/llm/engine/src/tokenizer/jinja.hpp',
'transformers/llm/engine/src/tokenizer/tokenizer.cpp',
'transformers/llm/engine/src/tokenizer/tokenizer.hpp',
'transformers/llm/engine/src/tokenizer/unicode.cpp',
'transformers/llm/engine/src/tokenizer/unicode.hpp',
'transformers/llm/engine/src/tokenizer/unicode_data.cpp',
'transformers/llm/engine/src/tokenizer/unicode_data.hpp',
'transformers/llm/engine/src/ujson.hpp'
]
# =============================================================================
# Public headers
# =============================================================================
s.public_header_files = [
'include/MNN/AutoTime.hpp',
'include/MNN/ErrorCode.hpp',
'include/MNN/HalideRuntime.h',
'include/MNN/ImageProcess.hpp',
'include/MNN/Interpreter.hpp',
'include/MNN/MNNDefine.h',
'include/MNN/MNNForwardType.h',
'include/MNN/MNNSharedContext.h',
'include/MNN/Matrix.h',
'include/MNN/Rect.h',
'include/MNN/Tensor.hpp',
'include/MNN/expr/Executor.hpp',
'include/MNN/expr/ExecutorScope.hpp',
'include/MNN/expr/Expr.hpp',
'include/MNN/expr/ExprCreator.hpp',
'include/MNN/expr/MathOp.hpp',
'include/MNN/expr/Module.hpp',
'include/MNN/expr/NeuralNetWorkOp.hpp',
'include/MNN/expr/Optimizer.hpp',
'include/MNN/expr/Scope.hpp',
'include/MNN/plugin/PluginContext.hpp',
'include/MNN/plugin/PluginKernel.hpp',
'include/MNN/plugin/PluginShapeInference.hpp'
]
# =============================================================================
# Build configuration
# =============================================================================
s.pod_target_xcconfig = {
'HEADER_SEARCH_PATHS' => [
'"$(PODS_TARGET_SRCROOT)/include"',
'"$(PODS_TARGET_SRCROOT)/source"',
'"$(PODS_TARGET_SRCROOT)/express"',
'"$(PODS_TARGET_SRCROOT)/tools"',
'"$(PODS_TARGET_SRCROOT)/schema/current"',
'"$(PODS_TARGET_SRCROOT)/3rd_party"',
'"$(PODS_TARGET_SRCROOT)/3rd_party/flatbuffers/include"',
'"$(PODS_TARGET_SRCROOT)/3rd_party/half"',
'"$(PODS_TARGET_SRCROOT)/source/backend/cpu"',
'"$(PODS_TARGET_SRCROOT)/source/backend/cpu/arm"',
'"$(PODS_TARGET_SRCROOT)/source/backend/arm82"',
'"$(PODS_TARGET_SRCROOT)/source/backend/arm82/compute"',
'"$(PODS_TARGET_SRCROOT)/source/backend/arm82/asm"',
'"$(PODS_TARGET_SRCROOT)/source/backend/metal"',
'"$(PODS_TARGET_SRCROOT)/tools/cv/include"',
'"$(PODS_TARGET_SRCROOT)/transformers/llm/engine/include"',
'"$(PODS_TARGET_SRCROOT)/transformers/llm/engine/src"'
].join(' '),
'GCC_PREPROCESSOR_DEFINITIONS' => [
'$(inherited)',
'MNN_METAL_ENABLED=1',
'ENABLE_ARMV82=1',
'MNN_USE_NEON=1',
'MNN_SUPPORT_TRANSFORMER_FUSE=1',
'MNN_LOW_MEMORY=1',
'MNN_IMGPROC_DRAW=1',
'MNN_REDUCE_SIZE=1'
].join(' '),
'OTHER_CFLAGS' => '-fno-rtti -fno-exceptions -Oz',
'OTHER_CPLUSPLUSFLAGS' => '-std=c++17 -fno-rtti -fno-exceptions -Oz',
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17',
'METAL_LIBRARY_FILE_BASE' => 'mnn',
'ARCHS' => 'arm64',
'VALID_ARCHS' => 'arm64',
# Optimization: remove debug info and strip
'GCC_OPTIMIZATION_LEVEL' => 'z',
'DEBUG_INFORMATION_FORMAT' => 'dwarf',
'STRIP_INSTALLED_PRODUCT' => 'YES',
'STRIP_STYLE' => 'non-global',
'DEAD_CODE_STRIPPING' => 'YES',
'DEPLOYMENT_POSTPROCESSING' => 'YES'
}
s.author = { "MNN" => "MNN@alibaba-inc.com" }
s.platform = :ios
s.ios.deployment_target = '8.0'
s.requires_arc = true
#s.source = { :git => "git@github.com:alibaba/MNN.git", :branch => 'master' }
s.source = {:git => "/Users/zhang/Development/AliNNPrivate/",:branch=> 'head'}
s.frameworks = 'Metal', 'Accelerate', 'CoreML'
s.library = 'c++'
s.source_files = \
'include/MNN/*.{h,hpp}',\
'include/MNN/expr/*.{h,hpp}',\
'schema/current/*.{h}',\
'3rd_party/flatbuffers/include/flatbuffers/*.{h}',\
'source/internal/logging/*.{hpp,cpp}',\
'source/internal/logging/ios/*.{h,c,m,mm,cc,hpp,cpp}',\
'source/internal/logging/aliyun-log-c-sdk/src/*.{h,c,m,mm,cc,hpp,cpp}',\
'source/core/**/*.{h,c,m,mm,cc,hpp,cpp}',\
'source/common/**/*.{h,c,m,mm,cc,hpp,cpp}',\
'source/utils/**/*.{h,c,m,mm,cc,hpp,cpp}',\
'source/geometry/**/*.{h,c,m,mm,cc,hpp,cpp}',\
'source/cv/**/*.{h,c,m,mm,cc,hpp,cpp}',\
'source/math/**/*.{h,c,m,mm,cc,hpp,cpp,metal}',\
'source/shape/*.{h,c,m,mm,cc,hpp,cpp}',\
#'source/backend/arm82/*.{h,c,m,mm,cc,S,hpp,cpp}',\
#'source/backend/arm82/asm/**/*.{h,c,m,mm,cc,S,hpp,cpp}',\
'source/backend/cpu/*.{h,c,m,mm,cc,S,hpp,cpp}',\
'source/backend/cpu/bf16/*.{h,c,m,mm,cc,S,hpp,cpp}',\
'source/backend/cpu/arm/**/*.{h,c,m,mm,cc,S,hpp,cpp}',\
'source/backend/cpu/compute/*.{h,c,m,mm,cc,S,hpp,cpp}',\
'source/backend/metal/*.{h,c,m,mm,cc,hpp,cpp,metal}',\
'source/backend/coreml/backend/*.{h,c,m,mm,cc,hpp,cpp,metal}',\
'source/backend/coreml/execution/*.{h,c,m,mm,cc,hpp,cpp,metal}',\
'source/backend/coreml/mlmodel/src/*.{h,c,m,mm,cc,hpp,cpp,metal}',\
'express/**/*.{hpp,cpp}',\
'tools/cv/include/**/*.{h,c,m,mm,cc,hpp,cpp,metal}',\
'tools/cv/source/imgproc/*.{h,c,m,mm,cc,hpp,cpp,metal}',\
'tools/cv/source/calib3d/*.{h,c,m,mm,cc,hpp,cpp,metal}'
s.header_mappings_dir = 'include'
s.subspec 'cv' do |sp|
sp.source_files = 'tools/cv/include/**/*.hpp'
sp.header_mappings_dir = 'tools/cv/include'
sp.xcconfig = { 'ALWAYS_SEARCH_USER_PATHS' => 'NO' }
# =============================================================================
# ARM82 FP16 - Requires -march=armv8.2-a+fp16 compiler flag
# Total 36 files
# =============================================================================
s.subspec 'ARM82' do |sp|
sp.source_files = [
'source/backend/arm82/Arm82Backend.cpp',
'source/backend/arm82/Arm82Binary.cpp',
'source/backend/arm82/Arm82Functions.cpp',
'source/backend/arm82/Arm82Interp.cpp',
'source/backend/arm82/Arm82OptFunc.cpp',
'source/backend/arm82/Arm82Relu.cpp',
'source/backend/arm82/Arm82Unary.cpp',
'source/backend/arm82/Arm82WinogradOptFunc.cpp',
'source/backend/arm82/asm/arm64/Arm82MNNPackForMatMul_A.S',
'source/backend/arm82/asm/arm64/CountMinMaxValue_FP16.S',
'source/backend/arm82/asm/arm64/MNNConvRunForLineDepthwiseFP16.S',
'source/backend/arm82/asm/arm64/MNNConvWinoSourceTransformUnit6x6FP16.S',
'source/backend/arm82/asm/arm64/MNNDepthwiseConvFastKernelFP16.S',
'source/backend/arm82/asm/arm64/MNNExpFP16.S',
'source/backend/arm82/asm/arm64/MNNGeluFP16.S',
'source/backend/arm82/asm/arm64/MNNLocalMinMaxFP16_Pack4.S',
'source/backend/arm82/asm/arm64/MNNLocalMinMaxFP16_Pack8.S',
'source/backend/arm82/asm/arm64/MNNPackC8FP16.S',
'source/backend/arm82/asm/arm64/MNNPackedMatMulFP16.S',
'source/backend/arm82/asm/arm64/MNNPackedMatMulRemainFP16.S',
'source/backend/arm82/asm/arm64/MNNQuantizeFP16_UNIT4.S',
'source/backend/arm82/asm/arm64/MNNRankOneUpdateFp16.S',
'source/backend/arm82/asm/arm64/MNNUnpackC8FP16.S',
'source/backend/arm82/asm/arm64/low_memory/MNNAbsMaxFP16_Pack4.S',
'source/backend/arm82/asm/arm64/low_memory/MNNAbsMaxFP16_pack8.S',
'source/backend/arm82/asm/arm64/low_memory/MNNDynamicQuanInput_ARM82.S',
'source/backend/arm82/asm/arm64/low_memory/MNNDynamicQuantAndReorder_ARM82.S',
'source/backend/arm82/asm/arm64/low_memory/MNNDynamicQuantFP16_Pack4.S',
'source/backend/arm82/asm/arm64/low_memory/MNNDynamicQuantFP16_Pack8.S',
'source/backend/arm82/asm/arm64/low_memory/MNNGemmInt8AddBiasScale_ARMV82_Unit_FP16.S',
'source/backend/arm82/asm/arm64/low_memory/MNNGemmInt8AddBiasScale_ARMV82_w4_Unit_FP16.S',
'source/backend/arm82/asm/arm64/low_memory/MNNGemmInt8AddBiasScale_ARMV86_Unit_FP16.S',
'source/backend/arm82/asm/arm64/low_memory/MNNGemmInt8AddBiasScale_ARMV86_w4_Unit_FP16.S',
'source/backend/arm82/asm/arm64/low_memory/MNNGeneralIm2col_Arm82.S',
'source/backend/arm82/asm/arm64/low_memory/MNNGeneralIm2col_Arm86.S',
'source/backend/arm82/asm/arm64/low_memory/MNNQuantScaleFP16.S'
]
sp.pod_target_xcconfig = {
'OTHER_CFLAGS' => '-march=armv8.2-a+fp16 -fno-rtti -fno-exceptions',
'OTHER_CPLUSPLUSFLAGS' => '-std=c++17 -march=armv8.2-a+fp16 -fno-rtti -fno-exceptions'
}
sp.xcconfig = {
'OTHER_ASFLAGS' => '-march=armv8.2-a+fp16'
}
end
s.compiler_flags = '-arch arm64 -march=armv8.2-a+simd+fp16'
s.pod_target_xcconfig = {'METAL_LIBRARY_FILE_BASE' => 'mnn', 'HEADER_SEARCH_PATHS' => '"$(PODS_TARGET_SRCROOT)/include" "$(PODS_TARGET_SRCROOT)/3rd_party/flatbuffers/include" "$(PODS_TARGET_SRCROOT)/source" "$(PODS_TARGET_SRCROOT)/3rd_party/half" "$(PODS_TARGET_SRCROOT)/source/backend/coreml/mlmodel/include" "$(PODS_TARGET_SRCROOT)/tools/cv/include"', 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) MNN_CODEGEN_REGISTER=1 MNN_SUPPORT_TFLITE_QUAN=1 MNN_METAL_ENABLED=1 MNN_SUPPORT_BF16=1 MNN_COREML_ENABLED=1 USE_LZ4_FLAG=1 MNN_INTERNAL_ENABLED=1 MNN_USE_SPARSE_COMPUTE=1'}
s.user_target_xcconfig = { 'OTHER_LDFLAGS' => '-force_load $(BUILD_DIR)/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME)/MNN/libMNN.a', 'HEADER_SEARCH_PATHS' => '"$(PODS_TARGET_SRCROOT)/include"' }
s.default_subspecs = ['ARM82']
end
+9 -2
View File
@@ -73,8 +73,15 @@ function (download_kleidiai_and_collect_sources)
CACHE PATH "Path to KleidiAI source (downloaded or provided)" FORCE)
endif()
list(APPEND MNN_SOURCES_KLEIDIAI ${CMAKE_CURRENT_LIST_DIR}/mnn_kleidiai.cpp)
list(APPEND MNN_SOURCES_KLEIDIAI ${CMAKE_CURRENT_LIST_DIR}/mnn_kleidiai_util.cpp)
set(MNN_KLEIDIAI_DIR "${CMAKE_SOURCE_DIR}/source/backend/cpu/kleidiai")
list(APPEND MNN_SOURCES_KLEIDIAI ${MNN_KLEIDIAI_DIR}/mnn_kleidiai.cpp)
list(APPEND MNN_SOURCES_KLEIDIAI ${MNN_KLEIDIAI_DIR}/mnn_kleidiai_util.cpp)
list(APPEND MNN_SOURCES_KLEIDIAI ${MNN_KLEIDIAI_DIR}/KleidiAIConvolution.cpp)
list(APPEND MNN_SOURCES_KLEIDIAI ${MNN_KLEIDIAI_DIR}/KleidiAIConvolutionDepthwise.cpp)
list(APPEND MNN_SOURCES_KLEIDIAI ${MNN_KLEIDIAI_DIR}/KleidiAIConvInt8.cpp)
list(APPEND MNN_SOURCES_KLEIDIAI ${MNN_KLEIDIAI_DIR}/KleidiAIDenseConvolution.cpp)
include_directories(${MNN_KLEIDIAI_DIR})
include_directories(
${KLEIDIAI_SRC_DIR}/
+425
View File
@@ -0,0 +1,425 @@
# =============================================================================
# generate_podspec.cmake
# 从 CMake target 中自动提取源文件列表,生成 MNN.podspec
#
# 使用方法:
# 在 CMakeLists.txt 末尾(所有 target 定义之后):
# include(cmake/generate_podspec.cmake)
# generate_mnn_podspec_from_targets()
# =============================================================================
cmake_minimum_required(VERSION 3.6)
# =============================================================================
# Configuration
# =============================================================================
# Use MNN_VERSION from CMakeLists.txt as default
if(NOT DEFINED MNN_PODSPEC_VERSION OR MNN_PODSPEC_VERSION STREQUAL "")
set(MNN_PODSPEC_VERSION "${MNN_VERSION}" CACHE STRING "MNN podspec version" FORCE)
endif()
set(MNN_IOS_DEPLOYMENT_TARGET "11.0" CACHE STRING "iOS deployment target")
# =============================================================================
# 辅助函数:获取 target 的所有源文件
# =============================================================================
function(get_target_sources_recursive TARGET OUTPUT_VAR)
set(RESULT "")
# 获取 target 的源文件
get_target_property(SRCS ${TARGET} SOURCES)
if(SRCS)
list(APPEND RESULT ${SRCS})
endif()
# 获取 OBJECT 库的源文件
get_target_property(INTERFACE_SOURCES ${TARGET} INTERFACE_SOURCES)
if(INTERFACE_SOURCES)
list(APPEND RESULT ${INTERFACE_SOURCES})
endif()
set(${OUTPUT_VAR} ${RESULT} PARENT_SCOPE)
endfunction()
# =============================================================================
# Helper: Convert absolute paths to relative paths (filter out directories)
# =============================================================================
function(convert_to_relative_paths SOURCE_LIST ROOT_DIR OUTPUT_VAR)
set(RESULT "")
foreach(SRC ${SOURCE_LIST})
if(IS_ABSOLUTE ${SRC})
# Skip directories
if(IS_DIRECTORY ${SRC})
continue()
endif()
file(RELATIVE_PATH REL_PATH "${ROOT_DIR}" "${SRC}")
list(APPEND RESULT "${REL_PATH}")
else()
# Skip if it looks like a directory (no extension)
get_filename_component(EXT "${SRC}" EXT)
if(NOT EXT STREQUAL "")
list(APPEND RESULT "${SRC}")
endif()
endif()
endforeach()
set(${OUTPUT_VAR} ${RESULT} PARENT_SCOPE)
endfunction()
# =============================================================================
# 辅助函数:按扩展名分类文件
# =============================================================================
function(classify_files FILE_LIST CPP_OUT HEADER_OUT ASM_OUT MM_OUT METAL_OUT OTHER_OUT)
set(CPP_FILES "")
set(HEADER_FILES "")
set(ASM_FILES "")
set(MM_FILES "")
set(METAL_FILES "")
set(OTHER_FILES "")
foreach(FILE ${FILE_LIST})
get_filename_component(EXT "${FILE}" EXT)
string(TOLOWER "${EXT}" EXT_LOWER)
if(EXT_LOWER MATCHES "\\.(cpp|cc|c)$")
list(APPEND CPP_FILES "${FILE}")
elseif(EXT_LOWER MATCHES "\\.(h|hpp)$")
list(APPEND HEADER_FILES "${FILE}")
elseif(EXT_LOWER MATCHES "\\.(s|S)$")
list(APPEND ASM_FILES "${FILE}")
elseif(EXT_LOWER STREQUAL ".mm")
list(APPEND MM_FILES "${FILE}")
elseif(EXT_LOWER STREQUAL ".metal")
list(APPEND METAL_FILES "${FILE}")
else()
list(APPEND OTHER_FILES "${FILE}")
endif()
endforeach()
set(${CPP_OUT} ${CPP_FILES} PARENT_SCOPE)
set(${HEADER_OUT} ${HEADER_FILES} PARENT_SCOPE)
set(${ASM_OUT} ${ASM_FILES} PARENT_SCOPE)
set(${MM_OUT} ${MM_FILES} PARENT_SCOPE)
set(${METAL_OUT} ${METAL_FILES} PARENT_SCOPE)
set(${OTHER_OUT} ${OTHER_FILES} PARENT_SCOPE)
endfunction()
# =============================================================================
# 辅助函数:格式化文件列表为 podspec 格式(每行一个)
# =============================================================================
function(format_file_list_for_podspec FILE_LIST OUTPUT_VAR INDENT)
set(RESULT "")
list(LENGTH FILE_LIST LEN)
math(EXPR LAST_INDEX "${LEN} - 1")
set(INDEX 0)
foreach(FILE ${FILE_LIST})
if(INDEX EQUAL LAST_INDEX)
string(APPEND RESULT "${INDENT}'${FILE}'")
else()
string(APPEND RESULT "${INDENT}'${FILE}',\n")
endif()
math(EXPR INDEX "${INDEX} + 1")
endforeach()
set(${OUTPUT_VAR} "${RESULT}" PARENT_SCOPE)
endfunction()
# =============================================================================
# 验证函数:检查生成 podspec 的前置条件
# =============================================================================
function(validate_podspec_generation)
set(MNN_ROOT "${CMAKE_SOURCE_DIR}")
# 1. 检查 MNN_ROOT 目录是否存在
if(NOT IS_DIRECTORY "${MNN_ROOT}")
message(FATAL_ERROR "MNN source directory not found: ${MNN_ROOT}")
endif()
# 2. 检查必要目录是否存在
set(REQUIRED_DIRS "include/MNN" "source" "3rd_party")
foreach(dir ${REQUIRED_DIRS})
if(NOT IS_DIRECTORY "${MNN_ROOT}/${dir}")
message(FATAL_ERROR "Required directory not found: ${dir}\nPlease ensure MNN source structure is complete.")
endif()
endforeach()
# 3. 检查 LICENSE 文件是否存在
if(NOT EXISTS "${MNN_ROOT}/LICENSE")
message(WARNING "LICENSE file not found. Podspec license field may be invalid.")
endif()
# 4. 检查 MNN_TARGETS 是否已定义且非空
if(NOT DEFINED MNN_TARGETS)
message(FATAL_ERROR "MNN_TARGETS is not defined. Please include generate_podspec.cmake after all targets are created.")
endif()
list(LENGTH MNN_TARGETS TARGETS_COUNT)
if(TARGETS_COUNT EQUAL 0)
message(FATAL_ERROR "MNN_TARGETS is empty. No targets to generate podspec from.")
endif()
# 5. 检查版本号是否有效
if(NOT DEFINED MNN_PODSPEC_VERSION OR MNN_PODSPEC_VERSION STREQUAL "")
message(FATAL_ERROR "MNN_PODSPEC_VERSION is not set. Please define MNN_VERSION or pass -DMNN_PODSPEC_VERSION=x.x.x")
endif()
message(STATUS "Validation passed: All prerequisites met for podspec generation.")
endfunction()
# =============================================================================
# 主函数:从 CMake targets 生成 podspec
# =============================================================================
function(generate_mnn_podspec_from_targets)
set(MNN_ROOT "${CMAKE_SOURCE_DIR}")
message(STATUS "========================================")
message(STATUS "Generating MNN.podspec from CMake targets...")
message(STATUS "========================================")
# =============================================================================
# 0. 验证前置条件
# =============================================================================
validate_podspec_generation()
# =============================================================================
# 1. Collect source files from all MNN targets
# Using MNN_TARGETS variable defined in CMakeLists.txt (fully automatic!)
# =============================================================================
set(ALL_SOURCE_FILES "")
set(ARM82_SOURCE_FILES "")
# MNN_TARGETS is already defined in CMakeLists.txt and contains all targets
# that are linked to the final MNN library. We just iterate over them!
message(STATUS "Collecting sources from MNN_TARGETS: ${MNN_TARGETS}")
foreach(TGT ${MNN_TARGETS})
if(TARGET ${TGT})
get_target_property(SRCS ${TGT} SOURCES)
if(SRCS)
# ARM82 needs special compiler flags, collect separately
if("${TGT}" STREQUAL "MNN_Arm82")
list(APPEND ARM82_SOURCE_FILES ${SRCS})
message(STATUS " [ARM82] ${TGT}: collecting separately")
else()
list(APPEND ALL_SOURCE_FILES ${SRCS})
list(LENGTH SRCS SRC_COUNT)
message(STATUS " ${TGT}: ${SRC_COUNT} files")
endif()
endif()
endif()
endforeach()
# Also collect ARM targets (MNNARM64, MNNARM32) which may not be in MNN_TARGETS
foreach(TGT MNNARM64 MNNARM32)
if(TARGET ${TGT})
get_target_property(SRCS ${TGT} SOURCES)
if(SRCS)
list(APPEND ALL_SOURCE_FILES ${SRCS})
list(LENGTH SRCS SRC_COUNT)
message(STATUS " ${TGT}: ${SRC_COUNT} files")
endif()
endif()
endforeach()
# Collect ARM82 if it exists but wasn't in MNN_TARGETS
if(TARGET MNN_Arm82)
get_target_property(SRCS MNN_Arm82 SOURCES)
if(SRCS AND NOT ARM82_SOURCE_FILES)
list(APPEND ARM82_SOURCE_FILES ${SRCS})
list(LENGTH SRCS SRC_COUNT)
message(STATUS " [ARM82] MNN_Arm82: ${SRC_COUNT} files")
endif()
endif()
# 去重
list(REMOVE_DUPLICATES ALL_SOURCE_FILES)
list(REMOVE_DUPLICATES ARM82_SOURCE_FILES)
# 转换为相对路径
convert_to_relative_paths("${ALL_SOURCE_FILES}" "${MNN_ROOT}" ALL_SOURCE_FILES_REL)
convert_to_relative_paths("${ARM82_SOURCE_FILES}" "${MNN_ROOT}" ARM82_SOURCE_FILES_REL)
# 分类文件
classify_files("${ALL_SOURCE_FILES_REL}"
CPP_FILES HEADER_FILES ASM_FILES MM_FILES METAL_FILES OTHER_FILES)
classify_files("${ARM82_SOURCE_FILES_REL}"
ARM82_CPP ARM82_HEADER ARM82_ASM ARM82_MM ARM82_METAL ARM82_OTHER)
# 统计
list(LENGTH ALL_SOURCE_FILES_REL TOTAL_FILES)
list(LENGTH ARM82_SOURCE_FILES_REL ARM82_TOTAL_FILES)
message(STATUS "Collected ${TOTAL_FILES} source files from CMake targets")
message(STATUS "Collected ${ARM82_TOTAL_FILES} ARM82 files (separate subspec)")
# =============================================================================
# 3. 收集公开头文件
# =============================================================================
file(GLOB_RECURSE PUBLIC_HEADERS
"${MNN_ROOT}/include/MNN/*.h"
"${MNN_ROOT}/include/MNN/*.hpp"
)
convert_to_relative_paths("${PUBLIC_HEADERS}" "${MNN_ROOT}" PUBLIC_HEADERS_REL)
# =============================================================================
# 4. 格式化文件列表
# =============================================================================
format_file_list_for_podspec("${ALL_SOURCE_FILES_REL}" SOURCE_FILES_FORMATTED " ")
format_file_list_for_podspec("${PUBLIC_HEADERS_REL}" PUBLIC_HEADERS_FORMATTED " ")
format_file_list_for_podspec("${ARM82_SOURCE_FILES_REL}" ARM82_FILES_FORMATTED " ")
# 收集 MM 文件路径(用于 requires_arc
set(ARC_FILES "")
foreach(FILE ${MM_FILES})
list(APPEND ARC_FILES "${FILE}")
endforeach()
format_file_list_for_podspec("${ARC_FILES}" ARC_FILES_FORMATTED " ")
# =============================================================================
# 5. 生成 podspec 内容
# =============================================================================
set(PODSPEC_CONTENT "# =============================================================================
# MNN.podspec
# Auto-generated by CMake, DO NOT EDIT!
# Command: cmake .. -DMNN_GENERATE_PODSPEC=ON
# =============================================================================
Pod::Spec.new do |s|
s.name = \"MNN\"
s.version = \"${MNN_PODSPEC_VERSION}\"
s.summary = \"MNN - A lightweight deep neural network inference framework\"
s.description = <<-DESC
MNN is a blazing fast, lightweight deep neural network inference engine.
Auto-generated from CMake configuration.
DESC
s.homepage = \"https://github.com/alibaba/MNN\"
s.license = { :type => 'Apache License, Version 2.0', :file => 'LICENSE' }
s.author = { \"MNN\" => \"mnn@alibaba-inc.com\" }
s.platform = :ios
s.ios.deployment_target = '${MNN_IOS_DEPLOYMENT_TARGET}'
# .mm files require ARC
s.requires_arc = [
${ARC_FILES_FORMATTED}
]
s.source = { :git => \"https://github.com/alibaba/MNN.git\", :tag => \"\#{s.version}\" }
s.frameworks = 'Metal', 'Accelerate', 'CoreVideo', 'Foundation'
s.weak_frameworks = 'MetalPerformanceShaders'
s.libraries = 'c++'
# =============================================================================
# Source files - Auto-extracted from CMake targets
# Total ${TOTAL_FILES} files
# =============================================================================
s.source_files = [
# Public headers
'include/MNN/*.{h,hpp}',
'include/MNN/expr/*.{h,hpp}',
'schema/current/*.{h}',
'3rd_party/flatbuffers/include/flatbuffers/*.{h}',
'3rd_party/half/*.{hpp}',
# Source files extracted from CMake targets
${SOURCE_FILES_FORMATTED}
]
# =============================================================================
# Public headers
# =============================================================================
s.public_header_files = [
${PUBLIC_HEADERS_FORMATTED}
]
# =============================================================================
# Build configuration
# =============================================================================
s.pod_target_xcconfig = {
'HEADER_SEARCH_PATHS' => [
'\"\$(PODS_TARGET_SRCROOT)/include\"',
'\"\$(PODS_TARGET_SRCROOT)/source\"',
'\"\$(PODS_TARGET_SRCROOT)/express\"',
'\"\$(PODS_TARGET_SRCROOT)/tools\"',
'\"\$(PODS_TARGET_SRCROOT)/schema/current\"',
'\"\$(PODS_TARGET_SRCROOT)/3rd_party\"',
'\"\$(PODS_TARGET_SRCROOT)/3rd_party/flatbuffers/include\"',
'\"\$(PODS_TARGET_SRCROOT)/3rd_party/half\"',
'\"\$(PODS_TARGET_SRCROOT)/source/backend/cpu\"',
'\"\$(PODS_TARGET_SRCROOT)/source/backend/cpu/arm\"',
'\"\$(PODS_TARGET_SRCROOT)/source/backend/arm82\"',
'\"\$(PODS_TARGET_SRCROOT)/source/backend/arm82/compute\"',
'\"\$(PODS_TARGET_SRCROOT)/source/backend/arm82/asm\"',
'\"\$(PODS_TARGET_SRCROOT)/source/backend/metal\"',
'\"\$(PODS_TARGET_SRCROOT)/tools/cv/include\"',
'\"\$(PODS_TARGET_SRCROOT)/transformers/llm/engine/include\"',
'\"\$(PODS_TARGET_SRCROOT)/transformers/llm/engine/src\"'
].join(' '),
'GCC_PREPROCESSOR_DEFINITIONS' => [
'\$(inherited)',
'MNN_METAL_ENABLED=1',
'ENABLE_ARMV82=1',
'MNN_USE_NEON=1',
'MNN_SUPPORT_TRANSFORMER_FUSE=1',
'MNN_LOW_MEMORY=1',
'MNN_IMGPROC_DRAW=1',
'MNN_REDUCE_SIZE=1'
].join(' '),
'OTHER_CFLAGS' => '-fno-rtti -fno-exceptions -Oz',
'OTHER_CPLUSPLUSFLAGS' => '-std=c++17 -fno-rtti -fno-exceptions -Oz',
'CLANG_CXX_LANGUAGE_STANDARD' => 'c++17',
'METAL_LIBRARY_FILE_BASE' => 'mnn',
'ARCHS' => 'arm64',
'VALID_ARCHS' => 'arm64',
# Optimization: remove debug info and strip
'GCC_OPTIMIZATION_LEVEL' => 'z',
'DEBUG_INFORMATION_FORMAT' => 'dwarf',
'STRIP_INSTALLED_PRODUCT' => 'YES',
'STRIP_STYLE' => 'non-global',
'DEAD_CODE_STRIPPING' => 'YES',
'DEPLOYMENT_POSTPROCESSING' => 'YES'
}
# =============================================================================
# ARM82 FP16 - Requires -march=armv8.2-a+fp16 compiler flag
# Total ${ARM82_TOTAL_FILES} files
# =============================================================================
s.subspec 'ARM82' do |sp|
sp.source_files = [
${ARM82_FILES_FORMATTED}
]
sp.pod_target_xcconfig = {
'OTHER_CFLAGS' => '-march=armv8.2-a+fp16 -fno-rtti -fno-exceptions',
'OTHER_CPLUSPLUSFLAGS' => '-std=c++17 -march=armv8.2-a+fp16 -fno-rtti -fno-exceptions'
}
sp.xcconfig = {
'OTHER_ASFLAGS' => '-march=armv8.2-a+fp16'
}
end
s.default_subspecs = ['ARM82']
end
")
# =============================================================================
# 6. 写入文件
# =============================================================================
set(PODSPEC_FILE "${MNN_ROOT}/MNN.podspec")
file(WRITE "${PODSPEC_FILE}" "${PODSPEC_CONTENT}")
message(STATUS "========================================")
message(STATUS "Generated: ${PODSPEC_FILE}")
message(STATUS "Total files: ${TOTAL_FILES}")
message(STATUS "ARM82 files: ${ARM82_TOTAL_FILES}")
message(STATUS "========================================")
endfunction()
# =============================================================================
# 如果直接调用
# =============================================================================
if(MNN_GENERATE_PODSPEC)
generate_mnn_podspec_from_targets()
endif()
+1
View File
@@ -27,6 +27,7 @@ MNN使用CMake构建项目,CMake中的宏定义列表如下:
| NATIVE_LIBRARY_OUTPUT | 如果构建为动态库,则指定动态库的输出路径,默认为`OFF` |
| NATIVE_INCLUDE_OUTPUT | 如果构建为动态库,则指定动态库的头文件路径,默认为`OFF` |
| MNN_AAPL_FMWK | 是否构建`MNN.framework`替代`*.dylib`,默认为`OFF` |
| MNN_GENERATE_PODSPEC | 是否构建`MNN.podspec`以支持CocoaPods发布,默认为`OFF` |
| MNN_WITH_PLUGIN | 是否支持`Plugin算子`,默认为`OFF` |
| MNN_SKIPBUILD_GEOMETRY | 是否跳过MNN的几何计算编译,若是,MNN引擎仅支持在模型转换工具时加上 --saveStaticModel 转换出来的固定输入形状的模型,默认为`OFF` |
| MNN_BUILD_MINI | 是否构建MNN的最小化版本,若是,开启 `MNN_SKIPBUILD_GEOMETRY``MNN_REDUCE_SIZE`,默认为`OFF` |
+102
View File
@@ -0,0 +1,102 @@
# MNN CocoaPods 支持
MNN 支持通过 CMake 自动生成 iOS CocoaPods 的 podspec 文件,方便集成到 iOS 项目中。
## 概述
`MNN_GENERATE_PODSPEC` 是一个实验性选项,用于从 CMake 配置自动生成 iOS CocoaPods 的 podspec 文件。启用后,CMake 会自动扫描所有 MNN target 的源文件,生成完整的 `MNN.podspec`
## 使用方式
### 方式一:使用脚本(推荐)
```bash
# 生成 podspec
./tools/script/generate_podspec.sh
# 生成并验证
./tools/script/generate_podspec.sh --validate
# 生成并完整验证(需要 Xcode
./tools/script/generate_podspec.sh --validate-full
# 检查 podspec 是否与 CMake 配置同步
./tools/script/generate_podspec.sh --check
# 指定版本号
./tools/script/generate_podspec.sh -v 3.3.0
# CI 模式(无颜色输出)
./tools/script/generate_podspec.sh --validate --ci
```
### 方式二:手动 CMake 构建
```bash
mkdir build && cd build
cmake .. \
-DCMAKE_TOOLCHAIN_FILE=../cmake/ios.toolchain.cmake \
-DMNN_METAL=ON \
-DMNN_AAPL_FMWK=ON \
-DMNN_BUILD_SHARED_LIBS=OFF \
-DMNN_SEP_BUILD=OFF \
-DMNN_GENERATE_PODSPEC=ON
make -j8
```
构建完成后,`MNN.podspec` 会生成在项目根目录。
## 脚本参数说明
| 参数 | 说明 |
|------|------|
| `--version`, `-v` | 覆盖 podspec 版本号(默认使用 CMakeLists.txt 中的 MNN_VERSION |
| `--check`, `-c` | 检查现有 podspec 是否与 CMake 配置同步(用于 CI) |
| `--validate` | 生成后执行快速语法验证 |
| `--validate-full` | 生成后执行完整验证(需要 Xcode,耗时较长) |
| `--ci` | CI 模式,禁用颜色输出,严格退出码 |
| `--help`, `-h` | 显示帮助信息 |
## 生成的 podspec 包含内容
- **平台**iOS 11.0+
- **架构**arm64
- **框架依赖**Metal、Accelerate、CoreVideo、Foundation
- **弱依赖**MetalPerformanceShaders
- **源文件**:自动从 CMake targets 提取
- **ARM82 子规范**FP16 计算支持(需要 `-march=armv8.2-a+fp16`
- **ARC 配置**:自动识别 .mm 文件
## 发布到 CocoaPods
```bash
# 1. 验证 podspec
pod spec lint MNN.podspec --allow-warnings
# 2. 推送到私有 spec repo
pod repo push my-specs MNN.podspec --allow-warnings
# 3. 推送到 CocoaPods trunk(需要权限)
pod trunk push MNN.podspec --allow-warnings
```
## 在 Podfile 中使用
```ruby
# 使用本地 podspec
pod 'MNN', :path => './path/to/MNN'
# 使用 Git 仓库
pod 'MNN', :git => 'https://github.com/alibaba/MNN.git', :tag => '3.3.0'
# 使用 CocoaPods trunk
pod 'MNN', '~> 3.3.0'
```
## 注意事项
1. **仅支持 iOS**:当前实现仅支持 iOS 平台,不支持 macOS 或 Catalyst
2. **Metal 后端**:生成的 podspec 默认启用 Metal 后端
3. **ARM82 子规范**:FP16 计算作为子规范提供,需要特殊编译标志
4. **同步检查**:修改 CMake 配置后,请重新生成 podspec 并保持同步
5. **错误处理**:如果生成失败,请检查 CMake 配置是否完整,特别是 MNN_TARGETS 是否正确定义
+3 -3
View File
@@ -1,9 +1,9 @@
# CPU
if(MNN_SUPPORT_RENDER)
FILE(GLOB MNN_CPU_SRC ${CMAKE_CURRENT_LIST_DIR}/* ${CMAKE_CURRENT_LIST_DIR}/compute/* ${CMAKE_CURRENT_LIST_DIR}/render/*)
FILE(GLOB MNN_CPU_SRC ${CMAKE_CURRENT_LIST_DIR}/*.cpp ${CMAKE_CURRENT_LIST_DIR}/*.h ${CMAKE_CURRENT_LIST_DIR}/*.hpp ${CMAKE_CURRENT_LIST_DIR}/compute/* ${CMAKE_CURRENT_LIST_DIR}/render/*)
else()
FILE(GLOB MNN_CPU_SRC ${CMAKE_CURRENT_LIST_DIR}/* ${CMAKE_CURRENT_LIST_DIR}/compute/*)
FILE(GLOB MNN_CPU_SRC ${CMAKE_CURRENT_LIST_DIR}/*.cpp ${CMAKE_CURRENT_LIST_DIR}/*.h ${CMAKE_CURRENT_LIST_DIR}/*.hpp ${CMAKE_CURRENT_LIST_DIR}/compute/*)
endif()
add_library(MNNCPU OBJECT ${MNN_CPU_SRC})
if (MNN_SUPPORT_BF16)
@@ -46,4 +46,4 @@ IF(MNN_ARM82)
list(APPEND MNN_TARGETS MNN_Arm82)
list(APPEND MNN_OBJECTS_TO_LINK $<TARGET_OBJECTS:MNN_Arm82>)
ENDIF()
ENDIF()
ENDIF()
@@ -16,7 +16,7 @@
#include "backend/cpu/compute/ConvOpt.h"
#ifdef MNN_KLEIDIAI_ENABLED
#include "backend/cpu/KleidiAIConvolutionDepthwise.hpp"
#include "backend/cpu/kleidiai/KleidiAIConvolutionDepthwise.hpp"
#include "backend/cpu/CPURuntime.hpp"
#endif //MNN_KLEIDIAI_ENABLED
@@ -215,13 +215,13 @@ ErrorCode CPUConvolutionDepthwise::BasicFloatExecution::onResize(const std::vect
auto biasP = inputs[2]->host<uint8_t>();
auto weightP = inputs[1]->host<uint8_t>();
for (int index = divides[tId]; index < divides[tId+1]; ++index) {
int dz = index / batch;
auto dstOrigin = outputPtr + dst_z_step * index * bytes;
const auto srcOrigin = inputPtr + src_z_step * index * bytes;
auto bias_z = biasP + unit * dz * bytes;
const auto weight_dz = weightP + dz * weight_z_step * bytes;
auto srcPtr = srcOrigin;
// Pad inputs
for (int y = 0; y < src_height; ++y) {
@@ -289,8 +289,8 @@ public:
int strideX = conv2d->common()->strideX();
int dilateX = conv2d->common()->dilateX();
int dilateY = conv2d->common()->dilateY();
bool useKleidiAI = kernel_height ==3 && kernel_width ==3 &&
strideY ==1 && strideX ==1 &&
bool useKleidiAI = kernel_height ==3 && kernel_width ==3 &&
strideY ==1 && strideX ==1 &&
dilateX ==1 && dilateY ==1 &&
bytes == 4;
useKleidiAI = backend->getRuntime()->hint().enableKleidiAI && MNNGetCPUInfo()->sme2 && useKleidiAI;
@@ -25,9 +25,9 @@
#include "backend/cpu/compute/ConvInt8TiledExecutor.hpp"
#ifdef MNN_KLEIDIAI_ENABLED
#include "backend/cpu/compute/KleidiAIConvInt8.hpp"
#include "backend/cpu/compute/KleidiAIConvolution.hpp"
#include "backend/cpu/compute/KleidiAIDenseConvolution.hpp"
#include "backend/cpu/kleidiai/KleidiAIConvInt8.hpp"
#include "backend/cpu/kleidiai/KleidiAIConvolution.hpp"
#include "backend/cpu/kleidiai/KleidiAIDenseConvolution.hpp"
#endif //MNN_KLEIDIAI_ENABLED
namespace MNN {
@@ -7,7 +7,7 @@
#ifndef KleidiAIConvInt8_hpp
#define KleidiAIConvInt8_hpp
#include "backend/cpu/CPUConvolution.hpp"
#include "backend/cpu/arm/mnn_kleidiai.h"
#include "mnn_kleidiai.h"
namespace MNN {
class KleidiAIConvInt8 : public CPUConvolution {
@@ -7,16 +7,16 @@
#ifndef KleidiAIConvolution_hpp
#define KleidiAIConvolution_hpp
#include "backend/cpu/CPUConvolution.hpp"
#include "backend/cpu/arm/mnn_kleidiai.h"
#include "mnn_kleidiai.h"
namespace MNN {
class KleidiAIConvolution : public CPUConvolution{
public:
KleidiAIConvolution(const Convolution2DCommon *common, Backend *b, const float *originWeight, size_t originWeightSize, const float *bias, size_t biasSize);
KleidiAIConvolution(std::shared_ptr<CPUConvolution::Resource> resource, const Convolution2DCommon *common, Backend* b);
virtual ~KleidiAIConvolution();
virtual ErrorCode onExecute(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) override;
virtual ErrorCode onResize(const std::vector<Tensor *> &inputs, const std::vector<Tensor *> &outputs) override;
virtual bool onClone(Backend* bn, const Op* op, Execution** dst) override;
private:
@@ -1,4 +1,4 @@
#include "backend/cpu/KleidiAIConvolutionDepthwise.hpp"
#include "KleidiAIConvolutionDepthwise.hpp"
#ifdef MNN_KLEIDIAI_ENABLED
@@ -12,23 +12,23 @@
namespace MNN {
template<typename T>
void nchw_to_nhwc_optimized(const T* src, T* dst,
void nchw_to_nhwc_optimized(const T* src, T* dst,
int batch, int channel, int height, int width) {
const int hw = height * width;
const int chw = channel * hw;
const int wc = width * channel;
for (int n = 0; n < batch; ++n) {
const T* src_batch = src + n * chw;
T* dst_batch = dst + n * chw;
for (int c = 0; c < channel; ++c) {
const T* src_channel = src_batch + c * hw;
for (int h = 0; h < height; ++h) {
const T* src_row = src_channel + h * width;
T* dst_row = dst_batch + h * wc + c;
for (int w = 0; w < width; ++w) {
dst_row[w * channel] = src_row[w];
}
@@ -39,7 +39,7 @@ void nchw_to_nhwc_optimized(const T* src, T* dst,
KleidiAIConvolutionDepthwise::KleidiAIDepthwiseExecution::KleidiAIDepthwiseExecution(const Convolution2DCommon* common, Backend* b,
const float* originWeight, size_t originWeightSize,
const float* bias, size_t biasSize)
const float* bias, size_t biasSize)
: MNN::CPUConvolution(common, b) {
int kernel_height = common->kernelY();
int kernel_width = common->kernelX();
@@ -65,7 +65,7 @@ KleidiAIConvolutionDepthwise::KleidiAIDepthwiseExecution::KleidiAIDepthwiseExecu
kai_run_rhs_dwconv_pack_x32p1vlx1b_x32_x32_sme(kernel_height, kernel_width, kernel_height, kernel_width, channels, weightTempPtr, bias, mPackedRhs.get()->host<void>());
b->onReleaseBuffer(mWeightTemp.get(), Backend::STATIC);
}
ErrorCode KleidiAIConvolutionDepthwise::KleidiAIDepthwiseExecution::onResize(const std::vector<Tensor*>& inputs,
const std::vector<Tensor*>& outputs) {
CPUConvolution::onResize(inputs, outputs);
@@ -109,8 +109,8 @@ ErrorCode KleidiAIConvolutionDepthwise::KleidiAIDepthwiseExecution::onExecute(co
auto postData = getPostParameters();
auto output_height = outputTensor->height();
auto core = static_cast<CPUBackend*>(backend())->functions();
auto batch = inputTensor->batch();
auto batch = inputTensor->batch();
MNN_CONCURRENCY_BEGIN(tId, mNumber) {
CPUTensorConverter::convert(inputTensor, &mInputNHWC, core, tId, mNumber);
}
@@ -3,7 +3,7 @@
#include <numeric>
#include "CommonOptFunction.h"
#include "backend/cpu/compute/CommonOptFunction.h"
#include "MNN/ErrorCode.hpp"
#include "backend/cpu/CPUBackend.hpp"
#include "backend/cpu/CPUTensorConvert.hpp"
@@ -1,7 +1,7 @@
#ifndef KleidiAIDenseConvolution_hpp
#define KleidiAIDenseConvolution_hpp
#include "ConvolutionTiledExecutor.hpp"
#include "backend/cpu/compute/ConvolutionTiledExecutor.hpp"
#include "backend/cpu/CPUConvolution.hpp"
namespace MNN {
@@ -239,4 +239,4 @@ private:
};
} // namespace MNN
#endif /* KleidiAIDenseConvolution_hpp */
#endif /* KleidiAIDenseConvolution_hpp */
+3
View File
@@ -152,6 +152,8 @@ static_check() {
fi
}
android_static_build() {
BASH_FILE="$USER_HOME/.zshrc"
if [ -f "$BASH_FILE" ]; then
@@ -751,6 +753,7 @@ case "$1" in
doc_check
static_check
py_check
echo_static_success
;;
*)
+2 -2
View File
@@ -5,7 +5,7 @@
#include <random>
#include "MNNTestSuite.h"
#include "backend/cpu/compute/KleidiAIDenseConvolution.hpp"
#include "backend/cpu/kleidiai/KleidiAIDenseConvolution.hpp"
using namespace MNN;
@@ -158,4 +158,4 @@ private:
};
MNNTestSuiteRegister(LhsPackingTest, "imatmul/lhs");
#endif
#endif
+387
View File
@@ -0,0 +1,387 @@
#!/bin/bash
# =============================================================================
# generate_podspec.sh
# Auto-generate MNN.podspec from CMake targets and optionally validate it
#
# Uses the same CMake configuration as production build
#
# Usage:
# ./tools/script/generate_podspec.sh # Generate podspec
# ./tools/script/generate_podspec.sh -c # Check if podspec is in sync
# ./tools/script/generate_podspec.sh -v 3.2.0 # Override version
# ./tools/script/generate_podspec.sh --validate # Generate + validate syntax
# ./tools/script/generate_podspec.sh --validate-full # Generate + full validation (requires Xcode)
# ./tools/script/generate_podspec.sh --ci # CI mode (no colors, strict exit)
# =============================================================================
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
MNN_ROOT="$(cd "$SCRIPT_DIR/../.." && pwd)"
# Options
VERSION=""
CHECK_MODE=false
VALIDATE_MODE=false
VALIDATE_FULL=false
CI_MODE=false
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'
# Parse arguments
while [[ $# -gt 0 ]]; do
case $1 in
--version|-v)
VERSION="$2"
shift 2
;;
--check|-c)
CHECK_MODE=true
shift
;;
--validate)
VALIDATE_MODE=true
shift
;;
--validate-full)
VALIDATE_FULL=true
VALIDATE_MODE=true
shift
;;
--ci)
CI_MODE=true
RED=''
GREEN=''
YELLOW=''
BLUE=''
NC=''
shift
;;
--help|-h)
echo "Usage: $0 [options]"
echo ""
echo "Generate MNN.podspec from CMake targets"
echo "Version defaults to MNN_VERSION from CMakeLists.txt"
echo ""
echo "Options:"
echo " --check, -c Check if podspec is in sync (for CI)"
echo " --version, -v VERSION Override podspec version"
echo " --validate Generate + validate syntax"
echo " --validate-full Generate + full validation (requires Xcode)"
echo " --ci CI mode (no colors, strict exit)"
echo " --help, -h Show this help message"
exit 0
;;
*)
echo "Unknown option: $1"
exit 1
;;
esac
done
# Helper functions for logging
log_info() { echo -e "${BLUE}[INFO]${NC} $1"; }
log_success() { echo -e "${GREEN}[PASS]${NC} $1"; }
log_warning() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[FAIL]${NC} $1"; }
# =============================================================================
# Check mode: backup current podspec first
# =============================================================================
if [ "$CHECK_MODE" = true ]; then
echo "=========================================="
echo "Checking MNN.podspec is in sync"
echo "=========================================="
if [ ! -f "$MNN_ROOT/MNN.podspec" ]; then
echo "❌ Error: MNN.podspec not found!"
echo ""
echo "Please run: ./tools/script/generate_podspec.sh"
exit 1
fi
cp "$MNN_ROOT/MNN.podspec" "$MNN_ROOT/MNN.podspec.backup"
else
echo "=========================================="
echo "Generating MNN.podspec from CMake targets"
echo "=========================================="
fi
echo "MNN Root: $MNN_ROOT"
if [ -n "$VERSION" ]; then
echo "Version: $VERSION (override)"
else
echo "Version: (from MNN_VERSION in CMakeLists.txt)"
fi
echo ""
# =============================================================================
# CMake configuration
# =============================================================================
BUILD_DIR="$MNN_ROOT/build_podspec_gen"
rm -rf "$BUILD_DIR"
mkdir -p "$BUILD_DIR"
cd "$BUILD_DIR"
# COMMON flags (same as online build script)
COMMON_FLAGS=(
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_TOOLCHAIN_FILE="$MNN_ROOT/cmake/ios.toolchain.cmake"
-DENABLE_BITCODE=0
-DMNN_AAPL_FMWK=ON
-DMNN_SEP_BUILD=OFF
-DMNN_BUILD_SHARED_LIBS=OFF
-DMNN_USE_THREAD_POOL=OFF
-DMNN_KLEIDIAI=OFF
-DMNN_REDUCE_SIZE=OFF
)
# EXTRA flags (same as online build script)
EXTRA_FLAGS=(
-DCMAKE_SYSTEM_NAME=iOS
-DMNN_BUILD_LLM=ON
-DMNN_SUPPORT_TRANSFORMER_FUSE=ON
-DMNN_LOW_MEMORY=ON
-DMNN_BUILD_AUDIO=OFF
-DLLM_SUPPORT_VISION=OFF
-DMNN_BUILD_OPENCV=ON
-DMNN_IMGCODECS=OFF
-DMNN_SME2=OFF
-DLLM_SUPPORT_HTTP_RESOURCE=OFF
)
# iOS arm64 flags (same as online build script - NO CoreML!)
IOS_FLAGS=(
-DMNN_METAL=ON
-DARCHS="arm64"
# Optimization flags same as online build
'-DCMAKE_CXX_FLAGS_RELEASE=-Oz'
'-DCMAKE_C_FLAGS_RELEASE=-Oz'
)
# Podspec generation flags
PODSPEC_FLAGS=(
-DMNN_GENERATE_PODSPEC=ON
)
if [ -n "$VERSION" ]; then
PODSPEC_FLAGS+=(-DMNN_PODSPEC_VERSION="$VERSION")
fi
echo "Configuring CMake..."
cmake "$MNN_ROOT" \
"${COMMON_FLAGS[@]}" \
"${EXTRA_FLAGS[@]}" \
"${IOS_FLAGS[@]}" \
"${PODSPEC_FLAGS[@]}" \
> /dev/null 2>&1
# Cleanup
cd "$MNN_ROOT"
rm -rf "$BUILD_DIR"
# =============================================================================
# Check mode: compare and report
# =============================================================================
if [ "$CHECK_MODE" = true ]; then
echo ""
if diff -q "$MNN_ROOT/MNN.podspec.backup" "$MNN_ROOT/MNN.podspec" > /dev/null 2>&1; then
echo "✅ MNN.podspec is in sync!"
rm -f "$MNN_ROOT/MNN.podspec.backup"
exit 0
else
echo "❌ MNN.podspec is out of sync!"
echo ""
echo "Differences:"
echo "=========================================="
diff -u "$MNN_ROOT/MNN.podspec.backup" "$MNN_ROOT/MNN.podspec" | head -30 || true
echo "=========================================="
echo ""
echo "To fix, run:"
echo " ./tools/script/generate_podspec.sh"
echo " git add MNN.podspec"
echo " git commit -m 'Update MNN.podspec'"
# Restore original
mv "$MNN_ROOT/MNN.podspec.backup" "$MNN_ROOT/MNN.podspec"
exit 1
fi
fi
# =============================================================================
# Validation functions
# =============================================================================
# Check if podspec file exists
validate_file_exists() {
log_info "Checking podspec file exists..."
if [ ! -f "$MNN_ROOT/MNN.podspec" ]; then
log_error "MNN.podspec not found at: $MNN_ROOT/MNN.podspec"
return 1
fi
log_success "Podspec file exists: $MNN_ROOT/MNN.podspec"
return 0
}
# Validate podspec syntax
validate_syntax() {
log_info "Validating podspec syntax..."
if ! command -v pod &> /dev/null; then
log_warning "CocoaPods not installed, skipping syntax validation"
echo " Install CocoaPods to enable validation: sudo gem install cocoapods"
return 0
fi
# Use pod spec lint for quick syntax check (no download/compile)
if pod spec lint "$MNN_ROOT/MNN.podspec" --quick --no-clean --allow-warnings 2>&1; then
log_success "Podspec syntax is valid"
return 0
else
log_error "Podspec syntax validation failed"
return 1
fi
}
# Validate file references in podspec
validate_file_references() {
log_info "Checking file references..."
local errors=0
# Extract source_files patterns and check if they exist
while IFS= read -r pattern; do
# Remove quotes and commas
pattern=$(echo "$pattern" | sed "s/['',]//g" | xargs)
# Skip empty lines and comments
if [ -z "$pattern" ] || [[ "$pattern" == \#* ]]; then
continue
fi
# Check if pattern contains glob
if [[ "$pattern" == *"*"* ]]; then
# Expand glob and check if any files match
expanded=$(eval echo "$pattern" 2>/dev/null)
if [ -z "$expanded" ]; then
log_warning "Pattern matches no files: $pattern"
fi
else
# Check if file exists
if [ ! -e "$MNN_ROOT/$pattern" ]; then
log_error "File not found: $pattern"
errors=$((errors + 1))
fi
fi
done < <(grep -E "^\s*'" "$MNN_ROOT/MNN.podspec" | grep -v "^\s*#" | head -100)
if [ $errors -eq 0 ]; then
log_success "File references are valid"
return 0
else
log_error "Found $errors invalid file references"
return 1
fi
}
# Full validation using pod lib lint (requires Xcode)
validate_full() {
log_info "Running full validation (this may take a while)..."
if ! command -v pod &> /dev/null; then
log_error "CocoaPods not installed"
echo " Install CocoaPods to enable full validation: sudo gem install cocoapods"
return 1
fi
if [[ "$(uname)" != "Darwin" ]]; then
log_warning "Full validation requires macOS, skipping"
return 0
fi
# Run pod lib lint
if pod lib lint "$MNN_ROOT/MNN.podspec" --allow-warnings --verbose 2>&1; then
log_success "Full validation passed"
return 0
else
log_error "Full validation failed"
return 1
fi
}
# =============================================================================
# Validation mode: run validation after generation
# =============================================================================
if [ "$VALIDATE_MODE" = true ]; then
echo ""
echo "=========================================="
echo "Validating MNN.podspec"
echo "=========================================="
VALIDATE_FAILED=0
# Step 1: Check file exists
if ! validate_file_exists; then
VALIDATE_FAILED=1
fi
# Step 2: Validate syntax (only if file exists)
if [ $VALIDATE_FAILED -eq 0 ]; then
if ! validate_syntax; then
VALIDATE_FAILED=1
fi
fi
# Step 3: Validate file references
if ! validate_file_references; then
VALIDATE_FAILED=1
fi
# Step 4: Full validation (if requested)
if [ "$VALIDATE_FULL" = true ]; then
if ! validate_full; then
VALIDATE_FAILED=1
fi
fi
# Report results
echo ""
echo "=========================================="
if [ $VALIDATE_FAILED -eq 0 ]; then
log_success "All validations passed!"
echo "=========================================="
else
log_error "Validation failed!"
echo "=========================================="
echo ""
echo "To fix issues:"
echo " 1. Review the errors above"
echo " 2. Regenerate podspec if needed"
echo " 3. Commit the updated podspec:"
echo " git add MNN.podspec"
echo " git commit -m 'Update MNN.podspec'"
exit 1
fi
fi
# =============================================================================
# Normal mode: show success message
# =============================================================================
if [ "$VALIDATE_MODE" = false ] && [ "$CHECK_MODE" = false ]; then
echo ""
echo "=========================================="
echo "Done! Generated: $MNN_ROOT/MNN.podspec"
echo "=========================================="
echo ""
echo "To validate the generated podspec:"
echo " ./tools/script/generate_podspec.sh --validate"
echo ""
echo "For full validation (requires Xcode):"
echo " ./tools/script/generate_podspec.sh --validate-full"
fi