blob: 43f130e562d5e4fab0be8839ac5acbc18865ad3d [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.
bjacob3dc368e2023-05-09 12:50:18 -040055if(EMSCRIPTEN)
bjacob8f5ced92023-03-20 20:20:36 -040056 # 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.
bjacob3dc368e2023-05-09 12:50:18 -040059 set(IREE_ARCH "")
60elseif((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "aarch64") OR
bjacob8f5ced92023-03-20 20:20:36 -040061 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64") OR
62 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64e") OR
63 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm64ec"))
bjacob3dc368e2023-05-09 12:50:18 -040064 set(IREE_ARCH "arm_64")
65elseif((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "arm") OR
bjacob8f5ced92023-03-20 20:20:36 -040066 (_IREE_UNNORMALIZED_ARCH_LOWERCASE MATCHES "^armv[5-8]"))
bjacob3dc368e2023-05-09 12:50:18 -040067 set(IREE_ARCH "arm_32")
68elseif((_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x86_64") OR
bjacob8f5ced92023-03-20 20:20:36 -040069 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "amd64") OR
70 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x64"))
bjacob3dc368e2023-05-09 12:50:18 -040071 set(IREE_ARCH "x86_64")
72elseif((_IREE_UNNORMALIZED_ARCH_LOWERCASE MATCHES "^i[3-7]86$") OR
bjacob8f5ced92023-03-20 20:20:36 -040073 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "x86") OR
74 (_IREE_UNNORMALIZED_ARCH_LOWERCASE STREQUAL "win32"))
bjacob3dc368e2023-05-09 12:50:18 -040075 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 "")
bjacob8f5ced92023-03-20 20:20:36 -040082 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()
bjacob3dc368e2023-05-09 12:50:18 -040091 set(IREE_ARCH "")
bjacob8f5ced92023-03-20 20:20:36 -040092 message(SEND_ERROR "Unrecognized target architecture ${_IREE_UNNORMALIZED_ARCH_LOWERCASE}")
93endif()
94
bjacob3dc368e2023-05-09 12:50:18 -040095# iree_arch_to_llvm_arch()
96#
97# Helper mapping an architecture in IREE's naming scheme (as in IREE_ARCH)
98# to an architecture in LLVM's naming scheme (as in LLVM target triples).
99function(iree_arch_to_llvm_arch DST_LLVM_ARCH_VARIABLE SRC_ARCH)
100 if("${SRC_ARCH}" STREQUAL "arm_64")
101 set(${DST_LLVM_ARCH_VARIABLE} "aarch64" PARENT_SCOPE)
102 elseif("${SRC_ARCH}" STREQUAL "arm_32")
103 set(${DST_LLVM_ARCH_VARIABLE} "arm" PARENT_SCOPE)
104 elseif("${SRC_ARCH}" STREQUAL "x86_64")
105 set(${DST_LLVM_ARCH_VARIABLE} "x86_64" PARENT_SCOPE)
106 elseif("${SRC_ARCH}" STREQUAL "x86_32")
107 set(${DST_LLVM_ARCH_VARIABLE} "i386" PARENT_SCOPE)
108 elseif("${SRC_ARCH}" STREQUAL "riscv_64")
109 set(${DST_LLVM_ARCH_VARIABLE} "riscv64" PARENT_SCOPE)
110 elseif("${SRC_ARCH}" STREQUAL "riscv_32")
111 set(${DST_LLVM_ARCH_VARIABLE} "riscv32" PARENT_SCOPE)
bjacob041b4e82023-05-30 19:59:26 -0400112 elseif("${SRC_ARCH}" STREQUAL "wasm_64")
113 set(${DST_LLVM_ARCH_VARIABLE} "wasm64" PARENT_SCOPE)
114 elseif("${SRC_ARCH}" STREQUAL "wasm_32")
115 set(${DST_LLVM_ARCH_VARIABLE} "wasm32" PARENT_SCOPE)
bjacob3dc368e2023-05-09 12:50:18 -0400116 else()
117 message(SEND_ERROR "What is the LLVM name of the architecture that we call ${SRC_ARCH} ?")
118 set(${DST_LLVM_ARCH_VARIABLE} "unknown" PARENT_SCOPE)
119 endif()
120endfunction()
121
Ben Vanik57d5e2e2020-03-03 07:14:56 -0800122#-------------------------------------------------------------------------------
Lei Zhang7e8589a2020-06-10 16:42:49 -0400123# General utilities
124#-------------------------------------------------------------------------------
125
126# iree_to_bool
127#
128# Sets `variable` to `ON` if `value` is true and `OFF` otherwise.
Lei Zhangd643f672020-06-16 10:56:41 -0400129function(iree_to_bool VARIABLE VALUE)
130 if(VALUE)
131 set(${VARIABLE} "ON" PARENT_SCOPE)
Lei Zhang7e8589a2020-06-10 16:42:49 -0400132 else()
Lei Zhangd643f672020-06-16 10:56:41 -0400133 set(${VARIABLE} "OFF" PARENT_SCOPE)
Lei Zhang7e8589a2020-06-10 16:42:49 -0400134 endif()
135endfunction()
136
Lei Zhangdd21f322020-09-10 10:47:33 -0400137# iree_append_list_to_string
138#
139# Joins ${ARGN} together as a string separated by " " and appends it to
140# ${VARIABLE}.
141function(iree_append_list_to_string VARIABLE)
142 if(NOT "${ARGN}" STREQUAL "")
143 string(JOIN " " _ARGN_STR ${ARGN})
144 set(${VARIABLE} "${${VARIABLE}} ${_ARGN_STR}" PARENT_SCOPE)
145 endif()
146endfunction()
147
Lei Zhang7e8589a2020-06-10 16:42:49 -0400148
149#-------------------------------------------------------------------------------
Ben Vanikcc2aff92019-09-24 10:23:55 -0700150# Packages and Paths
151#-------------------------------------------------------------------------------
152
Ben Vanik512d2d32019-09-20 13:22:34 -0700153# Sets ${PACKAGE_NS} to the IREE-root relative package name in C++ namespace
154# format (::).
155#
Scott Todd44f95f82022-06-01 09:59:32 -0700156# Examples:
157# compiler/src/iree/compiler/Utils/CMakeLists.txt -> iree::compiler::Utils
158# runtime/src/iree/base/CMakeLists.txt -> iree::base
159# tests/e2e/CMakeLists.txt -> iree::tests::e2e
Ben Vanik512d2d32019-09-20 13:22:34 -0700160function(iree_package_ns PACKAGE_NS)
Stella Laurenzobe0f1e12023-04-03 13:34:38 -0700161 if(DEFINED IREE_PACKAGE_ROOT_DIR)
162 # If an enclosing package root dir is set, then the package is just the
163 # relative part after that.
164 cmake_path(RELATIVE_PATH CMAKE_CURRENT_LIST_DIR
165 BASE_DIRECTORY "${IREE_PACKAGE_ROOT_DIR}"
166 OUTPUT_VARIABLE _PACKAGE)
167 if(_PACKAGE STREQUAL ".")
168 set(_PACKAGE "")
169 endif()
170 if(IREE_PACKAGE_ROOT_PREFIX)
bjacob3dc368e2023-05-09 12:50:18 -0400171 if("${_PACKAGE}" STREQUAL "")
Lei Zhang923535d2023-04-06 18:07:43 -0400172 set(_PACKAGE "${IREE_PACKAGE_ROOT_PREFIX}")
173 else()
174 set(_PACKAGE "${IREE_PACKAGE_ROOT_PREFIX}/${_PACKAGE}")
175 endif()
Stella Laurenzobe0f1e12023-04-03 13:34:38 -0700176 endif()
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700177 else()
Stella Laurenzobe0f1e12023-04-03 13:34:38 -0700178 # Get the relative path of the current dir (i.e. runtime/src/iree/vm).
179 string(REPLACE ${IREE_ROOT_DIR} "" _IREE_RELATIVE_PATH ${CMAKE_CURRENT_LIST_DIR})
180 string(SUBSTRING ${_IREE_RELATIVE_PATH} 1 -1 _IREE_RELATIVE_PATH)
181
182 if(NOT ${CMAKE_CURRENT_LIST_DIR} MATCHES "^${IREE_ROOT_DIR}/.*")
183 # Function is being called from outside IREE. Use the source-relative path.
184 # Please check the README.md to see the potential risk.
185 string(REPLACE ${PROJECT_SOURCE_DIR} "" _SOURCE_RELATIVE_PATH ${CMAKE_CURRENT_LIST_DIR})
186 string(SUBSTRING ${_SOURCE_RELATIVE_PATH} 1 -1 _SOURCE_RELATIVE_PATH)
187 set(_PACKAGE "${_SOURCE_RELATIVE_PATH}")
188
189 # If changing the directory/package mapping rules, please also implement
190 # the corresponding rule in:
191 # build_tools/bazel_to_cmake/bazel_to_cmake_targets.py
192 # Some sub-trees form their own roots for package purposes. Rewrite them.
193 else()
194 message(SEND_ERROR "iree_package_ns(): Could not determine package for ${CMAKE_CURRENT_LIST_DIR}")
195 set(_PACKAGE "iree/unknown")
196 endif()
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700197 endif()
198
Scott Toddf57ab752022-05-23 10:36:44 -0700199 string(REPLACE "/" "::" _PACKAGE_NS "${_PACKAGE}")
Stella Laurenzo1e8d1fa2022-04-22 09:50:43 -0700200
201 if(_DEBUG_IREE_PACKAGE_NAME)
Stella Laurenzobe0f1e12023-04-03 13:34:38 -0700202 message(STATUS "iree_package_ns(): map ${CMAKE_CURRENT_LIST_DIR} -> ${_PACKAGE_NS}")
Stella Laurenzo1e8d1fa2022-04-22 09:50:43 -0700203 endif()
204
Ben Vanikcc2aff92019-09-24 10:23:55 -0700205 set(${PACKAGE_NS} ${_PACKAGE_NS} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -0700206endfunction()
207
208# Sets ${PACKAGE_NAME} to the IREE-root relative package name.
209#
210# Example when called from iree/base/CMakeLists.txt:
211# iree_base
212function(iree_package_name PACKAGE_NAME)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700213 iree_package_ns(_PACKAGE_NS)
Scott Toddf57ab752022-05-23 10:36:44 -0700214 string(REPLACE "::" "_" _PACKAGE_NAME "${_PACKAGE_NS}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700215 set(${PACKAGE_NAME} ${_PACKAGE_NAME} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -0700216endfunction()
217
218# Sets ${PACKAGE_PATH} to the IREE-root relative package path.
219#
220# Example when called from iree/base/CMakeLists.txt:
221# iree/base
222function(iree_package_path PACKAGE_PATH)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700223 iree_package_ns(_PACKAGE_NS)
224 string(REPLACE "::" "/" _PACKAGE_PATH ${_PACKAGE_NS})
225 set(${PACKAGE_PATH} ${_PACKAGE_PATH} PARENT_SCOPE)
226endfunction()
227
228# Sets ${PACKAGE_DIR} to the directory name of the current package.
229#
230# Example when called from iree/base/CMakeLists.txt:
231# base
232function(iree_package_dir PACKAGE_DIR)
233 iree_package_ns(_PACKAGE_NS)
Scott Toddf57ab752022-05-23 10:36:44 -0700234 string(FIND "${_PACKAGE_NS}" "::" _END_OFFSET REVERSE)
Ben Vanikcc2aff92019-09-24 10:23:55 -0700235 math(EXPR _END_OFFSET "${_END_OFFSET} + 2")
236 string(SUBSTRING ${_PACKAGE_NS} ${_END_OFFSET} -1 _PACKAGE_DIR)
237 set(${PACKAGE_DIR} ${_PACKAGE_DIR} PARENT_SCOPE)
238endfunction()
239
240#-------------------------------------------------------------------------------
241# select()-like Evaluation
242#-------------------------------------------------------------------------------
243
244# Appends ${OPTS} with a list of values based on the current compiler.
245#
246# Example:
247# iree_select_compiler_opts(COPTS
248# CLANG
249# "-Wno-foo"
250# "-Wno-bar"
251# CLANG_CL
252# "/W3"
253# GCC
254# "-Wsome-old-flag"
255# MSVC
256# "/W3"
257# )
258#
259# Note that variables are allowed, making it possible to share options between
260# different compiler targets.
261function(iree_select_compiler_opts OPTS)
262 cmake_parse_arguments(
263 PARSE_ARGV 1
264 _IREE_SELECTS
265 ""
266 ""
Ben Vanikc5f97a12022-06-09 12:51:47 -0700267 "ALL;CLANG;CLANG_GTE_10;CLANG_CL;MSVC;GCC;CLANG_OR_GCC;MSVC_OR_CLANG_CL"
Ben Vanikcc2aff92019-09-24 10:23:55 -0700268 )
Geoffrey Martin-Noble3fa4f8d2021-09-10 09:25:27 -0700269 # OPTS is a variable containing the *name* of the variable being populated, so
270 # we need to dereference it twice.
271 set(_OPTS "${${OPTS}}")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700272 list(APPEND _OPTS "${_IREE_SELECTS_ALL}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700273 if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700274 list(APPEND _OPTS "${_IREE_SELECTS_GCC}")
275 list(APPEND _OPTS "${_IREE_SELECTS_CLANG_OR_GCC}")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700276 elseif("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
277 if(MSVC)
Ben Vanikb8fe0862019-09-25 09:26:03 -0700278 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_CL})
279 list(APPEND _OPTS ${_IREE_SELECTS_MSVC_OR_CLANG_CL})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700280 else()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700281 list(APPEND _OPTS ${_IREE_SELECTS_CLANG})
Ben Vanikc5f97a12022-06-09 12:51:47 -0700282 if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL 10)
283 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_GTE_10})
284 endif()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700285 list(APPEND _OPTS ${_IREE_SELECTS_CLANG_OR_GCC})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700286 endif()
287 elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700288 list(APPEND _OPTS ${_IREE_SELECTS_MSVC})
289 list(APPEND _OPTS ${_IREE_SELECTS_MSVC_OR_CLANG_CL})
Ben Vanikcc2aff92019-09-24 10:23:55 -0700290 else()
291 message(ERROR "Unknown compiler: ${CMAKE_CXX_COMPILER}")
Ben Vanikb8fe0862019-09-25 09:26:03 -0700292 list(APPEND _OPTS "")
Ben Vanikcc2aff92019-09-24 10:23:55 -0700293 endif()
Ben Vanikb8fe0862019-09-25 09:26:03 -0700294 set(${OPTS} ${_OPTS} PARENT_SCOPE)
Ben Vanik512d2d32019-09-20 13:22:34 -0700295endfunction()
Scott Todd633148d2020-03-09 10:53:56 -0700296
297#-------------------------------------------------------------------------------
298# Data dependencies
299#-------------------------------------------------------------------------------
300
301# Adds 'data' dependencies to a target.
302#
303# Parameters:
304# NAME: name of the target to add data dependencies to
Scott Todd1a1aea62022-04-28 09:12:11 -0700305# DATA: List of targets and/or files in the source tree (relative to the
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700306# project root).
Scott Todd633148d2020-03-09 10:53:56 -0700307function(iree_add_data_dependencies)
308 cmake_parse_arguments(
309 _RULE
310 ""
311 "NAME"
312 "DATA"
313 ${ARGN}
314 )
315
316 if(NOT _RULE_DATA)
317 return()
318 endif()
319
320 foreach(_DATA_LABEL ${_RULE_DATA})
321 if(TARGET ${_DATA_LABEL})
322 add_dependencies(${_RULE_NAME} ${_DATA_LABEL})
323 else()
324 # Not a target, assume to be a file instead.
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700325 set(_FILE_PATH ${_DATA_LABEL})
Scott Todd633148d2020-03-09 10:53:56 -0700326
327 # Create a target which copies the data file into the build directory.
328 # If this file is included in multiple rules, only create the target once.
329 string(REPLACE "::" "_" _DATA_TARGET ${_DATA_LABEL})
Stella Laurenzo9bde61b2022-04-21 15:37:14 -0700330 string(REPLACE "/" "_" _DATA_TARGET ${_DATA_TARGET})
Scott Todd633148d2020-03-09 10:53:56 -0700331 if(NOT TARGET ${_DATA_TARGET})
Stella Laurenzo749ce662021-09-21 18:34:26 -0700332 set(_INPUT_PATH "${PROJECT_SOURCE_DIR}/${_FILE_PATH}")
333 set(_OUTPUT_PATH "${PROJECT_BINARY_DIR}/${_FILE_PATH}")
Scott Todd633148d2020-03-09 10:53:56 -0700334 add_custom_target(${_DATA_TARGET}
335 COMMAND ${CMAKE_COMMAND} -E copy ${_INPUT_PATH} ${_OUTPUT_PATH}
336 )
337 endif()
338
339 add_dependencies(${_RULE_NAME} ${_DATA_TARGET})
340 endif()
341 endforeach()
342endfunction()
Lei Zhangedc9b2a2020-06-04 16:53:52 -0400343
Lei Zhang0c417da2020-06-29 19:36:00 -0400344#-------------------------------------------------------------------------------
Scott Todd2deecf32022-11-18 13:06:13 -0800345# Emscripten
346#-------------------------------------------------------------------------------
347
348# A global counter to guarantee unique names for js library files.
349set(_LINK_JS_COUNTER 1)
350
351# Links a JavaScript library to a target using --js-library=file.js.
352#
353# This function is only supported when running under Emscripten (emcmake).
354# This implementation is forked from `em_add_tracked_link_flag()` in
355# https://github.com/emscripten-core/emscripten/blob/main/cmake/Modules/Platform/Emscripten.cmake
356# with changes to be compatible with IREE project style and CMake conventions.
357#
358# Parameters:
359# TARGET: Name of the target to link against
360# SRCS: List of JavaScript source files to link
361function(iree_link_js_library)
362 cmake_parse_arguments(
363 _RULE
364 ""
365 "TARGET"
366 "SRCS"
367 ${ARGN}
368 )
369
370 # Convert from aliased, possibly package-relative, names to target names.
371 iree_package_ns(_PACKAGE_NS)
372 string(REGEX REPLACE "^::" "${_PACKAGE_NS}::" _RULE_TARGET ${_RULE_TARGET})
373 string(REPLACE "::" "_" _RULE_TARGET ${_RULE_TARGET})
374
375 foreach(_SRC_FILE ${_RULE_SRCS})
376 # If the JS file is changed, we want to relink dependent binaries, but
377 # unfortunately it is not possible to make a link step depend directly on a
378 # source file. Instead, we must make a dummy no-op build target on that
379 # source file, and make the original target depend on that dummy target.
380
381 # Sanitate the source .js filename to a good dummy filename.
382 get_filename_component(_JS_NAME "${_SRC_FILE}" NAME)
383 string(REGEX REPLACE "[/:\\\\.\ ]" "_" _DUMMY_JS_TARGET ${_JS_NAME})
384 set(_DUMMY_LIB_NAME ${_RULE_TARGET}_${_LINK_JS_COUNTER}_${_DUMMY_JS_TARGET})
385 set(_DUMMY_C_NAME "${CMAKE_BINARY_DIR}/${_DUMMY_JS_TARGET}_tracker.c")
386
387 # Create a new static library target that with a single dummy .c file.
388 add_library(${_DUMMY_LIB_NAME} STATIC ${_DUMMY_C_NAME})
389 # Make the dummy .c file depend on the .js file we are linking, so that if
390 # the .js file is edited, the dummy .c file, and hence the static library
391 # will be rebuild (no-op). This causes the main application to be
392 # relinked, which is what we want. This approach was recommended by
393 # http://www.cmake.org/pipermail/cmake/2010-May/037206.html
394 add_custom_command(
395 OUTPUT ${_DUMMY_C_NAME}
396 COMMAND ${CMAKE_COMMAND} -E touch ${_DUMMY_C_NAME}
397 DEPENDS ${_SRC_FILE}
398 )
399 target_link_libraries(${_RULE_TARGET}
400 PUBLIC
401 ${_DUMMY_LIB_NAME}
402 )
403
404 # Link the js-library to the target.
405 # When a linked library starts with a "-" cmake will just add it to the
406 # linker command line as it is. The advantage of doing it this way is
407 # that the js-library will also be automatically linked to targets that
408 # depend on this target.
409 get_filename_component(_SRC_ABSOLUTE_PATH "${_SRC_FILE}" ABSOLUTE)
410 target_link_libraries(${_RULE_TARGET}
411 PUBLIC
412 "--js-library \"${_SRC_ABSOLUTE_PATH}\""
413 )
414
415 math(EXPR _LINK_JS_COUNTER "${_LINK_JS_COUNTER} + 1")
416 endforeach()
417endfunction()
418
419#-------------------------------------------------------------------------------
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800420# Tool symlinks
421#-------------------------------------------------------------------------------
422
423# iree_symlink_tool
424#
425# Adds a command to TARGET which symlinks a tool from elsewhere
426# (FROM_TOOL_TARGET_NAME) to a local file name (TO_EXE_NAME) in the current
427# binary directory.
428#
429# Parameters:
430# TARGET: Local target to which to add the symlink command (i.e. an
431# iree_py_library, etc).
432# FROM_TOOL_TARGET: Target of the tool executable that is the source of the
433# link.
434# TO_EXE_NAME: The executable name to output in the current binary dir.
435function(iree_symlink_tool)
436 cmake_parse_arguments(
Scott Todd1a1aea62022-04-28 09:12:11 -0700437 _RULE
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800438 ""
439 "TARGET;FROM_TOOL_TARGET;TO_EXE_NAME"
440 ""
441 ${ARGN}
442 )
443
444 # Transform TARGET
445 iree_package_ns(_PACKAGE_NS)
446 iree_package_name(_PACKAGE_NAME)
Scott Todd1a1aea62022-04-28 09:12:11 -0700447 set(_TARGET "${_PACKAGE_NAME}_${_RULE_TARGET}")
448 set(_FROM_TOOL_TARGET ${_RULE_FROM_TOOL_TARGET})
449 set(_TO_TOOL_PATH "${CMAKE_CURRENT_BINARY_DIR}/${_RULE_TO_EXE_NAME}${CMAKE_EXECUTABLE_SUFFIX}")
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700450 get_filename_component(_TO_TOOL_DIR "${_TO_TOOL_PATH}" DIRECTORY)
451
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800452
453 add_custom_command(
454 TARGET "${_TARGET}"
455 BYPRODUCTS
Scott Todd1a1aea62022-04-28 09:12:11 -0700456 "${CMAKE_CURRENT_BINARY_DIR}/${_RULE_TO_EXE_NAME}${CMAKE_EXECUTABLE_SUFFIX}"
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800457 COMMAND
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700458 ${CMAKE_COMMAND} -E make_directory "${_TO_TOOL_DIR}"
459 COMMAND
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800460 ${CMAKE_COMMAND} -E create_symlink
461 "$<TARGET_FILE:${_FROM_TOOL_TARGET}>"
Geoffrey Martin-Noblefd8a7692021-08-20 05:54:39 -0700462 "${_TO_TOOL_PATH}"
Stella Laurenzoa3e97f12020-12-05 23:29:13 -0800463 )
464endfunction()
465
466
467#-------------------------------------------------------------------------------
Scott Todd6132bb32020-08-11 12:04:40 -0700468# Tests
469#-------------------------------------------------------------------------------
470
Geoffrey Martin-Noble527b7a02021-10-27 06:19:17 -0700471# iree_check_defined
472#
473# A lightweight way to check that all the given variables are defined. Useful
474# in cases like checking that a function has been passed all required arguments.
475# Doesn't give usage-specific error messages, but still significantly better
476# than no error checking.
477# Variable names should be passed directly without quoting or dereferencing.
478# Example:
479# iree_check_defined(_SOME_VAR _AND_ANOTHER_VAR)
480macro(iree_check_defined)
481 foreach(_VAR ${ARGN})
482 if(NOT DEFINED "${_VAR}")
483 message(SEND_ERROR "${_VAR} is not defined")
484 endif()
485 endforeach()
486endmacro()
487
488# iree_validate_required_arguments
489#
490# Validates that no arguments went unparsed or were given no values and that all
491# required arguments have values. Expects to be called after
492# cmake_parse_arguments and verifies that the variables it creates have been
493# populated as appropriate.
494function(iree_validate_required_arguments
495 PREFIX
496 REQUIRED_ONE_VALUE_KEYWORDS
497 REQUIRED_MULTI_VALUE_KEYWORDS)
498 if(DEFINED ${PREFIX}_UNPARSED_ARGUMENTS)
499 message(SEND_ERROR "Unparsed argument(s): '${${PREFIX}_UNPARSED_ARGUMENTS}'")
500 endif()
501 if(DEFINED ${PREFIX}_KEYWORDS_MISSING_VALUES)
502 message(SEND_ERROR
503 "No values for field(s) '${${PREFIX}_KEYWORDS_MISSING_VALUES}'")
504 endif()
505
Geoffrey Martin-Noble66d48892021-10-29 12:24:58 -0700506 foreach(_KEYWORD IN LISTS REQUIRED_ONE_VALUE_KEYWORDS REQUIRED_MULTI_VALUE_KEYWORDS)
507 if(NOT DEFINED ${PREFIX}_${_KEYWORD})
508 message(SEND_ERROR "Missing required argument ${_KEYWORD}")
Geoffrey Martin-Noble527b7a02021-10-27 06:19:17 -0700509 endif()
510 endforeach()
511endfunction()
CindyLiuc70b6992022-10-03 09:57:33 -0700512
513# iree_compile_flags_for_patform
514#
515# Helper function to add necessary compile flags based on platform-specific
516# configurations. Note the flags are added for cpu backends only.
517function(iree_compile_flags_for_platform OUT_FLAGS IN_FLAGS)
518 if(NOT (IN_FLAGS MATCHES "iree-hal-target-backends=llvm-cpu" OR
519 IN_FLAGS MATCHES "iree-hal-target-backends=vmvx"))
520 set(${OUT_FLAGS} "" PARENT_SCOPE)
521 return()
522 endif()
523
Ben Vanik338b9792023-03-08 19:15:22 -0800524 if(ANDROID AND NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
CindyLiuc70b6992022-10-03 09:57:33 -0700525 # Android's CMake toolchain defines some variables that we can use to infer
526 # the appropriate target triple from the configured settings:
527 # https://developer.android.com/ndk/guides/cmake#android_platform
528 #
529 # In typical CMake fashion, the various strings are pretty fuzzy and can
530 # have multiple values like "latest", "android-25"/"25"/"android-N-MR1".
531 #
532 # From looking at the toolchain file, ANDROID_PLATFORM_LEVEL seems like it
533 # should pretty consistently be just a number we can use for target triple.
534 set(_TARGET_TRIPLE "aarch64-none-linux-android${ANDROID_PLATFORM_LEVEL}")
Ben Vanik380bde72023-03-08 10:55:58 -0800535 list(APPEND _FLAGS "--iree-llvmcpu-target-triple=${_TARGET_TRIPLE}")
CindyLiuc70b6992022-10-03 09:57:33 -0700536 endif()
537
bjacob8f5ced92023-03-20 20:20:36 -0400538 if(IREE_ARCH STREQUAL "riscv_64" AND
CindyLiuc70b6992022-10-03 09:57:33 -0700539 CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
Ben Vanik338b9792023-03-08 19:15:22 -0800540 NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
CindyLiuc70b6992022-10-03 09:57:33 -0700541 # RV64 Linux crosscompile toolchain can support iree-compile with
542 # specific CPU flags. Add the llvm flags to support RV64 RVV codegen if
543 # llvm-target-triple is not specified.
544 list(APPEND _FLAGS ${RISCV64_TEST_DEFAULT_LLVM_FLAGS})
bjacob8f5ced92023-03-20 20:20:36 -0400545 elseif(IREE_ARCH STREQUAL "riscv_32" AND
CindyLiuc70b6992022-10-03 09:57:33 -0700546 CMAKE_SYSTEM_NAME STREQUAL "Linux" AND
Ben Vanik338b9792023-03-08 19:15:22 -0800547 NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
CindyLiuc70b6992022-10-03 09:57:33 -0700548 # RV32 Linux crosscompile toolchain can support iree-compile with
549 # specific CPU flags. Add the llvm flags to support RV32 RVV codegen if
550 # llvm-target-triple is not specified.
551 list(APPEND _FLAGS ${RISCV32_TEST_DEFAULT_LLVM_FLAGS})
552 endif()
553
Ben Vanik338b9792023-03-08 19:15:22 -0800554 if(EMSCRIPTEN AND NOT IN_FLAGS MATCHES "iree-llvmcpu-target-triple")
CindyLiuc70b6992022-10-03 09:57:33 -0700555 set(_EMSCRIPTEN_TEST_DEFAULT_FLAGS
Ben Vanik380bde72023-03-08 10:55:58 -0800556 "--iree-llvmcpu-target-triple=wasm32-unknown-emscripten"
CindyLiuc70b6992022-10-03 09:57:33 -0700557 )
558 list(APPEND _FLAGS ${_EMSCRIPTEN_TEST_DEFAULT_FLAGS})
559 endif()
560
561 set(${OUT_FLAGS} "${_FLAGS}" PARENT_SCOPE)
562endfunction()