Find default build location for Compute Library binaries.
[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         if ((NOT DEFINED ARMCOMPUTE_BUILD_DIR) AND (DEFINED ARMCOMPUTE_ROOT))
242             # Default build directory for ComputeLibrary is under the root
243             set(ARMCOMPUTE_BUILD_DIR ${ARMCOMPUTE_ROOT}/build)
244         endif()
245
246         find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute-static
247                      PATHS ${ARMCOMPUTE_BUILD_DIR}
248                      PATH_SUFFIXES "Debug"
249                      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
250         find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute-static
251                      PATHS ${ARMCOMPUTE_BUILD_DIR}
252                      PATH_SUFFIXES "Release"
253                      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
254         find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core-static
255                      PATHS ${ARMCOMPUTE_BUILD_DIR}
256                      PATH_SUFFIXES "Debug"
257                      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
258         find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core-static
259                      PATHS ${ARMCOMPUTE_BUILD_DIR}
260                      PATH_SUFFIXES "Release"
261                      NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
262
263         # In case it wasn't there, try a default search (will work in cases where
264         # the library has been installed into a standard location)
265         find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute-static)
266         find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute-static)
267         find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core-static)
268         find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core-static)
269
270         # In case it wasn't there, try the dynamic libraries
271         # This case will get used in a linux setup where the Compute Library
272         # has been installed in a standard system library path as a dynamic library
273         find_library(ARMCOMPUTE_LIBRARY_DEBUG NAMES arm_compute)
274         find_library(ARMCOMPUTE_LIBRARY_RELEASE NAMES arm_compute)
275         find_library(ARMCOMPUTE_CORE_LIBRARY_DEBUG NAMES arm_compute_core)
276         find_library(ARMCOMPUTE_CORE_LIBRARY_RELEASE NAMES arm_compute_core)
277
278         set(ARMCOMPUTE_LIBRARIES
279             debug ${ARMCOMPUTE_LIBRARY_DEBUG} ${ARMCOMPUTE_CORE_LIBRARY_DEBUG}
280             optimized ${ARMCOMPUTE_LIBRARY_RELEASE} ${ARMCOMPUTE_CORE_LIBRARY_RELEASE} )
281     endif()
282 endif()
283
284 # ARM Compute NEON backend
285 if(ARMCOMPUTENEON)
286     # Add preprocessor definition for ARM Compute NEON
287     add_definitions(-DARMCOMPUTENEON_ENABLED)
288     # The ARM Compute headers contain some NEON intrinsics, so we need to build armnn with NEON support on armv7
289     if(${CMAKE_SYSTEM_PROCESSOR} MATCHES armv7 AND COMPILER_IS_GNU_LIKE)
290         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mfpu=neon")
291     endif()
292 endif()
293
294 # ARM Compute OpenCL backend
295 if(ARMCOMPUTECL)
296     # Always use Arm compute library OpenCL headers
297     find_path(OPENCL_INCLUDE CL/cl2.hpp
298               PATHS ${ARMCOMPUTE_ROOT}/include
299               NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
300
301     # Link against libOpenCL in opencl-1.2-stubs, but don't search there at runtime
302     link_libraries(-L${ARMCOMPUTE_BUILD_DIR}/opencl-1.2-stubs)
303     set(OPENCL_LIBRARIES OpenCL)
304
305     include_directories(SYSTEM ${OPENCL_INCLUDE})
306
307     # Add preprocessor definition for ARM Compute OpenCL
308     add_definitions(-DARMCOMPUTECL_ENABLED)
309
310     set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -DARM_COMPUTE_DEBUG_ENABLED")
311 endif()
312
313 # Used by both Arm Compute backends, but should be added
314 # to the search path after the system directories if necessary
315 if(ARMCOMPUTENEON OR ARMCOMPUTECL)
316     find_path(HALF_INCLUDE half/half.hpp)
317     find_path(HALF_INCLUDE half/half.hpp
318               PATHS ${ARMCOMPUTE_ROOT}/include
319               NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
320     include_directories(SYSTEM ${HALF_INCLUDE})
321 endif()
322
323 # ArmNN reference backend
324 if(ARMNNREF)
325     add_definitions(-DARMNNREF_ENABLED)
326 endif()
327
328 # ArmNN dynamic backend
329 if(DYNAMIC_BACKEND_PATHS)
330     add_definitions(-DARMNN_DYNAMIC_BACKEND_ENABLED)
331 endif()
332
333 if(SAMPLE_DYNAMIC_BACKEND)
334     add_definitions(-DSAMPLE_DYNAMIC_BACKEND_ENABLED)
335 endif()
336
337 # Streamline annotate
338 if(PROFILING_BACKEND_STREAMLINE)
339     include_directories("${GATOR_ROOT}/annotate")
340     add_definitions(-DARMNN_STREAMLINE_ENABLED)
341 endif()
342
343 if(HEAP_PROFILING OR LEAK_CHECKING)
344     # enable heap profiling for everything except for referencetests
345     if(NOT ${PROJECT_NAME} STREQUAL "referencetests")
346         find_path(HEAP_PROFILER_INCLUDE gperftools/heap-profiler.h
347                 PATHS ${GPERFTOOLS_ROOT}/include
348                 NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
349         include_directories(SYSTEM "${HEAP_PROFILER_INCLUDE}")
350         find_library(GPERF_TOOLS_LIBRARY
351                     NAMES tcmalloc_debug
352                     HINTS ${GPERFTOOLS_ROOT}/lib)
353         link_directories(${GPERFTOOLS_ROOT}/lib)
354
355         link_libraries(${GPERF_TOOLS_LIBRARY})
356         if (HEAP_PROFILING)
357             add_definitions("-DARMNN_HEAP_PROFILING_ENABLED=1")
358         endif()
359         if (LEAK_CHECKING)
360             add_definitions("-DARMNN_LEAK_CHECKING_ENABLED=1")
361         endif()
362     else()
363         message(STATUS "Heap profiling and leak checking are disabled for referencetests")
364     endif()
365 else()
366     # Valgrind only works with gperftools version number <= 2.4
367     CHECK_INCLUDE_FILE(valgrind/memcheck.h VALGRIND_FOUND)
368 endif()
369
370
371 if(NOT BUILD_CAFFE_PARSER)
372     message(STATUS "Caffe parser support is disabled")
373 endif()
374
375 if(NOT BUILD_TF_PARSER)
376     message(STATUS "Tensorflow parser support is disabled")
377 endif()
378
379 if(NOT BUILD_TF_LITE_PARSER)
380     message(STATUS "Tensorflow Lite parser support is disabled")
381 endif()
382
383 if(NOT BUILD_ARMNN_SERIALIZER)
384     message(STATUS "Armnn Serializer support is disabled")
385 endif()
386
387 if(NOT BUILD_ARMNN_QUANTIZER)
388     message(STATUS "ArmNN Quantizer support is disabled")
389 endif()
390
391 if(NOT BUILD_PYTHON_WHL)
392     message(STATUS "PyArmNN wheel package is disabled")
393 endif()
394
395 if(NOT BUILD_PYTHON_SRC)
396     message(STATUS "PyArmNN source package is disabled")
397 endif()
398
399 if(BUILD_PYTHON_WHL OR BUILD_PYTHON_SRC)
400     find_package(PythonInterp 3 REQUIRED)
401     if(NOT ${PYTHONINTERP_FOUND})
402         message(FATAL_ERROR "Python 3.x required to build PyArmNN, but not found")
403     endif()
404
405     find_package(PythonLibs 3 REQUIRED)
406     if(NOT ${PYTHONLIBS_FOUND})
407         message(FATAL_ERROR "Python 3.x development package required to build PyArmNN, but not found")
408     endif()
409
410     find_package(SWIG 4 REQUIRED)
411     if(NOT ${SWIG_FOUND})
412         message(FATAL_ERROR "SWIG 4.x requried to build PyArmNN, but not found")
413     endif()
414 endif()
415
416 # ArmNN source files required for all build options
417 include_directories(SYSTEM third-party)