Skip to content

Commit 14871ac

Browse files
authored
Use the same patching script and command for all repos (#584)
To simplify patching, the script used for the LLVM repo can be expanded for use on all repos. This also updates the newlib patch to use the same format as llvm-project and picolibc; using git's patch format means the .patch file is compatible with both git am and git apply, whereas a simple diff only works with git apply. This also adds an option to control the patch method used by the script, since using git am may be preferable to the default git apply. The script already supports the option, so all that is needed to pass down the selection from the CMake cache if present. The --3way option has been removed as a default when using --apply, since it can leave conflict markers in place which will not get detected by the script or CMake and will lead to a compilation error. Instead, an option to the script has been added to use --3way. Since --check --apply --3way does not return an error code when the patch is valid but contains conflicts, the --restore_on_fail is now marked as incompatible with that combination.
1 parent e1d7bc9 commit 14871ac

File tree

6 files changed

+94
-32
lines changed

6 files changed

+94
-32
lines changed

cmake/fetch_llvm.cmake

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,25 +5,24 @@
55
# top level to any library builds to prevent repeated checkouts.
66

77
include(FetchContent)
8+
include(${CMAKE_CURRENT_LIST_DIR}/patch_repo.cmake)
89

910
if(NOT VERSIONS_JSON)
1011
include(${CMAKE_CURRENT_LIST_DIR}/read_versions.cmake)
1112
endif()
1213
read_repo_version(llvmproject llvm-project)
13-
14-
set(llvm_patch_script ${CMAKE_CURRENT_LIST_DIR}/patch_llvm.py)
15-
set(patch_dir ${CMAKE_CURRENT_LIST_DIR}/../patches)
16-
set(LLVM_PATCH_COMMAND ${Python3_EXECUTABLE} ${llvm_patch_script} ${patch_dir}/llvm-project)
14+
get_patch_command(${CMAKE_CURRENT_LIST_DIR}/.. llvm-project llvm_patch_command)
1715
if(APPLY_LLVM_PERFORMANCE_PATCHES)
18-
set(LLVM_PATCH_COMMAND ${LLVM_PATCH_COMMAND} && ${Python3_EXECUTABLE} ${llvm_patch_script} ${patch_dir}/llvm-project-perf)
16+
get_patch_command(${CMAKE_CURRENT_LIST_DIR}/.. llvm-project-perf llvm_perf_patch_command)
17+
set(llvm_patch_command ${llvm_patch_command} && ${llvm_perf_patch_command} )
1918
endif()
2019

2120
FetchContent_Declare(llvmproject
2221
GIT_REPOSITORY https://github.com/llvm/llvm-project.git
2322
GIT_TAG "${llvmproject_TAG}"
2423
GIT_SHALLOW "${llvmproject_SHALLOW}"
2524
GIT_PROGRESS TRUE
26-
PATCH_COMMAND ${LLVM_PATCH_COMMAND}
25+
PATCH_COMMAND ${llvm_patch_command}
2726
# Add the llvm subdirectory later to ensure that
2827
# LLVMEmbeddedToolchainForArm is the first project declared.
2928
# Otherwise CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT

cmake/fetch_newlib.cmake

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55
# top level to any library builss to prevent repeated checkouts.
66

77
include(FetchContent)
8+
include(${CMAKE_CURRENT_LIST_DIR}/patch_repo.cmake)
89

910
if(NOT VERSIONS_JSON)
1011
include(${CMAKE_CURRENT_LIST_DIR}/read_versions.cmake)
1112
endif()
1213
read_repo_version(newlib newlib)
13-
14-
set(newlib_patch ${CMAKE_CURRENT_LIST_DIR}/../patches/newlib.patch)
14+
get_patch_command(${CMAKE_CURRENT_LIST_DIR}/.. newlib newlib_patch_command)
1515

1616
FetchContent_Declare(newlib
1717
GIT_REPOSITORY https://sourceware.org/git/newlib-cygwin.git
1818
GIT_TAG "${newlib_TAG}"
1919
GIT_SHALLOW "${newlib_SHALLOW}"
2020
GIT_PROGRESS TRUE
21-
PATCH_COMMAND git reset --quiet --hard && git clean --quiet --force -dx && git apply ${newlib_patch}
21+
PATCH_COMMAND ${newlib_patch_command}
2222
# Similarly to picolibc, we don't do the configuration here.
2323
SOURCE_SUBDIR do_not_add_newlib_subdir
2424
)

cmake/fetch_picolibc.cmake

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,20 @@
55
# top level to any library builss to prevent repeated checkouts.
66

77
include(FetchContent)
8+
include(${CMAKE_CURRENT_LIST_DIR}/patch_repo.cmake)
89

910
if(NOT VERSIONS_JSON)
1011
include(${CMAKE_CURRENT_LIST_DIR}/read_versions.cmake)
1112
endif()
1213
read_repo_version(picolibc picolibc)
13-
14-
set(
15-
picolibc_patches
16-
${CMAKE_CURRENT_LIST_DIR}/../patches/picolibc/0001-Enable-libcxx-builds.patch
17-
${CMAKE_CURRENT_LIST_DIR}/../patches/picolibc/0002-Add-bootcode-for-AArch64-FVPs.patch
18-
)
14+
get_patch_command(${CMAKE_CURRENT_LIST_DIR}/.. picolibc picolibc_patch_command)
1915

2016
FetchContent_Declare(picolibc
2117
GIT_REPOSITORY https://github.com/picolibc/picolibc.git
2218
GIT_TAG "${picolibc_TAG}"
2319
GIT_SHALLOW "${picolibc_SHALLOW}"
2420
GIT_PROGRESS TRUE
25-
PATCH_COMMAND git reset --quiet --hard && git clean --quiet --force -dx && git apply ${picolibc_patches}
21+
PATCH_COMMAND ${picolibc_patch_command}
2622
# We only want to download the content, not configure it at this
2723
# stage. picolibc will be built in many configurations using
2824
# ExternalProject_Add using the sources that are checked out here.

cmake/patch_repo.cmake

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
# Function to generate a PATCH_COMMAND, calling the
3+
# patch_repo.py script using a target set of patches.
4+
5+
function(get_patch_command toolchain_root patch_dir patch_command_out)
6+
set(patch_script ${toolchain_root}/cmake/patch_repo.py)
7+
list(APPEND patch_script_args ${Python3_EXECUTABLE} ${patch_script})
8+
if(GIT_PATCH_METHOD STREQUAL "am")
9+
list(APPEND patch_script_args "--method" "am")
10+
elseif(GIT_PATCH_METHOD STREQUAL "apply")
11+
list(APPEND patch_script_args "--method" "apply")
12+
endif()
13+
list(APPEND patch_script_args ${toolchain_root}/patches/${patch_dir})
14+
15+
set(${patch_command_out} ${patch_script_args} PARENT_SCOPE)
16+
endfunction()

cmake/patch_llvm.py renamed to cmake/patch_repo.py

Lines changed: 34 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
#!/usr/bin/env python3
22

33
"""
4-
Script to apply a set of patches to llvm-project sources.
4+
Script to apply a set of patches to a git repository.
55
"""
66

77
import argparse
@@ -18,8 +18,8 @@ def main():
1818
help="Set of patches to apply. This should be a directory containing one or more ordered *.patch files.",
1919
)
2020
parser.add_argument(
21-
"--llvm_dir",
22-
help="Directory of the llvm-project git checkout, if not the current directory.",
21+
"--repo_dir",
22+
help="Directory of the git checkout, if not the current directory.",
2323
)
2424
parser.add_argument(
2525
"--method",
@@ -36,10 +36,24 @@ def main():
3636
action="store_true",
3737
help="If a patch in a series cannot be applied, restore the original state instead of leaving patches missing. Return code will be 2 instead of 1.",
3838
)
39+
parser.add_argument(
40+
"--3way",
41+
action="store_true",
42+
dest="three_way",
43+
help="If the patch does not apply cleanly, fall back on 3-way merge.",
44+
)
3945
args = parser.parse_args()
4046

41-
if args.llvm_dir:
42-
git_cmd = ["git", "-C", args.llvm_dir]
47+
# If the patch is valid but contain conflicts, using --3way --apply can apply
48+
# the patch but leave conflict markers in the source for the user to resolve.
49+
# This doesn't return an error code, making it compatible with this script's
50+
# --restore_on_fail option, which relies on the error code from running --check.
51+
if args.method == "apply" and args.restore_on_fail and args.three_way:
52+
print("--restore_on_fail is incompatible with --3way using apply")
53+
exit(1)
54+
55+
if args.repo_dir:
56+
git_cmd = ["git", "-C", args.repo_dir]
4357
else:
4458
git_cmd = ["git"]
4559

@@ -57,7 +71,9 @@ def main():
5771
print("\n".join(p.name for p in patch_list))
5872

5973
if args.method == "am":
60-
merge_args = git_cmd + ["am", "-k", "--ignore-whitespace", "--3way"]
74+
merge_args = git_cmd + ["am", "-k", "--ignore-whitespace"]
75+
if args.three_way:
76+
merge_args.append("--3way")
6177
for patch in patch_list:
6278
merge_args.append(str(patch))
6379
p = subprocess.run(merge_args, capture_output=True, text=True)
@@ -72,8 +88,8 @@ def main():
7288
# git am doesn't give any specific return codes,
7389
# so check for unresolved working files.
7490
rebase_apply_path = os.path.join(".git", "rebase-apply")
75-
if args.llvm_dir:
76-
rebase_apply_path = os.path.join(args.llvm_dir, rebase_apply_path)
91+
if args.repo_dir:
92+
rebase_apply_path = os.path.join(args.repo_dir, rebase_apply_path)
7793
if os.path.isdir(rebase_apply_path):
7894
print("Aborting git am...")
7995
subprocess.run(git_cmd + ["am", "--abort"], check=True)
@@ -90,10 +106,11 @@ def main():
90106
apply_check_args = git_cmd + [
91107
"apply",
92108
"--ignore-whitespace",
93-
"--3way",
94109
"--check",
95-
str(current_patch),
96110
]
111+
if args.three_way:
112+
apply_check_args.append("--3way")
113+
apply_check_args.append(str(current_patch))
97114
p_check = subprocess.run(apply_check_args)
98115

99116
if p_check.returncode == 0:
@@ -102,10 +119,11 @@ def main():
102119
apply_args = git_cmd + [
103120
"apply",
104121
"--ignore-whitespace",
105-
"--3way",
106-
str(current_patch),
107122
]
108-
apply_args = subprocess.run(apply_args, check=True)
123+
if args.three_way:
124+
apply_args.append("--3way")
125+
apply_args.append(str(current_patch))
126+
p = subprocess.run(apply_args, check=True)
109127
applied_patches.append(current_patch)
110128
else:
111129
# Patch won't apply.
@@ -118,10 +136,11 @@ def main():
118136
reverse_args = git_cmd + [
119137
"apply",
120138
"--ignore-whitespace",
121-
"--3way",
122139
"--reverse",
123-
str(previous_patch),
124140
]
141+
if args.three_way:
142+
reverse_args.append("--3way")
143+
reverse_args.append(str(previous_patch))
125144
p_check = subprocess.run(reverse_args, check=True)
126145
print(
127146
f"Rollback successful, failure occured on {current_patch.name}"

patches/newlib.patch renamed to patches/newlib/0001-Enable-newlib-build.patch

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,40 @@
1+
From 0e1475e5112b986ef5d9caee23dac554c749c54b Mon Sep 17 00:00:00 2001
2+
From: David Candler <[email protected]>
3+
Date: Thu, 28 Nov 2024 15:31:35 +0000
4+
Subject: [PATCH] Enable newlib build
5+
6+
---
7+
libgloss/aarch64/syscalls.c | 6 ++
8+
libgloss/arm/cpu-init/rdimon-aem.S | 107 ++++++++++++------------
9+
libgloss/arm/crt0.S | 2 +-
10+
libgloss/arm/linux-crt0.c | 2 +-
11+
libgloss/arm/syscalls.c | 6 +-
12+
libgloss/arm/trap.S | 2 +-
13+
libgloss/libnosys/configure | 2 +-
14+
newlib/libc/include/sys/features.h | 2 +
15+
newlib/libc/machine/aarch64/memchr.S | 6 +-
16+
newlib/libc/machine/aarch64/strchr.S | 6 +-
17+
newlib/libc/machine/aarch64/strchrnul.S | 6 +-
18+
newlib/libc/machine/aarch64/strrchr.S | 10 +--
19+
newlib/libc/stdlib/aligned_alloc.c | 1 +
20+
newlib/libc/sys/arm/crt0.S | 2 +-
21+
newlib/libc/sys/arm/trap.S | 2 +-
22+
newlib/libm/machine/arm/sf_ceil.c | 2 +-
23+
newlib/libm/machine/arm/sf_floor.c | 2 +-
24+
newlib/libm/machine/arm/sf_nearbyint.c | 2 +-
25+
newlib/libm/machine/arm/sf_rint.c | 2 +-
26+
newlib/libm/machine/arm/sf_round.c | 2 +-
27+
newlib/libm/machine/arm/sf_trunc.c | 2 +-
28+
21 files changed, 92 insertions(+), 82 deletions(-)
29+
130
diff --git a/libgloss/aarch64/syscalls.c b/libgloss/aarch64/syscalls.c
231
index 7343cc61f..2c4b63c17 100644
332
--- a/libgloss/aarch64/syscalls.c
433
+++ b/libgloss/aarch64/syscalls.c
534
@@ -172,6 +172,12 @@ newslot (void)
635
return i;
736
}
8-
37+
938
+int __aarch64_sme_accessible() {
1039
+ int result = 0;
1140
+ asm volatile ( "mrs %x[result], id_aa64pfr1_el1" : [result]"=r"(result) : : );
@@ -635,3 +664,6 @@ index 64e4aeb9a..c08fa6fed 100644
635664
#include <math.h>
636665

637666
float
667+
--
668+
2.43.0
669+

0 commit comments

Comments
 (0)