Skip to content

[UR] Support conditional symbols in linker scripts #18629

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions unified-runtime/cmake/helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -264,3 +264,20 @@ function(FetchContentSparse_Declare name GIT_REPOSITORY GIT_TAG GIT_DIR)
FetchSource(${GIT_REPOSITORY} ${GIT_TAG} ${GIT_DIR} ${content-build-dir})
FetchContent_Declare(${name} SOURCE_DIR ${content-build-dir}/${GIT_DIR})
endfunction()

function(configure_linker_file input output)
# Configure the input file into a temporary file, this needs to happen
# first in order to keep default configure_file() behaviour when the input
# file is changed to avoid going out of sync with in-tree
set(tmp ${output}.tmp)
configure_file(${input} ${tmp} ${ARGN})
# Strip guarded lines and capture stripped content from stdout
execute_process(
COMMAND ${PYTHON_EXECUTABLE}
${PROJECT_SOURCE_DIR}/scripts/strip-guarded-lines.py ${tmp}
# List names of guarded blocks to include in the output file here
OUTPUT_VARIABLE stripped
)
# Write stripped output to file for use by the linker
file(GENERATE OUTPUT ${output} CONTENT "${stripped}")
endfunction()
Empty file.
135 changes: 135 additions & 0 deletions unified-runtime/scripts/strip-guarded-lines.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#!/usr/bin/env python3

# Copyright (C) 2025 Intel Corporation
#
# Part of the Unified-Runtime Project, under the Apache License v2.0 with LLVM Exceptions.
# See LICENSE.TXT
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception


"""
This script is a basic pre-processor which deals with conditionally excluding
blocks of lines based on pre and post guard marker lines, a list of guard
names to include in the output, and an input file.

- Pre and post guard marker lines will always be removed even when those guard
names have not been specified for inclusion.
- Lines within guard blocks which are not specified for inclusion are always
removed.
- Lines within guard blocks which are specified for inclusion will be always be
included in the output file.
- All other lines not within guard blocks are always included in the output
file.
"""

from argparse import ArgumentParser, FileType, RawDescriptionHelpFormatter
import re
from sys import stdout
from typing import List, Tuple, Union


def _create_guards(pre: str, post: str, names: List[str]) -> List[Tuple[str, str]]:
guards = []
for name in names:
guards.append(
(
pre % name if "%s" in pre else pre,
post % name if "%s" in post else post,
)
)
return guards


def _is_guard(marker: str, line: str) -> bool:
line = line.strip()
marker = marker.replace("%s", r"[A-Za-z0-9][A-Za-z0-9_]+")
if re.match(marker, line):
return True
return False


def _find_guard(
line: str, guards: List[Tuple[str, str]]
) -> Union[Tuple[str, str], None]:
line = line.strip()
for guard in guards:
if guard[0] in line or guard[1] in line:
return guard
return None


def strip_guarded_lines(
inlines: List[str],
pre: str,
post: str,
names: List[str],
) -> List[str]:
guards = _create_guards(pre, post, names)
stack = []
outlines = []
for line in inlines:
if _is_guard(pre, line):
stack.append(_find_guard(line, guards))
continue
elif _is_guard(post, line):
guard = stack.pop()
if guard:
assert _is_guard(
guard[1], line
), f'interleaved guard found: "{guard[1]}" before "{line.strip()}"'
continue
else:
if not all(stack):
continue
outlines.append(line)
return outlines


def main():
parser = ArgumentParser(
description=__doc__, formatter_class=RawDescriptionHelpFormatter
)
parser.add_argument(
"infile", type=FileType("r"), help="input file to strip guarded lines from"
)
group = parser.add_mutually_exclusive_group()
group.add_argument(
"-o",
"--outfile",
type=FileType("w"),
default=stdout,
help="file to write to stripped output to, default: stdout",
)
group.add_argument(
"-i", "--in-place", action="store_true", help="write to input file in-place"
)
parser.add_argument("--encoding", help="encoding to be used for the outfile")
parser.add_argument(
"--pre",
default="#if %s",
help='pre-guard marker where %%s is the guard name, default: "#if %%s"',
)
parser.add_argument(
"--post",
default="#endif",
help='post-guard market where %%s is the guard name, default: "#endif"',
)
parser.add_argument("guards", nargs="*", help="names of guards to strip lines of")
args = parser.parse_args()

inlines = args.infile.readlines()
if args.in_place:
args.infile.close()
args.outfile = open(args.infile.name, "w")
if args.encoding:
args.outfile.reconfigure(encoding=args.encoding)

outlines = strip_guarded_lines(inlines, args.pre, args.post, args.guards)
args.outfile.writelines(outlines)


if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
exit(130)
4 changes: 2 additions & 2 deletions unified-runtime/scripts/templates/api_funcs.def.mako
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ _UR_API(${th.make_func_name(n, tags, obj)})
%endfor
%endfor
%for obj in th.get_loader_functions(specs, meta, n, tags):
%if n + "Loader" in obj:
_UR_API(${obj})
%if n + "Loader" in obj['name']:
_UR_API(${obj['name']})
%endif
%endfor
Loading