blob: abdc29a380edcf76ba60a8beb4741b2c4528495b [file] [log] [blame]
Geoffrey Martin-Noble552d3f82021-05-25 17:56:09 -07001# Copyright 2019 The IREE Authors
Ben Vanik512d2d32019-09-20 13:22:34 -07002#
Geoffrey Martin-Noble552d3f82021-05-25 17:56:09 -07003# Licensed under the Apache License v2.0 with LLVM Exceptions.
4# See https://llvm.org/LICENSE.txt for license information.
5# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Ben Vanik512d2d32019-09-20 13:22:34 -07006
Ben Vanikcc2aff92019-09-24 10:23:55 -07007include(CMakeParseArguments)
8
9#-------------------------------------------------------------------------------
Ben Vanik57d5e2e2020-03-03 07:14:56 -080010# Missing CMake Variables
11#-------------------------------------------------------------------------------
12
13if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows")
14 set(IREE_HOST_SCRIPT_EXT "bat")
Lei Zhang5e888322020-06-29 16:17:39 -040015 # https://gitlab.kitware.com/cmake/cmake/-/issues/17553
16 set(IREE_HOST_EXECUTABLE_SUFFIX ".exe")
Ben Vanik57d5e2e2020-03-03 07:14:56 -080017else()
18 set(IREE_HOST_SCRIPT_EXT "sh")
Lei Zhang5e888322020-06-29 16:17:39 -040019 set(IREE_HOST_EXECUTABLE_SUFFIX "")
Ben Vanik57d5e2e2020-03-03 07:14:56 -080020endif()
21
22#-------------------------------------------------------------------------------
Lei Zhang7e8589a2020-06-10 16:42:49 -040023# General utilities
24#-------------------------------------------------------------------------------
25
26# iree_to_bool
27#
28# Sets `variable` to `ON` if `value` is true and `OFF` otherwise.
Lei Zhangd643f672020-06-16 10:56:41 -040029function(iree_to_bool VARIABLE VALUE)
30 if(VALUE)
31 set(${VARIABLE} "ON" PARENT_SCOPE)
Lei Zhang7e8589a2020-06-10 16:42:49 -040032 else()
Lei Zhangd643f672020-06-16 10:56:41 -040033 set(${VARIABLE} "OFF" PARENT_SCOPE)
Lei Zhang7e8589a2020-06-10 16:42:49 -040034 endif()
35endfunction()
36
Lei Zhangdd21f322020-09-10 10:47:33 -040037# iree_append_list_to_string
38#
39# Joins ${ARGN} together as a string separated by " " and appends it to
40# ${VARIABLE}.
41function(iree_append_list_to_string VARIABLE)
42 if(NOT "${ARGN}" STREQUAL "")
43 string(JOIN " " _ARGN_STR ${ARGN})
44 set(${VARIABLE} "${${VARIABLE}} ${_ARGN_STR}" PARENT_SCOPE)
45 endif()
46endfunction()
47
Lei Zhang7e8589a2020-06-10 16:42:49 -040048
49#-------------------------------------------------------------------------------
Ben Vanikcc2aff92019-09-24 10:23:55 -070050# Packages and Paths
51#-------------------------------------------------------------------------------
52
Ben Vanik512d2d32019-09-20 13:22:34 -070053# Sets ${PACKAGE_NS} to the IREE-root relative package name in C++ namespace
54# format (::).
55#
Scott Todd44f95f82022-06-01 09:59:32 -070056# Examples:
57# compiler/src/iree/compiler/Utils/CMakeLists.txt -> iree::compiler::Utils
58# runtime/src/iree/base/CMakeLists.txt -> iree::base
59# tests/e2e/CMakeLists.txt -> iree::tests::e2e
Ben Vanik512d2d32019-09-20 13:22:34 -070060function(iree_package_ns PACKAGE_NS)
Stella Laurenzo9bde61b2022-04-21 15:37:14 -070061 # Get the relative path of the current dir (i.e. runtime/src/iree/vm).
CindyLiu4f683bc2022-07-11 17:14:25 +000062 string(REPLACE ${IREE_ROOT_DIR} "" _IREE_RELATIVE_PATH ${CMAKE_CURRENT_LIST_DIR})
63 string(SUBSTRING ${_IREE_RELATIVE_PATH} 1 -1 _IREE_RELATIVE_PATH)
64
65 if(NOT ${CMAKE_CURRENT_LIST_DIR} MATCHES "^${IREE_ROOT_DIR}/.*")
66 # Function is being called from outside IREE. Use the source-relative path.
67 # Please check the README.md to see the potential risk.
68 string(REPLACE ${PROJECT_SOURCE_DIR} "" _SOURCE_RELATIVE_PATH ${CMAKE_CURRENT_LIST_DIR})
69 string(SUBSTRING ${_SOURCE_RELATIVE_PATH} 1 -1 _SOURCE_RELATIVE_PATH)
70 set(_PACKAGE "${_SOURCE_RELATIVE_PATH}")
Stella Laurenzo9bde61b2022-04-21 15:37:14 -070071
Stella Laurenzo1e8d1fa2022-04-22 09:50:43 -070072 # If changing the directory/package mapping rules, please also implement
73 # the corresponding rule in:
74 # build_tools/bazel_to_cmake/bazel_to_cmake_targets.py
Stella Laurenzo9bde61b2022-04-21 15:37:14 -070075 # Some sub-trees form their own roots for package purposes. Rewrite them.
CindyLiu4f683bc2022-07-11 17:14:25 +000076 elseif(_IREE_RELATIVE_PATH MATCHES "^compiler/src/(.*)")
Stella Laurenzo41a2ceb2022-04-29 12:49:36 -070077 # compiler/src/iree/compiler -> iree/compiler
78 set(_PACKAGE "${CMAKE_MATCH_1}")
CindyLiu4f683bc2022-07-11 17:14:25 +000079 elseif(_IREE_RELATIVE_PATH MATCHES "^runtime/src/(.*)")
Stella Laurenzo9bde61b2022-04-21 15:37:14 -070080 # runtime/src/iree/base -> iree/base
81 set(_PACKAGE "${CMAKE_MATCH_1}")
CindyLiu4f683bc2022-07-11 17:14:25 +000082 elseif(_IREE_RELATIVE_PATH MATCHES "^tools$")
Scott Todd44f95f82022-06-01 09:59:32 -070083 # Special case for tools/ -> "" (empty string)
84 # For example, tools/iree-compile -> iree-compile (no namespace)
Scott Toddf57ab752022-05-23 10:36:44 -070085 set(_PACKAGE "")
Stella Laurenzo9bde61b2022-04-21 15:37:14 -070086 else()
Scott Todd44f95f82022-06-01 09:59:32 -070087 # Default to prefixing with iree/
CindyLiu4f683bc2022-07-11 17:14:25 +000088 set(_PACKAGE "iree/${_IREE_RELATIVE_PATH}")
Stella Laurenzo9bde61b2022-04-21 15:37:14 -070089 endif()
90
Scott Toddf57ab752022-05-23 10:36:44 -070091 string(REPLACE "/" "::" _PACKAGE_NS "${_PACKAGE}")
Stella Laurenzo1e8d1fa2022-04-22 09:50:43 -070092
93 if(_DEBUG_IREE_PACKAGE_NAME)
CindyLiu4f683bc2022-07-11 17:14:25 +000094 message(STATUS "iree_package_ns(): map ${_IREE_RELATIVE_PATH} -> ${_PACKAGE_NS}")
Stella Laurenzo1e8d1fa2022-04-22 09:50:43 -070095 endif()
96
Ben Vanikcc2aff92019-09-24 10:23:55 -070097 set(${PACKAGE_NS} ${_PACKAGE_NS} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -070098endfunction()
99
100# Sets ${PACKAGE_NAME} to the IREE-root relative package name.
101#
102# Example when called from iree/base/CMakeLists.txt:
103# iree_base
104function(iree_package_name PACKAGE_NAME)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700105 iree_package_ns(_PACKAGE_NS)
Scott Toddf57ab752022-05-23 10:36:44 -0700106 string(REPLACE "::" "_" _PACKAGE_NAME "${_PACKAGE_NS}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700107 set(${PACKAGE_NAME} ${_PACKAGE_NAME} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -0700108endfunction()
109
110# Sets ${PACKAGE_PATH} to the IREE-root relative package path.
111#
112# Example when called from iree/base/CMakeLists.txt:
113# iree/base
114function(iree_package_path PACKAGE_PATH)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700115 iree_package_ns(_PACKAGE_NS)
116 string(REPLACE "::" "/" _PACKAGE_PATH ${_PACKAGE_NS})
117 set(${PACKAGE_PATH} ${_PACKAGE_PATH} PARENT_SCOPE)
118endfunction()
119
120# Sets ${PACKAGE_DIR} to the directory name of the current package.
121#
122# Example when called from iree/base/CMakeLists.txt:
123# base
124function(iree_package_dir PACKAGE_DIR)
125 iree_package_ns(_PACKAGE_NS)
Scott Toddf57ab752022-05-23 10:36:44 -0700126 string(FIND "${_PACKAGE_NS}" "::" _END_OFFSET REVERSE)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700127 math(EXPR _END_OFFSET "${_END_OFFSET} + 2")
128 string(SUBSTRING ${_PACKAGE_NS} ${_END_OFFSET} -1 _PACKAGE_DIR)
129 set(${PACKAGE_DIR} ${_PACKAGE_DIR} PARENT_SCOPE)
130endfunction()
131
Lei Zhang1ff70612020-06-04 10:12:41 -0400132# iree_get_executable_path
133#
Lei Zhange71d9732020-06-23 10:21:09 -0400134# Gets the path to an executable in a cross-compilation-aware way. This
135# should be used when accessing binaries that are used as part of the build,
Scott Toddd5beb622021-03-01 11:44:15 -0800136# such as for generating files used for later build steps.
Lei Zhang1ff70612020-06-04 10:12:41 -0400137#
138# Paramters:
Lei Zhang486e7072020-06-16 11:42:49 -0400139# - OUTPUT_PATH_VAR: variable name for receiving the path to the built target.
Geoffrey Martin-Nobleb5d90ac2021-05-12 13:49:59 -0700140# - EXECUTABLE: the executable to get its path. Note that this needs to be the
141# name of the executable target when not cross compiling and the basename of
142# the binary when importing a binary from a host build. Thus this should be
143# the global unqualified name of the binary, not the fully-specified name.
Lei Zhang0c417da2020-06-29 19:36:00 -0400144function(iree_get_executable_path OUTPUT_PATH_VAR EXECUTABLE)
Scott Todd1a1aea62022-04-28 09:12:11 -0700145 if(NOT DEFINED IREE_HOST_BINARY_ROOT OR TARGET "${EXECUTABLE}")
Scott Toddd5beb622021-03-01 11:44:15 -0800146 # We can either expect the target to be defined as part of this CMake
147 # invocation (if not cross compiling) or the target is defined already.
Lei Zhang0c417da2020-06-29 19:36:00 -0400148 set(${OUTPUT_PATH_VAR} "$<TARGET_FILE:${EXECUTABLE}>" PARENT_SCOPE)
Scott Toddd5beb622021-03-01 11:44:15 -0800149 else()
150 # The target won't be directly defined by this CMake invocation so check
151 # for an already built executable at IREE_HOST_BINARY_ROOT. If we find it,
152 # add it as an imported target so it gets picked up on later invocations.
153 set(_EXECUTABLE_PATH "${IREE_HOST_BINARY_ROOT}/bin/${EXECUTABLE}${IREE_HOST_EXECUTABLE_SUFFIX}")
Scott Todd1a1aea62022-04-28 09:12:11 -0700154 if(EXISTS ${_EXECUTABLE_PATH})
Scott Toddd5beb622021-03-01 11:44:15 -0800155 add_executable("${EXECUTABLE}" IMPORTED GLOBAL)
156 set_property(TARGET "${EXECUTABLE}" PROPERTY IMPORTED_LOCATION "${_EXECUTABLE_PATH}")
157 set(${OUTPUT_PATH_VAR} "$<TARGET_FILE:${EXECUTABLE}>" PARENT_SCOPE)
158 else()
159 message(FATAL_ERROR "Could not find '${EXECUTABLE}' at '${_EXECUTABLE_PATH}'. "
160 "Ensure that IREE_HOST_BINARY_ROOT points to installed binaries.")
161 endif()
Lei Zhang1ff70612020-06-04 10:12:41 -0400162 endif()
163endfunction()
164
Ben Vanikcc2aff92019-09-24 10:23:55 -0700165#-------------------------------------------------------------------------------
166# select()-like Evaluation
167#-------------------------------------------------------------------------------
168
169# Appends ${OPTS} with a list of values based on the current compiler.
170#
171# Example:
172# iree_select_compiler_opts(COPTS
173# CLANG
174# "-Wno-foo"
175# "-Wno-bar"
176# CLANG_CL
177# "/W3"
178# GCC
179# "-Wsome-old-flag"
180# MSVC
181# "/W3"
182# )
183#
184# Note that variables are allowed, making it possible to share options between
185# different compiler targets.
186function(iree_select_compiler_opts OPTS)
187 cmake_parse_arguments(
188 PARSE_ARGV 1
189 _IREE_SELECTS
190 ""
191 ""
Ben Vanikc5f97a12022-06-09 12:51:47 -0700192 "ALL;CLANG;CLANG_GTE_10;CLANG_CL;MSVC;GCC;CLANG_OR_GCC;MSVC_OR_CLANG_CL"
Ben Vanikcc2aff92019-09-24 10:23:55 -0700193 )
Geoffrey Martin-Noble3fa4f8d2021-09-10 09:25:27 -0700194 # OPTS is a variable containing the *name* of the variable being populated, so
195 # we need to dereference it twice.
196 set(_OPTS "${${OPTS}}")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700197 list(APPEND _OPTS "${_IREE_SELECTS_ALL}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700198 if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700199 list(APPEND _OPTS "${_IREE_SELECTS_GCC}")
200 list(APPEND _OPTS "${_IREE_SELECTS_CLANG_OR_GCC}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700201 elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
202 if(MSVC)
Ben Vanikb8fe0862019-09-25 09:26:03 -0700203 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_CL})
204 list(APPEND _OPTS ${_IREE_SELECTS_MSVC_OR_CLANG_CL})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700205 else()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700206 list(APPEND _OPTS ${_IREE_SELECTS_CLANG})
Ben Vanikc5f97a12022-06-09 12:51:47 -0700207 if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
208 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_GTE_10})
209 endif()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700210 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_OR_GCC})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700211 endif()
212 elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700213 list(APPEND _OPTS ${_IREE_SELECTS_MSVC})
214 list(APPEND _OPTS ${_IREE_SELECTS_MSVC_OR_CLANG_CL})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700215 else()
216 message(ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER}")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700217 list(APPEND _OPTS "")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700218 endif()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700219 set(${OPTS} ${_OPTS} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -0700220endfunction()
Scott Todd633148d2020-03-09 10:53:56 -0700221
222#-------------------------------------------------------------------------------
223# Data dependencies
224#-------------------------------------------------------------------------------
225
226# Adds 'data' dependencies to a target.
227#
228# Parameters:
229# NAME: name of the target to add data dependencies to
Scott Todd1a1aea62022-04-28 09:12:11 -0700230# DATA: List of targets and/or files in the source tree (relative to the
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700231# project root).
Scott Todd633148d2020-03-09 10:53:56 -0700232function(iree_add_data_dependencies)
233 cmake_parse_arguments(
234 _RULE
235 ""
236 "NAME"
237 "DATA"
238 ${ARGN}
239 )
240
241 if(NOT _RULE_DATA)
242 return()
243 endif()
244
245 foreach(_DATA_LABEL ${_RULE_DATA})
246 if(TARGET ${_DATA_LABEL})
247 add_dependencies(${_RULE_NAME} ${_DATA_LABEL})
248 else()
249 # Not a target, assume to be a file instead.
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700250 set(_FILE_PATH ${_DATA_LABEL})
Scott Todd633148d2020-03-09 10:53:56 -0700251
252 # Create a target which copies the data file into the build directory.
253 # If this file is included in multiple rules, only create the target once.
254 string(REPLACE "::" "_" _DATA_TARGET ${_DATA_LABEL})
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700255 string(REPLACE "/" "_" _DATA_TARGET ${_DATA_TARGET})
Scott Todd633148d2020-03-09 10:53:56 -0700256 if(NOT TARGET ${_DATA_TARGET})
Stella Laurenzo749ce662021-09-21 18:34:26 -0700257 set(_INPUT_PATH "${PROJECT_SOURCE_DIR}/${_FILE_PATH}")
258 set(_OUTPUT_PATH "${PROJECT_BINARY_DIR}/${_FILE_PATH}")
Scott Todd633148d2020-03-09 10:53:56 -0700259 add_custom_target(${_DATA_TARGET}
260 COMMAND ${CMAKE_COMMAND} -E copy ${_INPUT_PATH} ${_OUTPUT_PATH}
261 )
262 endif()
263
264 add_dependencies(${_RULE_NAME} ${_DATA_TARGET})
265 endif()
266 endforeach()
267endfunction()
Lei Zhangedc9b2a2020-06-04 16:53:52 -0400268
Lei Zhang0c417da2020-06-29 19:36:00 -0400269#-------------------------------------------------------------------------------
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800270# Tool symlinks
271#-------------------------------------------------------------------------------
272
273# iree_symlink_tool
274#
275# Adds a command to TARGET which symlinks a tool from elsewhere
276# (FROM_TOOL_TARGET_NAME) to a local file name (TO_EXE_NAME) in the current
277# binary directory.
278#
279# Parameters:
280# TARGET: Local target to which to add the symlink command (i.e. an
281# iree_py_library, etc).
282# FROM_TOOL_TARGET: Target of the tool executable that is the source of the
283# link.
284# TO_EXE_NAME: The executable name to output in the current binary dir.
285function(iree_symlink_tool)
286 cmake_parse_arguments(
Scott Todd1a1aea62022-04-28 09:12:11 -0700287 _RULE
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800288 ""
289 "TARGET;FROM_TOOL_TARGET;TO_EXE_NAME"
290 ""
291 ${ARGN}
292 )
293
294 # Transform TARGET
295 iree_package_ns(_PACKAGE_NS)
296 iree_package_name(_PACKAGE_NAME)
Scott Todd1a1aea62022-04-28 09:12:11 -0700297 set(_TARGET "${_PACKAGE_NAME}_${_RULE_TARGET}")
298 set(_FROM_TOOL_TARGET ${_RULE_FROM_TOOL_TARGET})
299 set(_TO_TOOL_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_RULE_TO_EXE_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700300 get_filename_component(_TO_TOOL_DIR "${_TO_TOOL_PATH}" DIRECTORY)
301
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800302
303 add_custom_command(
304 TARGET "${_TARGET}"
305 BYPRODUCTS
Scott Todd1a1aea62022-04-28 09:12:11 -0700306 "${CMAKE_CURRENT_BINARY_DIR}/${_RULE_TO_EXE_NAME}${CMAKE_EXECUTABLE_SUFFIX}"
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800307 COMMAND
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700308 ${CMAKE_COMMAND} -E make_directory "${_TO_TOOL_DIR}"
309 COMMAND
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800310 ${CMAKE_COMMAND} -E create_symlink
311 "$<TARGET_FILE:${_FROM_TOOL_TARGET}>"
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700312 "${_TO_TOOL_PATH}"
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800313 )
314endfunction()
315
316
317#-------------------------------------------------------------------------------
Scott Todd6132bb32020-08-11 12:04:40 -0700318# Tests
319#-------------------------------------------------------------------------------
320
Geoffrey Martin-Noble527b7a02021-10-27 06:19:17 -0700321# iree_check_defined
322#
323# A lightweight way to check that all the given variables are defined. Useful
324# in cases like checking that a function has been passed all required arguments.
325# Doesn't give usage-specific error messages, but still significantly better
326# than no error checking.
327# Variable names should be passed directly without quoting or dereferencing.
328# Example:
329# iree_check_defined(_SOME_VAR _AND_ANOTHER_VAR)
330macro(iree_check_defined)
331 foreach(_VAR ${ARGN})
332 if(NOT DEFINED "${_VAR}")
333 message(SEND_ERROR "${_VAR} is not defined")
334 endif()
335 endforeach()
336endmacro()
337
338# iree_validate_required_arguments
339#
340# Validates that no arguments went unparsed or were given no values and that all
341# required arguments have values. Expects to be called after
342# cmake_parse_arguments and verifies that the variables it creates have been
343# populated as appropriate.
344function(iree_validate_required_arguments
345 PREFIX
346 REQUIRED_ONE_VALUE_KEYWORDS
347 REQUIRED_MULTI_VALUE_KEYWORDS)
348 if(DEFINED ${PREFIX}_UNPARSED_ARGUMENTS)
349 message(SEND_ERROR "Unparsed argument(s): '${${PREFIX}_UNPARSED_ARGUMENTS}'")
350 endif()
351 if(DEFINED ${PREFIX}_KEYWORDS_MISSING_VALUES)
352 message(SEND_ERROR
353 "No values for field(s) '${${PREFIX}_KEYWORDS_MISSING_VALUES}'")
354 endif()
355
Geoffrey Martin-Noble66d48892021-10-29 12:24:58 -0700356 foreach(_KEYWORD IN LISTS REQUIRED_ONE_VALUE_KEYWORDS REQUIRED_MULTI_VALUE_KEYWORDS)
357 if(NOT DEFINED ${PREFIX}_${_KEYWORD})
358 message(SEND_ERROR "Missing required argument ${_KEYWORD}")
Geoffrey Martin-Noble527b7a02021-10-27 06:19:17 -0700359 endif()
360 endforeach()
361endfunction()