| # 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 //package:file) with the path into the | |
| # source tree from the repository root. | |
| string(REGEX REPLACE "\\$\\(rootpath //([^:)]+):([^)]+)\\)" "${IREE_ROOT_DIR}/\\1/\\2" _CMD "${_CMD}") | |
| # Replace Bazel syntax $(rootpath //path/to/file) with the path into the | |
| # source tree from the repository root. | |
| string(REGEX REPLACE "\\$\\(rootpath //([^)]+)\\)" "${IREE_ROOT_DIR}/\\1" _CMD "${_CMD}") | |
| # Replace Bazel syntax $(rootpath x) with the path into the source dir. | |
| string(REGEX REPLACE "\\$\\(rootpath ([^)]+)\\)" "${CMAKE_CURRENT_SOURCE_DIR}/\\1" _CMD "${_CMD}") | |
| # Replace Bazel syntax $(execpath //package:file) with the path into the | |
| # binary tree from the repository root. | |
| string(REGEX REPLACE "\\$\\(execpath //([^:)]+):([^)]+)\\)" "${IREE_BINARY_DIR}/\\1/\\2" _CMD "${_CMD}") | |
| # Replace Bazel syntax $(execpath //path/to/file) with the path into the | |
| # binary tree from the repository root. | |
| string(REGEX REPLACE "\\$\\(execpath //([^)]+)\\)" "${IREE_BINARY_DIR}/\\1" _CMD "${_CMD}") | |
| # Replace Bazel syntax $(execpath :x) with x in the binary dir. | |
| string(REGEX REPLACE "\\$\\(execpath :([^)]+)\\)" "\\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() |