|  | # Copyright 2025 The IREE Authors | 
|  | # | 
|  | # Licensed under the Apache License v2.0 with LLVM Exceptions. | 
|  | # See https://llvm.org/LICENSE.txt for license information. | 
|  | # SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  |  | 
|  | # A wrapper around add_custom_command and a minimal subset of Bazel genrule. | 
|  | # | 
|  | # Parameters: | 
|  | # NAME: Name of the target. | 
|  | # SRCS: Source files, including any script run in the command. | 
|  | #       Unlike Bazel's genrule, we do not try to distinguish between the | 
|  | #       two. The distinction is needed when tools need to be compiled for | 
|  | #       host, but that doesn't concern us if we only need to run python | 
|  | #       scripts. | 
|  | # OUTS: Files generated by the command. | 
|  | # CMD:  The command to be executed. The only supported special Bazel genrule | 
|  | #       syntax is: | 
|  | #            * "$(rootpath x)", only supported for source files. In conversion | 
|  | #              to CMake, this expands to the path of x relatively to the current | 
|  | #              source dir. | 
|  | #            * "$(execpath x)", only supported for generated files. In | 
|  | #              conversion to CMake, this expands to just x, as the binary dir is | 
|  | #              the default working dir for custom commands anyway. | 
|  | function(iree_genrule) | 
|  | cmake_parse_arguments( | 
|  | _RULE | 
|  | "" | 
|  | "NAME" | 
|  | "SRCS;OUTS;CMD" | 
|  | ${ARGN} | 
|  | ) | 
|  |  | 
|  | set(_CMD "${_RULE_CMD}") | 
|  |  | 
|  | # Replace Bazel syntax $(rootpath x) with the path into the source dir. | 
|  | string(REGEX REPLACE "\\$\\(rootpath ([^)]+)\\)" "${CMAKE_CURRENT_SOURCE_DIR}/\\1" _CMD "${_CMD}") | 
|  |  | 
|  | # Simply drop Bazel syntax $(execpath x) as Bazel custom commands are executed | 
|  | # by default in the build directory. | 
|  | string(REGEX REPLACE "\\$\\(execpath ([^)]+)\\)" "\\1" _CMD "${_CMD}") | 
|  |  | 
|  | # Convert CMake/Unix-style paths with forward slashes to Windows-style with | 
|  | # backslashes. It is a bit incorrect to do it as a single cmake_path command | 
|  | # on the whole command string, which isn't technically a path, but this should | 
|  | # not matter if all what this does is this character substitution. | 
|  | # It is not worth implementing a cumbersome fix here, when CMake 4.0 brings | 
|  | # the $<PATH:NATIVE_PATH,...> generator expression which is a simpler, better | 
|  | # fix here. TODO(bjacob): use that generator expression in the above string | 
|  | # replace command directly, whenever we can rely on CMake 4.0. | 
|  | cmake_path(NATIVE_PATH _CMD _CMD) | 
|  |  | 
|  | # CMake add_custom_command expects a list as the command, so we replace spaces | 
|  | # by semicolon here. Careful to avoid replacing backslash-escaped spaces. | 
|  | string(REGEX REPLACE "([^\\]) " "\\1;" _CMD "${_CMD}") | 
|  |  | 
|  | add_custom_command( | 
|  | OUTPUT | 
|  | "${_RULE_OUTS}" | 
|  | COMMAND | 
|  | ${_CMD} | 
|  | DEPENDS | 
|  | "${_RULE_SRCS}" | 
|  | COMMENT | 
|  | "Generating ${_RULE_OUTS}" | 
|  | VERBATIM | 
|  | ) | 
|  |  | 
|  | add_custom_target("${_RULE_NAME}" | 
|  | DEPENDS "${_RULE_OUTS}" | 
|  | ) | 
|  | endfunction() |