968642b35d1218ae1c30bdfdcf847c7f7921e4ac
[platform/upstream/armnn.git] / cmake / GlobalConfig.cmake
1 #
2 # Copyright © 2020 Arm Ltd. All rights reserved.
3 # Copyright 2020 NXP
4 # SPDX-License-Identifier: MIT
5 #
6 option(BUILD_CAFFE_PARSER "Build Caffe parser" OFF)
7 option(BUILD_TF_PARSER "Build Tensorflow parser" OFF)
8 option(BUILD_ONNX_PARSER "Build Onnx parser" OFF)
9 option(BUILD_UNIT_TESTS "Build unit tests" ON)
10 option(BUILD_TESTS "Build test applications" OFF)
11 option(BUILD_FOR_COVERAGE "Use no optimization and output .gcno and .gcda files" OFF)
12 option(ARMCOMPUTENEON "Build with ARM Compute NEON support" OFF)
13 option(ARMCOMPUTECL "Build with ARM Compute OpenCL support" OFF)
14 option(ARMNNREF "Build with ArmNN reference support" ON)
15 option(PROFILING_BACKEND_STREAMLINE "Forward the armNN profiling events to DS-5/Streamline as annotations" OFF)
16 # options used for heap profiling and leak checking
17 option(HEAP_PROFILING "Build with heap profiling enabled" OFF)
18 option(LEAK_CHECKING "Build with leak checking enabled" OFF)
19 option(GPERFTOOLS_ROOT "Location where the gperftools 'include' and 'lib' folders to be found" Off)
20 # options used for tensorflow lite support
21 option(BUILD_TF_LITE_PARSER "Build Tensorflow Lite parser" OFF)
22 option(BUILD_ARMNN_SERIALIZER "Build Armnn Serializer" OFF)
23 option(BUILD_ARMNN_QUANTIZER "Build ArmNN quantizer" OFF)
24 option(BUILD_ACCURACY_TOOL "Build Accuracy Tool" OFF)
25 option(FLATC_DIR "Path to Flatbuffers compiler" OFF)
26 option(TF_LITE_GENERATED_PATH "Tensorflow lite generated C++ schema location" OFF)
27 option(FLATBUFFERS_ROOT "Location where the flatbuffers 'include' and 'lib' folders to be found" Off)
28 option(DYNAMIC_BACKEND_PATHS "Colon seperated list of paths where to load the dynamic backends from" "")
29 option(BUILD_GATORD_MOCK "Build the Gatord simulator for external profiling testing." ON)
30 option(BUILD_TIMELINE_DECODER "Build the Timeline Decoder for external profiling." ON)
31 option(SHARED_BOOST "Use dynamic linking for boost libraries" OFF)
32 option(BUILD_BASE_PIPE_SERVER "Build the server to handle external profiling pipe traffic" ON)
33 option(BUILD_PYTHON_WHL "Build Python wheel package" OFF)
34 option(BUILD_PYTHON_SRC "Build Python source package" OFF)
35
36 include(SelectLibraryConfigurations)
37
38 set(COMPILER_IS_GNU_LIKE 0)
39 if(${CMAKE_CXX_COMPILER_ID} STREQUAL GNU OR ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang)
40     set(COMPILER_IS_GNU_LIKE 1)
41 endif()
42
43 # Enable CCache if available and not disabled
44 option(USE_CCACHE "USE_CCACHE" ON)
45 find_program(CCACHE_FOUND ccache)
46 if(CCACHE_FOUND AND USE_CCACHE)
47     get_property(rule_launch_compile DIRECTORY PROPERTY RULE_LAUNCH_COMPILE)
48     set_property(DIRECTORY PROPERTY RULE_LAUNCH_COMPILE "CCACHE_CPP2=yes ${rule_launch_compile} ccache")
49 endif()
50
51 # Enable distcc if available and not disabled
52 option(USE_DISTCC "USE_DISTCC" OFF)
53 find_program(DISTCC_FOUND distcc)
54 if(DISTCC_FOUND AND USE_DISTCC)
55     get_property(rule_launch_compile DIRECTORY PROPERTY RULE_LAUNCH_COMPILE)
56     set_property(DIRECTORY PROPERTY RULE_LAUNCH_COMPILE "${rule_launch_compile} distcc")
57 endif()
58
59 # Set to release configuration by default
60 if(NOT CMAKE_BUILD_TYPE)
61     set(CMAKE_BUILD_TYPE "Release")
62 endif()
63
64 # Compiler flags that are always set
65 set(CMAKE_POSITION_INDEPENDENT_CODE ON)
66 if(COMPILER_IS_GNU_LIKE)
67     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -Wall -Wextra -Werror -Wold-style-cast -Wno-missing-braces -Wconversion -Wsign-conversion")
68 elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
69         # Disable C4996 (use of deprecated identifier) due to https://developercommunity.visualstudio.com/content/problem/252574/deprecated-compilation-warning-for-virtual-overrid.html
70     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /MP /wd4996")
71     add_definitions(-DNOMINMAX=1 -DNO_STRICT=1)
72 endif()
73 if("${CMAKE_SYSTEM_NAME}" STREQUAL Android)
74     set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -llog")
75     set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -llog")
76 endif()
77
78 # Compiler flags for Release builds
79 set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -DNDEBUG")
80 if(COMPILER_IS_GNU_LIKE)
81     set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
82 elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
83     set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /O2")
84 endif()
85
86 # Compiler flags for Debug builds
87 if(COMPILER_IS_GNU_LIKE)
88     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -g -O0")
89 elseif(${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
90     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd /ZI /Od")
91     # Disable SAFESEH which is necessary for Edit and Continue to work
92     set(CMAKE_EXE_LINKER_FLAGS_DEBUG  "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
93     set(CMAKE_SHARED_LINKER_FLAGS_DEBUG  "${CMAKE_EXE_LINKER_FLAGS_DEBUG} /SAFESEH:NO")
94 endif()
95
96 # Modify RelWithDebInfo so that NDEBUG isn't defined.
97 # This enables asserts.
98 if (COMPILER_IS_GNU_LIKE)
99     string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
100 elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL MSVC)
101     string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
102 endif()
103
104 # Compiler flags for code coverage measurements
105 if(BUILD_FOR_COVERAGE)
106     if(NOT CMAKE_BUILD_TYPE EQUAL "Debug")
107         message(WARNING "BUILD_FOR_COVERAGE set so forcing to Debug build")
108         set(CMAKE_BUILD_TYPE "Debug")
109     endif()
110
111     set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} --coverage")
112     set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage")
113 endif()
114
115 if(BUILD_FOR_COVERAGE AND NOT BUILD_UNIT_TESTS)
116     message(WARNING "BUILD_FOR_COVERAGE set but not BUILD_UNIT_TESTS, so code coverage will not be able to run")
117 endif()
118
119 set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules ${CMAKE_MODULE_PATH})
120
121 # Boost
122 if(SHARED_BOOST)
123     add_definitions(-DBOOST_ALL_DYN_LINK)
124     set(Boost_USE_STATIC_LIBS OFF)
125 else()
126     set(Boost_USE_STATIC_LIBS ON)
127 endif()
128 add_definitions("-DBOOST_ALL_NO_LIB") # Turn off auto-linking as we specify the libs manually
129 find_package(Boost 1.59 REQUIRED COMPONENTS unit_test_framework system filesystem program_options)
130 include_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
131 link_directories(${Boost_LIBRARY_DIRS})
132
133 # pthread
134 find_package (Threads)
135
136 # Favour the protobuf passed on command line
137 if(BUILD_TF_PARSER OR BUILD_CAFFE_PARSER OR BUILD_ONNX_PARSER)
138     find_library(PROTOBUF_LIBRARY_DEBUG NAMES "protobufd"
139         PATHS ${PROTOBUF_ROOT}/lib
140         NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
141     find_library(PROTOBUF_LIBRARY_DEBUG NAMES "protobufd")
142
143     find_library(PROTOBUF_LIBRARY_RELEASE NAMES "protobuf"
144         PATHS ${PROTOBUF_ROOT}/lib
145         NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
146     find_library(PROTOBUF_LIBRARY_RELEASE NAMES "protobuf")
147
148     select_library_configurations(PROTOBUF)
149
150     find_path(PROTOBUF_INCLUDE_DIRS "google/protobuf/message.h"
151               PATHS ${PROTOBUF_ROOT}/include
152               NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
153     find_path(PROTOBUF_INCLUDE_DIRS "google/protobuf/message.h")
154
155     include_directories(SYSTEM "${PROTOBUF_INCLUDE_DIRS}")
156     add_definitions(-DPROTOBUF_USE_DLLS)
157 endif()
158
159 # Caffe and its dependencies
160 if(BUILD_CAFFE_PARSER)
161     add_definitions(-DARMNN_CAFFE_PARSER)
162
163     find_path(CAFFE_GENERATED_SOURCES "caffe/proto/caffe.pb.h"
164         HINTS ${CAFFE_BUILD_ROOT}/include)
165     include_directories(SYSTEM "${CAFFE_GENERATED_SOURCES}")
166 endif()
167
168 if(BUILD_TF_PARSER)
169     add_definitions(-DARMNN_TF_PARSER)
170
171     find_path(TF_GENERATED_SOURCES "tensorflow/core/protobuf/saved_model.pb.cc")
172
173     # C++ sources generated for tf protobufs
174     file(GLOB_RECURSE TF_PROTOBUFS "${TF_GENERATED_SOURCES}/*.pb.cc")
175
176     # C++ headers generated for tf protobufs
177     include_directories(SYSTEM "${TF_GENERATED_SOURCES}")
178 endif()
179
180 if(BUILD_ONNX_PARSER)
181     add_definitions(-DARMNN_ONNX_PARSER)
182
183     find_path(ONNX_GENERATED_SOURCES "onnx/onnx.pb.cc")
184
185     # C++ headers generated for onnx protobufs
186     include_directories(SYSTEM "${ONNX_GENERATED_SOURCES}")
187 endif()
188
189 # Flatbuffers support for TF Lite and Armnn Serializer
190 if(BUILD_TF_LITE_PARSER OR BUILD_ARMNN_SERIALIZER)
191     # verify we have a valid flatbuffers include path
192     find_path(FLATBUFFERS_INCLUDE_PATH flatbuffers/flatbuffers.h
193               HINTS ${FLATBUFFERS_ROOT}/include /usr/local/include /usr/include)
194
195     message(STATUS "Flatbuffers headers are located at: ${FLATBUFFERS_INCLUDE_PATH}")
196
197     find_library(FLATBUFFERS_LIBRARY
198                  NAMES libflatbuffers.a flatbuffers
199                  HINTS ${FLATBUFFERS_ROOT}/lib /usr/local/lib /usr/lib)
200
201     message(STATUS "Flatbuffers library located at: ${FLATBUFFERS_LIBRARY}")
202 endif()
203
204 # Flatbuffers schema support for TF Lite
205 if(BUILD_TF_LITE_PARSER)
206     find_path(TF_LITE_SCHEMA_INCLUDE_PATH
207               schema_generated.h
208               HINTS ${TF_LITE_GENERATED_PATH})
209
210     message(STATUS "Tf Lite generated header found at: ${TF_LITE_SCHEMA_INCLUDE_PATH}")
211
212     add_definitions(-DARMNN_TF_LITE_PARSER)
213 endif()
214
215 if(BUILD_ARMNN_SERIALIZER)
216     add_definitions(-DARMNN_SERIALIZER)
217     add_definitions(-DARMNN_SERIALIZER_SCHEMA_PATH="${CMAKE_CURRENT_SOURCE_DIR}/src/armnnSerializer/ArmnnSchema.fbs")
218 endif()
219
220 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)
221 include_directories(${CMAKE_CURRENT_SOURCE_DIR}/profiling)
222
223 # ARM Compute
224 # Note that ARM Compute has a different folder layout depending on the branch but also on
225 # whether it comes from a prepackaged archive (this is why we add several hints below)
226 if(ARMCOMPUTENEON OR ARMCOMPUTECL)
227     find_path(ARMCOMPUTE_INCLUDE arm_compute/core/CL/ICLKernel.h
228               PATHS ${ARMCOMPUTE_ROOT}/include
229               PATHS ${ARMCOMPUTE_ROOT}/applications/arm_compute
230               PATHS ${ARMCOMPUTE_ROOT}
231               NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
232     find_path(ARMCOMPUTE_INCLUDE arm_compute/core/CL/ICLKernel.h)
233     include_directories(SYSTEM "${ARMCOMPUTE_INCLUDE}")
234
235     # Find the Arm Compute libraries if not already specified (the user may have already defined this in advance,
236     # e.g. if building clframework as a dependent cmake project)
237     if (NOT DEFINED ARMCOMPUTE_LIBRARIES)
238         # We link to the static variant so that customers don't need to find and build a compatible version of clframework.
239         # First try the folders specified ARMCOMPUTE_BUILD_DIR (with PATH_SUFFIXES for
240         # Windows builds)
241         find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute-static
242                      PATHS ${ARMCOMPUTE_BUILD_DIR}
243                      PATH_SUFFIXES "Debug"
244                      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
245         find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute-static
246                      PATHS ${ARMCOMPUTE_BUILD_DIR}
247                      PATH_SUFFIXES "Release"
248                      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
249         find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core-static
250                      PATHS ${ARMCOMPUTE_BUILD_DIR}
251                      PATH_SUFFIXES "Debug"
252                      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
253         find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core-static
254                      PATHS ${ARMCOMPUTE_BUILD_DIR}
255                      PATH_SUFFIXES "Release"
256                      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
257
258         # In case it wasn't there, try a default search (will work in cases where
259         # the library has been installed into a standard location)
260         find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute-static)
261         find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute-static)
262         find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core-static)
263         find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core-static)
264
265         # In case it wasn't there, try the dynamic libraries
266         # This case will get used in a linux setup where the Compute Library
267         # has been installed in a standard system library path as a dynamic library
268         find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute)
269         find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute)
270         find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core)
271         find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core)
272
273         set(ARMCOMPUTE_LIBRARIES
274             debug ${ARMCOMPUTE_LIBRARY_DEBUG} ${ARMCOMPUTE_CORE_LIBRARY_DEBUG}
275             optimized ${ARMCOMPUTE_LIBRARY_RELEASE} ${ARMCOMPUTE_CORE_LIBRARY_RELEASE} )
276     endif()
277 endif()
278
279 # ARM Compute NEON backend
280 if(ARMCOMPUTENEON)
281     # Add preprocessor definition for ARM Compute NEON
282     add_definitions(-DARMCOMPUTENEON_ENABLED)
283     # The ARM Compute headers contain some NEON intrinsics, so we need to build armnn with NEON support on armv7
284     if(${CMAKE_SYSTEM_PROCESSOR} MATCHES armv7 AND COMPILER_IS_GNU_LIKE)
285         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon")
286     endif()
287 endif()
288
289 # ARM Compute OpenCL backend
290 if(ARMCOMPUTECL)
291     # Always use Arm compute library OpenCL headers
292     find_path(OPENCL_INCLUDE CL/cl2.hpp
293               PATHS ${ARMCOMPUTE_ROOT}/include
294               NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
295
296     # Link against libOpenCL in opencl-1.2-stubs, but don't search there at runtime
297     link_libraries(-L${ARMCOMPUTE_BUILD_DIR}/opencl-1.2-stubs)
298     set(OPENCL_LIBRARIES OpenCL)
299
300     include_directories(SYSTEM ${OPENCL_INCLUDE})
301
302     # Add preprocessor definition for ARM Compute OpenCL
303     add_definitions(-DARMCOMPUTECL_ENABLED)
304
305     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DARM_COMPUTE_DEBUG_ENABLED")
306 endif()
307
308 # Used by both Arm Compute backends, but should be added
309 # to the search path after the system directories if necessary
310 if(ARMCOMPUTENEON OR ARMCOMPUTECL)
311     find_path(HALF_INCLUDE half/half.hpp)
312     find_path(HALF_INCLUDE half/half.hpp
313               PATHS ${ARMCOMPUTE_ROOT}/include
314               NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
315     include_directories(SYSTEM ${HALF_INCLUDE})
316 endif()
317
318 # ArmNN reference backend
319 if(ARMNNREF)
320     add_definitions(-DARMNNREF_ENABLED)
321 endif()
322
323 # ArmNN dynamic backend
324 if(DYNAMIC_BACKEND_PATHS)
325     add_definitions(-DARMNN_DYNAMIC_BACKEND_ENABLED)
326 endif()
327
328 if(SAMPLE_DYNAMIC_BACKEND)
329     add_definitions(-DSAMPLE_DYNAMIC_BACKEND_ENABLED)
330 endif()
331
332 # Streamline annotate
333 if(PROFILING_BACKEND_STREAMLINE)
334     include_directories("${GATOR_ROOT}/annotate")
335     add_definitions(-DARMNN_STREAMLINE_ENABLED)
336 endif()
337
338 if(HEAP_PROFILING OR LEAK_CHECKING)
339     # enable heap profiling for everything except for referencetests
340     if(NOT ${PROJECT_NAME} STREQUAL "referencetests")
341         find_path(HEAP_PROFILER_INCLUDE gperftools/heap-profiler.h
342                 PATHS ${GPERFTOOLS_ROOT}/include
343                 NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
344         include_directories(SYSTEM "${HEAP_PROFILER_INCLUDE}")
345         find_library(GPERF_TOOLS_LIBRARY
346                     NAMES tcmalloc_debug
347                     HINTS ${GPERFTOOLS_ROOT}/lib)
348         link_directories(${GPERFTOOLS_ROOT}/lib)
349
350         link_libraries(${GPERF_TOOLS_LIBRARY})
351         if (HEAP_PROFILING)
352             add_definitions("-DARMNN_HEAP_PROFILING_ENABLED=1")
353         endif()
354         if (LEAK_CHECKING)
355             add_definitions("-DARMNN_LEAK_CHECKING_ENABLED=1")
356         endif()
357     else()
358         message(STATUS "Heap profiling and leak checking are disabled for referencetests")
359     endif()
360 else()
361     # Valgrind only works with gperftools version number <= 2.4
362     CHECK_INCLUDE_FILE(valgrind/memcheck.h VALGRIND_FOUND)
363 endif()
364
365
366 if(NOT BUILD_CAFFE_PARSER)
367     message(STATUS "Caffe parser support is disabled")
368 endif()
369
370 if(NOT BUILD_TF_PARSER)
371     message(STATUS "Tensorflow parser support is disabled")
372 endif()
373
374 if(NOT BUILD_TF_LITE_PARSER)
375     message(STATUS "Tensorflow Lite parser support is disabled")
376 endif()
377
378 if(NOT BUILD_ARMNN_SERIALIZER)
379     message(STATUS "Armnn Serializer support is disabled")
380 endif()
381
382 if(NOT BUILD_ARMNN_QUANTIZER)
383     message(STATUS "ArmNN Quantizer support is disabled")
384 endif()
385
386 if(NOT BUILD_PYTHON_WHL)
387     message(STATUS "PyArmNN wheel package is disabled")
388 endif()
389
390 if(NOT BUILD_PYTHON_SRC)
391     message(STATUS "PyArmNN source package is disabled")
392 endif()
393
394 if(BUILD_PYTHON_WHL OR BUILD_PYTHON_SRC)
395     find_package(PythonInterp 3 REQUIRED)
396     if(NOT ${PYTHONINTERP_FOUND})
397         message(FATAL_ERROR "Python 3.x required to build PyArmNN, but not found")
398     endif()
399
400     find_package(PythonLibs 3 REQUIRED)
401     if(NOT ${PYTHONLIBS_FOUND})
402         message(FATAL_ERROR "Python 3.x development package required to build PyArmNN, but not found")
403     endif()
404
405     find_package(SWIG 4 REQUIRED)
406     if(NOT ${SWIG_FOUND})
407         message(FATAL_ERROR "SWIG 4.x requried to build PyArmNN, but not found")
408     endif()
409 endif()
410
411 # ArmNN source files required for all build options
412 include_directories(SYSTEM third-party)