summaryrefslogtreecommitdiff
path: root/scripts/cmake/util_functions.cmake
blob: 9aa19b93ea758a3dc91e9fcc1f0828cf798b7c81 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#----------------------------------------------------------------------------
#  Copyright (c) 2021-2022 Arm Limited. All rights reserved.
#  SPDX-License-Identifier: Apache-2.0
#
#  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
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
#  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.
#----------------------------------------------------------------------------

##############################################################################
# Helper function to provide user option and corresponding default value
##############################################################################
function(USER_OPTION name description default type)

    if (${type} STREQUAL PATH_OR_FILE)

        if (DEFINED ${name})
            get_filename_component(ABSPATH "${${name}}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})

            get_path_type(${${name}} PATH_TYPE)
        else()
            get_filename_component(ABSPATH "${default}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})

            get_path_type(${default} PATH_TYPE)
        endif()

        if (NOT EXISTS ${ABSPATH})
            message(FATAL_ERROR
                    "Invalid directory or file path. Description: ${description}; Path: ${ABSPATH}")
        endif()

        # Set the default type if path is not a dir or file path (or undefined)
        if (NOT ${PATH_TYPE} STREQUAL PATH AND NOT ${PATH_TYPE} STREQUAL FILEPATH)
            message(FATAL_ERROR "Invalid ${name}. It should be a dir or file path.")
        endif()
        set(type ${PATH_TYPE})
    endif()

    if (NOT DEFINED ${name})
        set(${name} ${default} CACHE ${type} ${description})
    endif()

    # if it is a path
    if (${type} STREQUAL PATH)

        # Get the absolute path, relative to the cmake root
        get_filename_component(ABSPATH "${${name}}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})

        # check that this is a directory
        if (NOT IS_DIRECTORY ${ABSPATH})
            message(FATAL_ERROR
                "Invalid directory path. Description: ${description}; Path: ${ABSPATH}")
        endif()

        set(${name} ${ABSPATH} CACHE ${type} ${description} FORCE)

    # if this is a file path
    elseif(${type} STREQUAL FILEPATH)

        # Get the absolute path, relative to the cmake root
        get_filename_component(ABSPATH "${${name}}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})

        # check that the file exists:
        if (NOT EXISTS ${ABSPATH})
            message(FATAL_ERROR
                "Invalid file path. Description: ${description}; Path: ${ABSPATH}")
        endif()

        set(${name} ${ABSPATH} CACHE ${type} ${description} FORCE)

    endif()

    message(STATUS "User option ${name} is set to ${${name}}")
    LIST(APPEND USER_OPTIONS ${name})
    set(USER_OPTIONS ${USER_OPTIONS} CACHE INTERNAL "")

endfunction()


# Function to check if a variable is defined, and throw
# an error if it is not.
function(assert_defined var_name)
    if (NOT DEFINED ${var_name})
        message(FATAL_ERROR "ERROR: ${var_name} is undefined!")
    endif()
endfunction()

# Function to get the path type for a variable
# Args:
#   path_var[in]:           path variable for which the cmake path type is requested
#   cmake_path_type[out]:   CMake path type. Set to FILEPATH when it is a file
#                           or PATH when it points to a directory. If the path
#                           is invalid, this remains empty.
function(get_path_type path_var cmake_path_type)
    # Validate path - get absolute value
    get_filename_component(ABSPATH "${path_var}" ABSOLUTE
                           BASE_DIR ${CMAKE_SOURCE_DIR})

    if (DEFINED path_var)
        if (IS_DIRECTORY ${ABSPATH})
            set(${cmake_path_type} PATH PARENT_SCOPE)
            message(STATUS "Variable of PATH type")
        elseif(EXISTS ${ABSPATH})
            set(${cmake_path_type} FILEPATH PARENT_SCOPE)
        else()
            set(${cmake_path_type} "" PARENT_SCOPE)
        endif()
    else()
        set(${cmake_path_type} UNINITIALIZED PARENT_SCOPE)
    endif()

endfunction()

# Function to print all the user options added using the function `USER_OPTION`
function(print_useroptions)
    message(STATUS "--------------------------------------------------------------------------------------------------")
    message(STATUS "Defined build user options:")
    message(STATUS "")
    foreach(opt ${USER_OPTIONS})
        message(STATUS "    ${opt}=${${opt}}")
    endforeach()
    message(STATUS "--------------------------------------------------------------------------------------------------")
endfunction()

function (SUBDIRLIST result curdir)
    file(GLOB children RELATIVE ${curdir} ${curdir}/*)
    set(dirlist "")
    foreach(child ${children})
        if(IS_DIRECTORY ${curdir}/${child})
            LIST(APPEND dirlist ${child})
        endif()
    endforeach()
    set(${result} ${dirlist} PARENT_SCOPE)
endfunction()

function(to_py_bool cmake_bool py_bool)
    if(${${cmake_bool}})
        set(${py_bool} True PARENT_SCOPE)
    else()
        set(${py_bool} False PARENT_SCOPE)
    endif()
endfunction()

# Function to download a files from the Arm Model Zoo
# Arguments:
#   model_zoo_version: hash of the Arm Model Zoo commit to use
#   file_sub_path: subpath within the model zoo repository
#   download_path: location where this file is to be downloaded (path including filename)
function(download_file_from_modelzoo model_zoo_version file_sub_path download_path)

    set(MODEL_ZOO_REPO "https://github.com/ARM-software/ML-zoo/raw")

    string(JOIN "/" FILE_URL
        ${MODEL_ZOO_REPO} ${model_zoo_version} ${file_sub_path})

    message(STATUS "Downloading ${FILE_URL} to ${download_path}...")

    file(DOWNLOAD ${FILE_URL} ${download_path}
        STATUS DOWNLOAD_STATE)
    list(GET DOWNLOAD_STATE 0 RET_VAL)

    if(${RET_VAL})
        list(GET DOWNLOAD_STATE 1 RET_MSG)
        message(FATAL_ERROR "Download failed with error code: ${RET_VAL}; "
                            "Error message: ${RET_MSG}")
    endif()

endfunction()

function(add_platform_build_configuration)

    set(oneValueArgs TARGET_PLATFORM)
    cmake_parse_arguments(PARSED "" "${oneValueArgs}" "" ${ARGN} )
    message(STATUS "Searching for ${PARSED_TARGET_PLATFORM} build configuration")
    list(APPEND PLATFORM_BUILD_CONFIG_DIRS ${CMAKE_SCRIPTS_DIR}/platforms)

    FIND_PATH(PLATFORM_BUILD_CONFIG
            NAMES build_configuration.cmake
            PATH_SUFFIXES ${PARSED_TARGET_PLATFORM}
            PATHS ${PLATFORM_BUILD_CONFIG_DIRS}
            )

    message(STATUS "Found build configuration: ${PLATFORM_BUILD_CONFIG}")
    include(${PLATFORM_BUILD_CONFIG}/build_configuration.cmake)
endfunction()

function(check_update_public_resources resource_downloaded_dir)

    string(JOIN "/" FILE_URL ${resource_downloaded_dir})
    execute_process(
            COMMAND python3 ${SCRIPTS_DIR}/py/check_update_resources_downloaded.py
            --resource_downloaded_dir ${resource_downloaded_dir}
            --setup_script_path ${SCRIPTS_DIR}/../set_up_default_resources.py
            RESULT_VARIABLE return_code
    )
    if (NOT return_code EQUAL "0")
        if (NOT return_code EQUAL "1")
            # Return code equal to 2 or else means an error in the resources_downloaded folder
            message(FATAL_ERROR "Resources downloaded error, please run: set_up_default_resources.py")
        else()
            # Return code equal to 1 means that resources_downloaded need to be updated
            message(FATAL_ERROR "Resources downloaded need to be updated, please run: set_up_default_resources.py --clean")
        endif()
    endif ()

endfunction()

function(set_input_file_path_user_option file_extension use_case)
    if(NOT USE_SINGLE_INPUT)
        USER_OPTION(${use_case}_FILE_PATH "Directory with custom input files, or path to a single input file, to use in the evaluation application."
                ${CMAKE_CURRENT_SOURCE_DIR}/resources/${use_case}/samples/
                PATH_OR_FILE)
    else()
        file(GLOB_RECURSE INPUTS ${CMAKE_CURRENT_SOURCE_DIR}/resources/${use_case}/samples/*${file_extension})
        list (GET INPUTS 0 FIRST_INPUT_FILE)
        USER_OPTION(${use_case}_FILE_PATH "Directory with custom input files, or path to a single input file, to use in the evaluation application."
                ${FIRST_INPUT_FILE}
                PATH_OR_FILE)
    endif()
endfunction()