blob: fd2f8cbd627eebd3152432cb3cecb2f759a9dd83 [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
bjacob8f5ced92023-03-20 20:20:36 -040022
23#-------------------------------------------------------------------------------
24# IREE_ARCH: identifies the target CPU architecture. May be empty when this is
25# ill-defined, such as multi-architecture builds.
26# This should be kept consistent with the C preprocessor token IREE_ARCH defined
27# in target_platform.h.
28#-------------------------------------------------------------------------------
29
30# First, get the raw CMake architecture name, not yet normalized. Even that is
31# non-trivial: it usually is CMAKE_SYSTEM_PROCESSOR, but on some platforms, we
32# have to read other variables instead.
33if(CMAKE_OSX_ARCHITECTURES)
34 # Borrowing from:
35 # https://boringssl.googlesource.com/boringssl/+/c5f0e58e653d2d9afa8facc090ce09f8aaa3fa0d/CMakeLists.txt#43
36 # https://github.com/google/XNNPACK/blob/2eb43787bfad4a99bdb613111cea8bc5a82f390d/CMakeLists.txt#L40
37 list(LENGTH CMAKE_OSX_ARCHITECTURES NUM_ARCHES)
38 if(${NUM_ARCHES} EQUAL 1)
39 # Only one arch in CMAKE_OSX_ARCHITECTURES, use that.
40 set(_IREE_UNNORMALIZED_ARCH "${CMAKE_OSX_ARCHITECTURES}")
41 endif()
42 # Leaving _IREE_UNNORMALIZED_ARCH empty disables arch code paths. We will
43 # issue a performance warning about that below.
44elseif(CMAKE_GENERATOR MATCHES "^Visual Studio " AND CMAKE_GENERATOR_PLATFORM)
45 # Borrowing from:
46 # https://github.com/google/XNNPACK/blob/2eb43787bfad4a99bdb613111cea8bc5a82f390d/CMakeLists.txt#L50
47 set(_IREE_UNNORMALIZED_ARCH "${CMAKE_GENERATOR_PLATFORM}")
48else()
49 set(_IREE_UNNORMALIZED_ARCH "${CMAKE_SYSTEM_PROCESSOR}")
50endif()
51
52string(TOLOWER "${_IREE_UNNORMALIZED_ARCH}" _IREE_UNNORMALIZED_ARCH_LOWERCASE)
53
54# Normalize _IREE_UNNORMALIZED_ARCH into IREE_ARCH.
55if (EMSCRIPTEN)
56 # TODO: figure what to do about the wasm target, which masquerades as x86.
57 # This is the one case where the IREE_ARCH CMake variable is currently
58 # inconsistent with the IREE_ARCH C preprocessor token.
59 set (IREE_ARCH "")
60elseif ((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "aarch64") OR
61 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64") OR
62 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64e") OR
63 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64ec"))
64 set (IREE_ARCH "arm_64")
65elseif ((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm") OR
66 (_IREE_UNNORMALIZED_ARCH_LOWERCASE MATCHES "^armv[5-8]"))
67 set (IREE_ARCH "arm_32")
68elseif ((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x86_64") OR
69 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "amd64") OR
70 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x64"))
71 set (IREE_ARCH "x86_64")
72elseif ((_IREE_UNNORMALIZED_ARCH_LOWERCASE MATCHES "^i[3-7]86$") OR
73 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x86") OR
74 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "win32"))
75 set (IREE_ARCH "x86_32")
76elseif (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "riscv64")
77 set (IREE_ARCH "riscv_64")
78elseif (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "riscv32")
79 set (IREE_ARCH "riscv_32")
80elseif (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "")
81 set (IREE_ARCH "")
82 message(WARNING "Performance advisory: architecture-specific code paths "
83 "disabled because no target architecture was specified or we didn't know "
84 "which CMake variable to read. Some relevant CMake variables:\n"
85 "CMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}\n"
86 "CMAKE_GENERATOR=${CMAKE_GENERATOR}\n"
87 "CMAKE_GENERATOR_PLATFORM=${CMAKE_GENERATOR_PLATFORM}\n"
88 "CMAKE_OSX_ARCHITECTURES=${CMAKE_OSX_ARCHITECTURES}\n"
89 )
90else()
91 set (IREE_ARCH "")
92 message(SEND_ERROR "Unrecognized target architecture ${_IREE_UNNORMALIZED_ARCH_LOWERCASE}")
93endif()
94
Ben Vanik57d5e2e2020-03-03 07:14:56 -080095#-------------------------------------------------------------------------------
Lei Zhang7e8589a2020-06-10 16:42:49 -040096# General utilities
97#-------------------------------------------------------------------------------
98
99# iree_to_bool
100#
101# Sets `variable` to `ON` if `value` is true and `OFF` otherwise.
Lei Zhangd643f672020-06-16 10:56:41 -0400102function(iree_to_bool VARIABLE VALUE)
103 if(VALUE)
104 set(${VARIABLE} "ON" PARENT_SCOPE)
Lei Zhang7e8589a2020-06-10 16:42:49 -0400105 else()
Lei Zhangd643f672020-06-16 10:56:41 -0400106 set(${VARIABLE} "OFF" PARENT_SCOPE)
Lei Zhang7e8589a2020-06-10 16:42:49 -0400107 endif()
108endfunction()
109
Lei Zhangdd21f322020-09-10 10:47:33 -0400110# iree_append_list_to_string
111#
112# Joins ${ARGN} together as a string separated by " " and appends it to
113# ${VARIABLE}.
114function(iree_append_list_to_string VARIABLE)
115 if(NOT "${ARGN}" STREQUAL "")
116 string(JOIN " " _ARGN_STR ${ARGN})
117 set(${VARIABLE} "${${VARIABLE}} ${_ARGN_STR}" PARENT_SCOPE)
118 endif()
119endfunction()
120
Lei Zhang7e8589a2020-06-10 16:42:49 -0400121
122#-------------------------------------------------------------------------------
Ben Vanikcc2aff92019-09-24 10:23:55 -0700123# Packages and Paths
124#-------------------------------------------------------------------------------
125
Ben Vanik512d2d32019-09-20 13:22:34 -0700126# Sets ${PACKAGE_NS} to the IREE-root relative package name in C++ namespace
127# format (::).
128#
Scott Todd44f95f82022-06-01 09:59:32 -0700129# Examples:
130# compiler/src/iree/compiler/Utils/CMakeLists.txt -> iree::compiler::Utils
131# runtime/src/iree/base/CMakeLists.txt -> iree::base
132# tests/e2e/CMakeLists.txt -> iree::tests::e2e
Ben Vanik512d2d32019-09-20 13:22:34 -0700133function(iree_package_ns PACKAGE_NS)
Stella Laurenzobe0f1e12023-04-03 13:34:38 -0700134 if(DEFINED IREE_PACKAGE_ROOT_DIR)
135 # If an enclosing package root dir is set, then the package is just the
136 # relative part after that.
137 cmake_path(RELATIVE_PATH CMAKE_CURRENT_LIST_DIR
138 BASE_DIRECTORY "${IREE_PACKAGE_ROOT_DIR}"
139 OUTPUT_VARIABLE _PACKAGE)
140 if(_PACKAGE STREQUAL ".")
141 set(_PACKAGE "")
142 endif()
143 if(IREE_PACKAGE_ROOT_PREFIX)
Lei Zhang923535d2023-04-06 18:07:43 -0400144 if ("${_PACKAGE}" STREQUAL "")
145 set(_PACKAGE "${IREE_PACKAGE_ROOT_PREFIX}")
146 else()
147 set(_PACKAGE "${IREE_PACKAGE_ROOT_PREFIX}/${_PACKAGE}")
148 endif()
Stella Laurenzobe0f1e12023-04-03 13:34:38 -0700149 endif()
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700150 else()
Stella Laurenzobe0f1e12023-04-03 13:34:38 -0700151 # Get the relative path of the current dir (i.e. runtime/src/iree/vm).
152 string(REPLACE ${IREE_ROOT_DIR} "" _IREE_RELATIVE_PATH ${CMAKE_CURRENT_LIST_DIR})
153 string(SUBSTRING ${_IREE_RELATIVE_PATH} 1 -1 _IREE_RELATIVE_PATH)
154
155 if(NOT ${CMAKE_CURRENT_LIST_DIR} MATCHES "^${IREE_ROOT_DIR}/.*")
156 # Function is being called from outside IREE. Use the source-relative path.
157 # Please check the README.md to see the potential risk.
158 string(REPLACE ${PROJECT_SOURCE_DIR} "" _SOURCE_RELATIVE_PATH ${CMAKE_CURRENT_LIST_DIR})
159 string(SUBSTRING ${_SOURCE_RELATIVE_PATH} 1 -1 _SOURCE_RELATIVE_PATH)
160 set(_PACKAGE "${_SOURCE_RELATIVE_PATH}")
161
162 # If changing the directory/package mapping rules, please also implement
163 # the corresponding rule in:
164 # build_tools/bazel_to_cmake/bazel_to_cmake_targets.py
165 # Some sub-trees form their own roots for package purposes. Rewrite them.
166 else()
167 message(SEND_ERROR "iree_package_ns(): Could not determine package for ${CMAKE_CURRENT_LIST_DIR}")
168 set(_PACKAGE "iree/unknown")
169 endif()
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700170 endif()
171
Scott Toddf57ab752022-05-23 10:36:44 -0700172 string(REPLACE "/" "::" _PACKAGE_NS "${_PACKAGE}")
Stella Laurenzo1e8d1fa2022-04-22 09:50:43 -0700173
174 if(_DEBUG_IREE_PACKAGE_NAME)
Stella Laurenzobe0f1e12023-04-03 13:34:38 -0700175 message(STATUS "iree_package_ns(): map ${CMAKE_CURRENT_LIST_DIR} -> ${_PACKAGE_NS}")
Stella Laurenzo1e8d1fa2022-04-22 09:50:43 -0700176 endif()
177
Ben Vanikcc2aff92019-09-24 10:23:55 -0700178 set(${PACKAGE_NS} ${_PACKAGE_NS} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -0700179endfunction()
180
181# Sets ${PACKAGE_NAME} to the IREE-root relative package name.
182#
183# Example when called from iree/base/CMakeLists.txt:
184# iree_base
185function(iree_package_name PACKAGE_NAME)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700186 iree_package_ns(_PACKAGE_NS)
Scott Toddf57ab752022-05-23 10:36:44 -0700187 string(REPLACE "::" "_" _PACKAGE_NAME "${_PACKAGE_NS}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700188 set(${PACKAGE_NAME} ${_PACKAGE_NAME} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -0700189endfunction()
190
191# Sets ${PACKAGE_PATH} to the IREE-root relative package path.
192#
193# Example when called from iree/base/CMakeLists.txt:
194# iree/base
195function(iree_package_path PACKAGE_PATH)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700196 iree_package_ns(_PACKAGE_NS)
197 string(REPLACE "::" "/" _PACKAGE_PATH ${_PACKAGE_NS})
198 set(${PACKAGE_PATH} ${_PACKAGE_PATH} PARENT_SCOPE)
199endfunction()
200
201# Sets ${PACKAGE_DIR} to the directory name of the current package.
202#
203# Example when called from iree/base/CMakeLists.txt:
204# base
205function(iree_package_dir PACKAGE_DIR)
206 iree_package_ns(_PACKAGE_NS)
Scott Toddf57ab752022-05-23 10:36:44 -0700207 string(FIND "${_PACKAGE_NS}" "::" _END_OFFSET REVERSE)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700208 math(EXPR _END_OFFSET "${_END_OFFSET} + 2")
209 string(SUBSTRING ${_PACKAGE_NS} ${_END_OFFSET} -1 _PACKAGE_DIR)
210 set(${PACKAGE_DIR} ${_PACKAGE_DIR} PARENT_SCOPE)
211endfunction()
212
213#-------------------------------------------------------------------------------
214# select()-like Evaluation
215#-------------------------------------------------------------------------------
216
217# Appends ${OPTS} with a list of values based on the current compiler.
218#
219# Example:
220# iree_select_compiler_opts(COPTS
221# CLANG
222# "-Wno-foo"
223# "-Wno-bar"
224# CLANG_CL
225# "/W3"
226# GCC
227# "-Wsome-old-flag"
228# MSVC
229# "/W3"
230# )
231#
232# Note that variables are allowed, making it possible to share options between
233# different compiler targets.
234function(iree_select_compiler_opts OPTS)
235 cmake_parse_arguments(
236 PARSE_ARGV 1
237 _IREE_SELECTS
238 ""
239 ""
Ben Vanikc5f97a12022-06-09 12:51:47 -0700240 "ALL;CLANG;CLANG_GTE_10;CLANG_CL;MSVC;GCC;CLANG_OR_GCC;MSVC_OR_CLANG_CL"
Ben Vanikcc2aff92019-09-24 10:23:55 -0700241 )
Geoffrey Martin-Noble3fa4f8d2021-09-10 09:25:27 -0700242 # OPTS is a variable containing the *name* of the variable being populated, so
243 # we need to dereference it twice.
244 set(_OPTS "${${OPTS}}")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700245 list(APPEND _OPTS "${_IREE_SELECTS_ALL}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700246 if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700247 list(APPEND _OPTS "${_IREE_SELECTS_GCC}")
248 list(APPEND _OPTS "${_IREE_SELECTS_CLANG_OR_GCC}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700249 elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
250 if(MSVC)
Ben Vanikb8fe0862019-09-25 09:26:03 -0700251 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_CL})
252 list(APPEND _OPTS ${_IREE_SELECTS_MSVC_OR_CLANG_CL})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700253 else()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700254 list(APPEND _OPTS ${_IREE_SELECTS_CLANG})
Ben Vanikc5f97a12022-06-09 12:51:47 -0700255 if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
256 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_GTE_10})
257 endif()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700258 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_OR_GCC})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700259 endif()
260 elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700261 list(APPEND _OPTS ${_IREE_SELECTS_MSVC})
262 list(APPEND _OPTS ${_IREE_SELECTS_MSVC_OR_CLANG_CL})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700263 else()
264 message(ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER}")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700265 list(APPEND _OPTS "")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700266 endif()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700267 set(${OPTS} ${_OPTS} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -0700268endfunction()
Scott Todd633148d2020-03-09 10:53:56 -0700269
270#-------------------------------------------------------------------------------
271# Data dependencies
272#-------------------------------------------------------------------------------
273
274# Adds 'data' dependencies to a target.
275#
276# Parameters:
277# NAME: name of the target to add data dependencies to
Scott Todd1a1aea62022-04-28 09:12:11 -0700278# DATA: List of targets and/or files in the source tree (relative to the
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700279# project root).
Scott Todd633148d2020-03-09 10:53:56 -0700280function(iree_add_data_dependencies)
281 cmake_parse_arguments(
282 _RULE
283 ""
284 "NAME"
285 "DATA"
286 ${ARGN}
287 )
288
289 if(NOT _RULE_DATA)
290 return()
291 endif()
292
293 foreach(_DATA_LABEL ${_RULE_DATA})
294 if(TARGET ${_DATA_LABEL})
295 add_dependencies(${_RULE_NAME} ${_DATA_LABEL})
296 else()
297 # Not a target, assume to be a file instead.
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700298 set(_FILE_PATH ${_DATA_LABEL})
Scott Todd633148d2020-03-09 10:53:56 -0700299
300 # Create a target which copies the data file into the build directory.
301 # If this file is included in multiple rules, only create the target once.
302 string(REPLACE "::" "_" _DATA_TARGET ${_DATA_LABEL})
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700303 string(REPLACE "/" "_" _DATA_TARGET ${_DATA_TARGET})
Scott Todd633148d2020-03-09 10:53:56 -0700304 if(NOT TARGET ${_DATA_TARGET})
Stella Laurenzo749ce662021-09-21 18:34:26 -0700305 set(_INPUT_PATH "${PROJECT_SOURCE_DIR}/${_FILE_PATH}")
306 set(_OUTPUT_PATH "${PROJECT_BINARY_DIR}/${_FILE_PATH}")
Scott Todd633148d2020-03-09 10:53:56 -0700307 add_custom_target(${_DATA_TARGET}
308 COMMAND ${CMAKE_COMMAND} -E copy ${_INPUT_PATH} ${_OUTPUT_PATH}
309 )
310 endif()
311
312 add_dependencies(${_RULE_NAME} ${_DATA_TARGET})
313 endif()
314 endforeach()
315endfunction()
Lei Zhangedc9b2a2020-06-04 16:53:52 -0400316
Lei Zhang0c417da2020-06-29 19:36:00 -0400317#-------------------------------------------------------------------------------
Scott Todd2deecf32022-11-18 13:06:13 -0800318# Emscripten
319#-------------------------------------------------------------------------------
320
321# A global counter to guarantee unique names for js library files.
322set(_LINK_JS_COUNTER 1)
323
324# Links a JavaScript library to a target using --js-library=file.js.
325#
326# This function is only supported when running under Emscripten (emcmake).
327# This implementation is forked from `em_add_tracked_link_flag()` in
328# https://github.com/emscripten-core/emscripten/blob/main/cmake/Modules/Platform/Emscripten.cmake
329# with changes to be compatible with IREE project style and CMake conventions.
330#
331# Parameters:
332# TARGET: Name of the target to link against
333# SRCS: List of JavaScript source files to link
334function(iree_link_js_library)
335 cmake_parse_arguments(
336 _RULE
337 ""
338 "TARGET"
339 "SRCS"
340 ${ARGN}
341 )
342
343 # Convert from aliased, possibly package-relative, names to target names.
344 iree_package_ns(_PACKAGE_NS)
345 string(REGEX REPLACE "^::" "${_PACKAGE_NS}::" _RULE_TARGET ${_RULE_TARGET})
346 string(REPLACE "::" "_" _RULE_TARGET ${_RULE_TARGET})
347
348 foreach(_SRC_FILE ${_RULE_SRCS})
349 # If the JS file is changed, we want to relink dependent binaries, but
350 # unfortunately it is not possible to make a link step depend directly on a
351 # source file. Instead, we must make a dummy no-op build target on that
352 # source file, and make the original target depend on that dummy target.
353
354 # Sanitate the source .js filename to a good dummy filename.
355 get_filename_component(_JS_NAME "${_SRC_FILE}" NAME)
356 string(REGEX REPLACE "[/:\\\\.\ ]" "_" _DUMMY_JS_TARGET ${_JS_NAME})
357 set(_DUMMY_LIB_NAME ${_RULE_TARGET}_${_LINK_JS_COUNTER}_${_DUMMY_JS_TARGET})
358 set(_DUMMY_C_NAME "${CMAKE_BINARY_DIR}/${_DUMMY_JS_TARGET}_tracker.c")
359
360 # Create a new static library target that with a single dummy .c file.
361 add_library(${_DUMMY_LIB_NAME} STATIC ${_DUMMY_C_NAME})
362 # Make the dummy .c file depend on the .js file we are linking, so that if
363 # the .js file is edited, the dummy .c file, and hence the static library
364 # will be rebuild (no-op). This causes the main application to be
365 # relinked, which is what we want. This approach was recommended by
366 # http://www.cmake.org/pipermail/cmake/2010-May/037206.html
367 add_custom_command(
368 OUTPUT ${_DUMMY_C_NAME}
369 COMMAND ${CMAKE_COMMAND} -E touch ${_DUMMY_C_NAME}
370 DEPENDS ${_SRC_FILE}
371 )
372 target_link_libraries(${_RULE_TARGET}
373 PUBLIC
374 ${_DUMMY_LIB_NAME}
375 )
376
377 # Link the js-library to the target.
378 # When a linked library starts with a "-" cmake will just add it to the
379 # linker command line as it is. The advantage of doing it this way is
380 # that the js-library will also be automatically linked to targets that
381 # depend on this target.
382 get_filename_component(_SRC_ABSOLUTE_PATH "${_SRC_FILE}" ABSOLUTE)
383 target_link_libraries(${_RULE_TARGET}
384 PUBLIC
385 "--js-library \"${_SRC_ABSOLUTE_PATH}\""
386 )
387
388 math(EXPR _LINK_JS_COUNTER "${_LINK_JS_COUNTER} + 1")
389 endforeach()
390endfunction()
391
392#-------------------------------------------------------------------------------
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800393# Tool symlinks
394#-------------------------------------------------------------------------------
395
396# iree_symlink_tool
397#
398# Adds a command to TARGET which symlinks a tool from elsewhere
399# (FROM_TOOL_TARGET_NAME) to a local file name (TO_EXE_NAME) in the current
400# binary directory.
401#
402# Parameters:
403# TARGET: Local target to which to add the symlink command (i.e. an
404# iree_py_library, etc).
405# FROM_TOOL_TARGET: Target of the tool executable that is the source of the
406# link.
407# TO_EXE_NAME: The executable name to output in the current binary dir.
408function(iree_symlink_tool)
409 cmake_parse_arguments(
Scott Todd1a1aea62022-04-28 09:12:11 -0700410 _RULE
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800411 ""
412 "TARGET;FROM_TOOL_TARGET;TO_EXE_NAME"
413 ""
414 ${ARGN}
415 )
416
417 # Transform TARGET
418 iree_package_ns(_PACKAGE_NS)
419 iree_package_name(_PACKAGE_NAME)
Scott Todd1a1aea62022-04-28 09:12:11 -0700420 set(_TARGET "${_PACKAGE_NAME}_${_RULE_TARGET}")
421 set(_FROM_TOOL_TARGET ${_RULE_FROM_TOOL_TARGET})
422 set(_TO_TOOL_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_RULE_TO_EXE_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700423 get_filename_component(_TO_TOOL_DIR "${_TO_TOOL_PATH}" DIRECTORY)
424
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800425
426 add_custom_command(
427 TARGET "${_TARGET}"
428 BYPRODUCTS
Scott Todd1a1aea62022-04-28 09:12:11 -0700429 "${CMAKE_CURRENT_BINARY_DIR}/${_RULE_TO_EXE_NAME}${CMAKE_EXECUTABLE_SUFFIX}"
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800430 COMMAND
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700431 ${CMAKE_COMMAND} -E make_directory "${_TO_TOOL_DIR}"
432 COMMAND
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800433 ${CMAKE_COMMAND} -E create_symlink
434 "$<TARGET_FILE:${_FROM_TOOL_TARGET}>"
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700435 "${_TO_TOOL_PATH}"
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800436 )
437endfunction()
438
439
440#-------------------------------------------------------------------------------
Scott Todd6132bb32020-08-11 12:04:40 -0700441# Tests
442#-------------------------------------------------------------------------------
443
Geoffrey Martin-Noble527b7a02021-10-27 06:19:17 -0700444# iree_check_defined
445#
446# A lightweight way to check that all the given variables are defined. Useful
447# in cases like checking that a function has been passed all required arguments.
448# Doesn't give usage-specific error messages, but still significantly better
449# than no error checking.
450# Variable names should be passed directly without quoting or dereferencing.
451# Example:
452# iree_check_defined(_SOME_VAR _AND_ANOTHER_VAR)
453macro(iree_check_defined)
454 foreach(_VAR ${ARGN})
455 if(NOT DEFINED "${_VAR}")
456 message(SEND_ERROR "${_VAR} is not defined")
457 endif()
458 endforeach()
459endmacro()
460
461# iree_validate_required_arguments
462#
463# Validates that no arguments went unparsed or were given no values and that all
464# required arguments have values. Expects to be called after
465# cmake_parse_arguments and verifies that the variables it creates have been
466# populated as appropriate.
467function(iree_validate_required_arguments
468 PREFIX
469 REQUIRED_ONE_VALUE_KEYWORDS
470 REQUIRED_MULTI_VALUE_KEYWORDS)
471 if(DEFINED ${PREFIX}_UNPARSED_ARGUMENTS)
472 message(SEND_ERROR "Unparsed argument(s): '${${PREFIX}_UNPARSED_ARGUMENTS}'")
473 endif()
474 if(DEFINED ${PREFIX}_KEYWORDS_MISSING_VALUES)
475 message(SEND_ERROR
476 "No values for field(s) '${${PREFIX}_KEYWORDS_MISSING_VALUES}'")
477 endif()
478
Geoffrey Martin-Noble66d48892021-10-29 12:24:58 -0700479 foreach(_KEYWORD IN LISTS REQUIRED_ONE_VALUE_KEYWORDS REQUIRED_MULTI_VALUE_KEYWORDS)
480 if(NOT DEFINED ${PREFIX}_${_KEYWORD})
481 message(SEND_ERROR "Missing required argument ${_KEYWORD}")
Geoffrey Martin-Noble527b7a02021-10-27 06:19:17 -0700482 endif()
483 endforeach()
484endfunction()
CindyLiuc70b6992022-10-03 09:57:33 -0700485
486# iree_compile_flags_for_patform
487#
488# Helper function to add necessary compile flags based on platform-specific
489# configurations. Note the flags are added for cpu backends only.
490function(iree_compile_flags_for_platform OUT_FLAGS IN_FLAGS)
491 if(NOT (IN_FLAGS MATCHES "iree-hal-target-backends=llvm-cpu" OR
492 IN_FLAGS MATCHES "iree-hal-target-backends=vmvx"))
493 set(${OUT_FLAGS} "" PARENT_SCOPE)
494 return()
495 endif()
496
Ben Vanik338b9792023-03-08 19:15:22 -0800497 if(ANDROID AND NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
CindyLiuc70b6992022-10-03 09:57:33 -0700498 # Android's CMake toolchain defines some variables that we can use to infer
499 # the appropriate target triple from the configured settings:
500 # https://developer.android.com/ndk/guides/cmake#android_platform
501 #
502 # In typical CMake fashion, the various strings are pretty fuzzy and can
503 # have multiple values like "latest", "android-25"/"25"/"android-N-MR1".
504 #
505 # From looking at the toolchain file, ANDROID_PLATFORM_LEVEL seems like it
506 # should pretty consistently be just a number we can use for target triple.
507 set(_TARGET_TRIPLE "aarch64-none-linux-android${ANDROID_PLATFORM_LEVEL}")
Ben Vanik380bde72023-03-08 10:55:58 -0800508 list(APPEND _FLAGS "--iree-llvmcpu-target-triple=${_TARGET_TRIPLE}")
CindyLiuc70b6992022-10-03 09:57:33 -0700509 endif()
510
bjacob8f5ced92023-03-20 20:20:36 -0400511 if(IREE_ARCH STREQUAL "riscv_64" AND
CindyLiuc70b6992022-10-03 09:57:33 -0700512 CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
Ben Vanik338b9792023-03-08 19:15:22 -0800513 NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
CindyLiuc70b6992022-10-03 09:57:33 -0700514 # RV64 Linux crosscompile toolchain can support iree-compile with
515 # specific CPU flags. Add the llvm flags to support RV64 RVV codegen if
516 # llvm-target-triple is not specified.
517 list(APPEND _FLAGS ${RISCV64_TEST_DEFAULT_LLVM_FLAGS})
bjacob8f5ced92023-03-20 20:20:36 -0400518 elseif(IREE_ARCH STREQUAL "riscv_32" AND
CindyLiuc70b6992022-10-03 09:57:33 -0700519 CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
Ben Vanik338b9792023-03-08 19:15:22 -0800520 NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
CindyLiuc70b6992022-10-03 09:57:33 -0700521 # RV32 Linux crosscompile toolchain can support iree-compile with
522 # specific CPU flags. Add the llvm flags to support RV32 RVV codegen if
523 # llvm-target-triple is not specified.
524 list(APPEND _FLAGS ${RISCV32_TEST_DEFAULT_LLVM_FLAGS})
525 endif()
526
Ben Vanik338b9792023-03-08 19:15:22 -0800527 if(EMSCRIPTEN AND NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
CindyLiuc70b6992022-10-03 09:57:33 -0700528 set(_EMSCRIPTEN_TEST_DEFAULT_FLAGS
Ben Vanik380bde72023-03-08 10:55:58 -0800529 "--iree-llvmcpu-target-triple=wasm32-unknown-emscripten"
CindyLiuc70b6992022-10-03 09:57:33 -0700530 )
531 list(APPEND _FLAGS ${_EMSCRIPTEN_TEST_DEFAULT_FLAGS})
532 endif()
533
534 set(${OUT_FLAGS} "${_FLAGS}" PARENT_SCOPE)
535endfunction()