# # Copyright © 2022-2024 Arm Ltd and Contributors. All rights reserved. # SPDX-License-Identifier: MIT # cmake_minimum_required (VERSION 3.7.0) project(armnnDelegate) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17 -Wall -Wextra -Werror -Wold-style-cast -Wno-missing-braces -Wconversion -Wsign-conversion -Wno-comment") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules/") option(BUILD_UNIT_TESTS "Build unit tests" ON) option(BUILD_CLASSIC_DELEGATE "Build classic delegate" ON) option(BUILD_OPAQUE_DELEGATE "Build opaque delegate" OFF) option(BUILD_SHARED_LIBS "Build share libs" ON) option(BUILD_DELEGATE_JNI_INTERFACE "Builds a library to allow accessing the Arm NN delegate from Java code. This is an experimental feature." ON) ## Do not include flatbuffers::ClassicLocale which can cause abort when destroyed add_definitions(-DFLATBUFFERS_LOCALE_INDEPENDENT=0) set(armnnDelegate_sources) list(APPEND armnnDelegate_sources common/include/DelegateOptions.hpp common/src/DelegateOptions.cpp common/src/DelegateUtils.hpp common/src/MultiLayerFacade.hpp) ## Add Armnn as a Dependency if(NOT ARMNN_SUB_PROJECT) find_package(Armnn REQUIRED CONFIG HINTS ${Armnn_DIR}) endif() if (BUILD_CLASSIC_DELEGATE) add_subdirectory(classic) add_library(armnnDelegate ${armnnDelegate_sources}) target_include_directories(armnnDelegate PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common/src) endif() if (BUILD_OPAQUE_DELEGATE) add_subdirectory(opaque) add_library(armnnOpaqueDelegate ${armnnDelegate_sources}) target_include_directories(armnnOpaqueDelegate PUBLIC $ $ PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/common/src) endif() include(GNUInstallDirs) if (BUILD_CLASSIC_DELEGATE) target_link_libraries(armnnDelegate PUBLIC Armnn::Armnn) ## Add armnnClassicDelegateObject as a Dependency target_link_libraries(armnnDelegate PUBLIC armnnClassicDelegateObject) endif() if (BUILD_OPAQUE_DELEGATE) target_link_libraries(armnnOpaqueDelegate PUBLIC Armnn::Armnn) ## Add armnnOpaqueDelegateObject as a Dependency target_link_libraries(armnnOpaqueDelegate PUBLIC armnnOpaqueDelegateObject) endif() ## Add TfLite dependency find_package(TfLiteSrc REQUIRED MODULE) find_package(TfLite REQUIRED MODULE) if (BUILD_CLASSIC_DELEGATE) target_link_libraries(armnnDelegate PUBLIC ${TfLite_LIB}) # lpthread and ldl are not required for Android if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL Android) target_link_libraries(armnnDelegate PUBLIC -lpthread) target_link_libraries(armnnDelegate PUBLIC -ldl) endif() endif() if (BUILD_OPAQUE_DELEGATE) target_link_libraries(armnnOpaqueDelegate PUBLIC ${TfLite_LIB}) # lpthread and ldl are not required for Android if(NOT "${CMAKE_SYSTEM_NAME}" STREQUAL Android) target_link_libraries(armnnOpaqueDelegate PUBLIC -lpthread) target_link_libraries(armnnOpaqueDelegate PUBLIC -ldl) endif() endif() # Add libraries from armnn third-party libraries # Third-party header files are not warning clean # We can't change compilation flags on header files directly, so we need to add them to an interface library first add_library(thirdparty_headers INTERFACE) target_include_directories(thirdparty_headers INTERFACE $ $) target_compile_options(thirdparty_headers INTERFACE -Wno-old-style-cast) if (BUILD_CLASSIC_DELEGATE) target_link_libraries(armnnDelegate PUBLIC thirdparty_headers) endif() if (BUILD_OPAQUE_DELEGATE) target_link_libraries(armnnOpaqueDelegate PUBLIC thirdparty_headers) endif() add_library(profiling_library_headers INTERFACE) target_include_directories(profiling_library_headers INTERFACE $ $) if (BUILD_CLASSIC_DELEGATE) target_link_libraries(armnnDelegate PUBLIC profiling_library_headers) target_link_libraries(armnnDelegate PUBLIC Armnn::armnnUtils) set_target_properties(armnnDelegate PROPERTIES VERSION ${DELEGATE_LIB_VERSION} SOVERSION ${DELEGATE_LIB_SOVERSION}) endif() if (BUILD_OPAQUE_DELEGATE) target_link_libraries(armnnOpaqueDelegate PUBLIC profiling_library_headers) target_link_libraries(armnnOpaqueDelegate PUBLIC Armnn::armnnUtils) set_target_properties(armnnOpaqueDelegate PROPERTIES VERSION ${OPAQUE_DELEGATE_LIB_VERSION} SOVERSION ${OPAQUE_DELEGATE_LIB_SOVERSION}) endif() if(BUILD_UNIT_TESTS) set(commonDelegate_unittest_sources) list(APPEND commonDelegate_unittest_sources common/src/test/DelegateTestInterpreter.hpp common/src/test/DelegateTestInterpreterUtils.hpp test/ActivationTest.cpp test/ActivationTestHelper.hpp test/ArgMinMaxTest.cpp test/ArgMinMaxTestHelper.hpp test/BatchMatMulTest.cpp test/BatchMatMulTestHelper.hpp test/BatchSpaceTest.cpp test/BatchSpaceTestHelper.hpp test/BroadcastToTest.cpp test/BroadcastToTestHelper.hpp test/CastTest.cpp test/CastTestHelper.hpp test/ComparisonTest.cpp test/ComparisonTestHelper.hpp test/ControlTest.cpp test/ControlTestHelper.hpp test/Convolution2dTest.cpp test/Convolution3dTest.cpp test/ConvolutionTestHelper.hpp test/DepthwiseConvolution2dTest.cpp test/ElementwiseBinaryTest.cpp test/ElementwiseBinaryTestHelper.hpp test/ElementwiseUnaryTest.cpp test/ElementwiseUnaryTestHelper.hpp test/ExpandDimsTest.cpp test/FillTest.cpp test/FillTestHelper.hpp test/FullyConnectedTest.cpp test/FullyConnectedTestHelper.hpp test/GatherTest.cpp test/GatherTestHelper.hpp test/GatherNdTest.cpp test/GatherNdTestHelper.hpp test/LogicalTest.cpp test/LogicalTestHelper.hpp test/LstmTest.cpp test/LstmTestHelper.hpp test/MirrorPadTest.cpp test/NormalizationTest.cpp test/NormalizationTestHelper.hpp test/PackTest.cpp test/PackTestHelper.hpp test/PadTest.cpp test/PadTestHelper.hpp test/Pooling2dTest.cpp test/Pooling2dTestHelper.hpp test/Pooling3dTest.cpp test/Pooling3dTestHelper.hpp test/PreluTest.cpp test/PreluTestHelper.hpp test/QuantizationTest.cpp test/QuantizationTestHelper.hpp test/RedefineTestHelper.hpp test/ReduceTest.cpp test/ReduceTestHelper.hpp test/ReshapeTest.cpp test/ResizeTest.cpp test/ResizeTestHelper.hpp test/ReverseV2Test.cpp test/ReverseV2TestHelper.hpp test/RoundTest.cpp test/RoundTestHelper.hpp test/ScatterNdTest.cpp test/ScatterNdTestHelper.hpp test/SoftmaxTest.cpp test/SoftmaxTestHelper.hpp test/SpaceDepthTest.cpp test/SpaceDepthTestHelper.hpp test/ShapeTest.cpp test/ShapeTestHelper.hpp test/SliceTest.cpp test/SliceTestHelper.hpp test/SqueezeTest.cpp test/StridedSliceTest.cpp test/StridedSliceTestHelper.hpp test/SplitTest.cpp test/SplitTestHelper.hpp test/TestUtils.hpp test/TestUtils.cpp test/TileTest.cpp test/TileTestHelper.hpp test/TransposeConvolution2dTest.cpp test/TransposeTest.cpp test/TransposeTestHelper.hpp test/UnidirectionalSequenceLstmTest.cpp test/UnidirectionalSequenceLstmTestHelper.hpp test/UnpackTest.cpp test/UnpackTestHelper.hpp) # There's a known Android NDK bug which causes a subset of NeonLayerTests to # fail. We'll exclude these tests in NeonLayerTests_NDK_Bug.cpp if we're doing # a debug build and NDK is less than r21. # https://github.com/android/ndk/issues/1135 # Default to always including these tests. set(INCLUDE_NDK_BUG_TESTS "ON") # Reconsider if we in a debug build. string( TOLOWER ${CMAKE_BUILD_TYPE} BUILD_TYPE_LOWERCASE ) if ( NOT BUILD_TYPE_LOWERCASE STREQUAL "release" ) message("CMAKE:: BUILD TYPE IS ${CMAKE_BUILD_TYPE}") # And NDK_VERSION has been set. if ( DEFINED NDK_VERSION ) message("CMAKE:: NDK DEFINED") # And the version is less than r21. if ( ${NDK_VERSION} STRLESS "r21" ) message("CMAKE:: BUG TESTS OFF") set(INCLUDE_NDK_BUG_TESTS "OFF") endif() endif() endif() if ( INCLUDE_NDK_BUG_TESTS STREQUAL "ON" ) list(APPEND commonDelegate_unittest_sources test/NeonDelegateTests_NDK_Issue.cpp) endif() if (BUILD_CLASSIC_DELEGATE) set(classicDelegate_unittest_sources) list(APPEND classicDelegate_unittest_sources classic/src/test/ArmnnClassicDelegateTest.cpp classic/src/test/DelegateTestInterpreter.cpp test/DelegateOptionsTest.cpp test/DelegateOptionsTestHelper.hpp) add_executable(DelegateUnitTests ${commonDelegate_unittest_sources} ${classicDelegate_unittest_sources}) target_include_directories(DelegateUnitTests SYSTEM PRIVATE "${TF_LITE_SCHEMA_INCLUDE_PATH}") target_include_directories(DelegateUnitTests SYSTEM PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/common/src/test") target_include_directories(DelegateUnitTests PUBLIC ${PROJECT_SOURCE_DIR}) # Add half library from armnn third-party libraries target_link_libraries(DelegateUnitTests PRIVATE thirdparty_headers) target_link_libraries(DelegateUnitTests PRIVATE armnnDelegate) target_link_libraries(DelegateUnitTests PRIVATE Armnn::armnnUtils) target_link_libraries(DelegateUnitTests PRIVATE profiling_library_headers) endif() if (BUILD_OPAQUE_DELEGATE) set(opaqueDelegate_unittest_sources) list(APPEND opaqueDelegate_unittest_sources opaque/src/test/ArmnnOpaqueDelegateTest.cpp opaque/src/test/DelegateTestInterpreter.cpp) # Until all operators are supported, we have to add tests one by one above to opaqueDelegate_unittest_sources. # After we add can add commonDelegate_unittest_sources to the add_executable below. add_executable(OpaqueDelegateUnitTests ${opaqueDelegate_unittest_sources} ${commonDelegate_unittest_sources}) target_include_directories(OpaqueDelegateUnitTests SYSTEM PRIVATE "${TF_LITE_SCHEMA_INCLUDE_PATH}") target_include_directories(OpaqueDelegateUnitTests SYSTEM PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/common/src/test") target_include_directories(OpaqueDelegateUnitTests PUBLIC ${PROJECT_SOURCE_DIR}) # Add half library from armnn third-party libraries target_link_libraries(OpaqueDelegateUnitTests PRIVATE thirdparty_headers) target_link_libraries(OpaqueDelegateUnitTests PRIVATE armnnOpaqueDelegate) target_link_libraries(OpaqueDelegateUnitTests PRIVATE Armnn::armnnUtils) target_link_libraries(OpaqueDelegateUnitTests PRIVATE profiling_library_headers) endif() endif() if(BUILD_DELEGATE_JNI_INTERFACE AND BUILD_CLASSIC_DELEGATE) add_subdirectory(armnnDelegateJNI) endif() #################################################### ## Export targets if (BUILD_CLASSIC_DELEGATE) set(armnn_delegate_export_targets) list(APPEND armnn_delegate_export_targets armnnClassicDelegateObject armnnDelegate tflite_headers flatbuffer_headers profiling_library_headers thirdparty_headers) install( TARGETS ${armnn_delegate_export_targets} EXPORT armnn-delegate-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) ## Set export alias set_target_properties(armnnDelegate PROPERTIES EXPORT_NAME ArmnnDelegate) ## Export target scrips install( EXPORT armnn-delegate-targets FILE ArmnnDelegateTargets.cmake NAMESPACE ArmnnDelegate:: DESTINATION ${CMAKE_INSTALL_LIBDIR}) ## Create ArmnnDelegateConfig.cmake include(CMakePackageConfigHelpers) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}) message(STATUS "CMAKE_CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}" ) message(STATUS "CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}" ) SET(Armnn_DIR "${Armnn_DIR}") configure_package_config_file( ${CMAKE_CURRENT_LIST_DIR}/cmake/Modules/ArmnnDelegateConfig.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/ArmnnDelegateConfig.cmake INSTALL_DESTINATION ${INSTALL_CONFIGDIR} PATH_VARS Armnn_DIR) ## Install ArmNN Delegate config file install( FILES ${CMAKE_CURRENT_BINARY_DIR}/ArmnnDelegateConfig.cmake DESTINATION ${INSTALL_CONFIGDIR}) ## Export from build tree export( EXPORT armnn-delegate-targets FILE ${CMAKE_CURRENT_BINARY_DIR}/ArmnnDelegateTargets.cmake NAMESPACE ArmnnDelegate::) add_library(ArmnnDelegate::ArmnnDelegate ALIAS armnnDelegate) endif() #################################################### ## Export opaque delegate targets if(BUILD_OPAQUE_DELEGATE) set(armnn_opaque_delegate_export_targets) list(APPEND armnn_opaque_delegate_export_targets armnnOpaqueDelegateObject armnnOpaqueDelegate tflite_headers flatbuffer_headers profiling_library_headers thirdparty_headers) install( TARGETS armnnOpaqueDelegate EXPORT armnn-opaque-delegate-targets LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) ## Set export alias set_target_properties(armnnOpaqueDelegate PROPERTIES EXPORT_NAME ArmnnOpaqueDelegate) add_library(ArmnnDelegate::ArmnnOpaqueDelegate ALIAS armnnOpaqueDelegate) endif() ####################################################