|
| 1 | +# Copyright 2025 The IREE Authors |
| 2 | +# |
| 3 | +# 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 |
| 6 | + |
| 7 | +include(CMakeParseArguments) |
| 8 | + |
| 9 | +# A wrapper around add_custom_command and a minimal subset of Bazel genrule. |
| 10 | +# |
| 11 | +# Parameters: |
| 12 | +# NAME: Name of the target. |
| 13 | +# SRCS: Source files, including any script run in the command. |
| 14 | +# Unlike Bazel's genrule, we do not try to distinguish between the |
| 15 | +# two. The distinction is needed when tools need to be compiled for |
| 16 | +# host, but that doesn't concern us if we only need to run python |
| 17 | +# scripts. |
| 18 | +# OUTS: Files generated by the command. |
| 19 | +# CMD: The command to be executed. The only supported special Bazel genrule |
| 20 | +# syntax is: |
| 21 | +# * "$(rootpath x)", only supported for source files. In conversion |
| 22 | +# to CMake, this expands to the path of x relatively to the current |
| 23 | +# source dir. |
| 24 | +# * "$(execpath x)", only supported for generated files. In |
| 25 | +# conversion to CMake, this expands to just x, as the binary dir is |
| 26 | +# the default working dir for custom commands anyway. |
| 27 | +function(iree_genrule) |
| 28 | + cmake_parse_arguments( |
| 29 | + _RULE |
| 30 | + "" |
| 31 | + "NAME" |
| 32 | + "SRCS;OUTS;CMD" |
| 33 | + ${ARGN} |
| 34 | + ) |
| 35 | + |
| 36 | + set(_CMD "${_RULE_CMD}") |
| 37 | + |
| 38 | + # Replace Bazel syntax $(rootpath x) with the path into the source dir. |
| 39 | + string(REGEX REPLACE "\\$\\(rootpath ([^)]+)\\)" "${CMAKE_CURRENT_SOURCE_DIR}/\\1" _CMD "${_CMD}") |
| 40 | + |
| 41 | + # Simply drop Bazel syntax $(execpath x) as Bazel custom commands are executed |
| 42 | + # by default in the build directory. |
| 43 | + string(REGEX REPLACE "\\$\\(execpath ([^)]+)\\)" "\\1" _CMD "${_CMD}") |
| 44 | + |
| 45 | + # Convert CMake/Unix-style paths with forward slashes to Windows-style with |
| 46 | + # backslashes. It is a bit incorrect to do it as a single cmake_path command |
| 47 | + # on the whole command string, which isn't technically a path, but this should |
| 48 | + # not matter if all what this does is this character substitution. |
| 49 | + # It is not worth implementing a cumbersome fix here, when CMake 4.0 brings |
| 50 | + # the $<PATH:NATIVE_PATH,...> generator expression which is a simpler, better |
| 51 | + # fix here. TODO(bjacob): use that generator expression in the above string |
| 52 | + # replace command directly, whenever we can rely on CMake 4.0. |
| 53 | + cmake_path(NATIVE_PATH _CMD _CMD) |
| 54 | + |
| 55 | + # CMake add_custom_command expects a list as the command, so we replace spaces |
| 56 | + # by semicolon here. Careful to avoid replacing backslash-escaped spaces. |
| 57 | + string(REGEX REPLACE "([^\\]) " "\\1;" _CMD "${_CMD}") |
| 58 | + |
| 59 | + add_custom_command( |
| 60 | + OUTPUT |
| 61 | + "${_RULE_OUTS}" |
| 62 | + COMMAND |
| 63 | + ${_CMD} |
| 64 | + DEPENDS |
| 65 | + "${_RULE_SRCS}" |
| 66 | + COMMENT |
| 67 | + "Generating ${_RULE_OUTS}" |
| 68 | + VERBATIM |
| 69 | + ) |
| 70 | + |
| 71 | + add_custom_target("${_RULE_NAME}" |
| 72 | + DEPENDS "${_RULE_OUTS}" |
| 73 | + ) |
| 74 | +endfunction() |
0 commit comments