Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'linux_kselftest-nolibc-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull nolibc updates from Shuah Khan:
"Highlights:

- Clang support (including LTO)

Other Changes:

- stdbool.h support

- argc/argv/envp arguments for constructors

- Small #include ordering fix"

* tag 'linux_kselftest-nolibc-6.12-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest: (21 commits)
tools/nolibc: x86_64: use local label in memcpy/memmove
tools/nolibc: stackprotector: mark implicitly used symbols as used
tools/nolibc: crt: mark _start_c() as used
selftests/nolibc: run-tests.sh: allow building through LLVM
selftests/nolibc: use correct clang target for s390/systemz
selftests/nolibc: don't use libgcc when building with clang
selftests/nolibc: run-tests.sh: avoid overwriting CFLAGS_EXTRA
selftests/nolibc: add cc-option compatible with clang cross builds
selftests/nolibc: add support for LLVM= parameter
selftests/nolibc: determine $(srctree) first
selftests/nolibc: avoid passing NULL to printf("%s")
selftests/nolibc: report failure if no testcase passed
tools/nolibc: compiler: use attribute((naked)) if available
tools/nolibc: move entrypoint specifics to compiler.h
tools/nolibc: compiler: introduce __nolibc_has_attribute()
tools/nolibc: powerpc: limit stack-protector workaround to GCC
tools/nolibc: mips: load current function to $t9
tools/nolibc: arm: use clang-compatible asm syntax
tools/nolibc: pass argc, argv and envp to constructors
tools/nolibc: add stdbool.h header
...

+123 -67
+1
tools/include/nolibc/Makefile
··· 35 35 stackprotector.h \ 36 36 std.h \ 37 37 stdarg.h \ 38 + stdbool.h \ 38 39 stdint.h \ 39 40 stdlib.h \ 40 41 string.h \
+2 -2
tools/include/nolibc/arch-aarch64.h
··· 142 142 }) 143 143 144 144 /* startup code */ 145 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void) 145 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 146 146 { 147 147 __asm__ volatile ( 148 148 "mov x0, sp\n" /* save stack pointer to x0, as arg1 of _start_c */ 149 149 "and sp, x0, -16\n" /* sp must be 16-byte aligned in the callee */ 150 150 "bl _start_c\n" /* transfer to c runtime */ 151 151 ); 152 - __builtin_unreachable(); 152 + __nolibc_entrypoint_epilogue(); 153 153 } 154 154 #endif /* _NOLIBC_ARCH_AARCH64_H */
+4 -4
tools/include/nolibc/arch-arm.h
··· 185 185 }) 186 186 187 187 /* startup code */ 188 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void) 188 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 189 189 { 190 190 __asm__ volatile ( 191 - "mov %r0, sp\n" /* save stack pointer to %r0, as arg1 of _start_c */ 192 - "and ip, %r0, #-8\n" /* sp must be 8-byte aligned in the callee */ 191 + "mov r0, sp\n" /* save stack pointer to %r0, as arg1 of _start_c */ 192 + "and ip, r0, #-8\n" /* sp must be 8-byte aligned in the callee */ 193 193 "mov sp, ip\n" 194 194 "bl _start_c\n" /* transfer to c runtime */ 195 195 ); 196 - __builtin_unreachable(); 196 + __nolibc_entrypoint_epilogue(); 197 197 } 198 198 199 199 #endif /* _NOLIBC_ARCH_ARM_H */
+2 -2
tools/include/nolibc/arch-i386.h
··· 162 162 * 2) The deepest stack frame should be set to zero 163 163 * 164 164 */ 165 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void) 165 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 166 166 { 167 167 __asm__ volatile ( 168 168 "xor %ebp, %ebp\n" /* zero the stack frame */ ··· 174 174 "call _start_c\n" /* transfer to c runtime */ 175 175 "hlt\n" /* ensure it does not return */ 176 176 ); 177 - __builtin_unreachable(); 177 + __nolibc_entrypoint_epilogue(); 178 178 } 179 179 180 180 #endif /* _NOLIBC_ARCH_I386_H */
+2 -2
tools/include/nolibc/arch-loongarch.h
··· 149 149 #endif 150 150 151 151 /* startup code */ 152 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void) 152 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 153 153 { 154 154 __asm__ volatile ( 155 155 "move $a0, $sp\n" /* save stack pointer to $a0, as arg1 of _start_c */ 156 156 LONG_BSTRINS " $sp, $zero, 3, 0\n" /* $sp must be 16-byte aligned */ 157 157 "bl _start_c\n" /* transfer to c runtime */ 158 158 ); 159 - __builtin_unreachable(); 159 + __nolibc_entrypoint_epilogue(); 160 160 } 161 161 162 162 #endif /* _NOLIBC_ARCH_LOONGARCH_H */
+5 -3
tools/include/nolibc/arch-mips.h
··· 179 179 }) 180 180 181 181 /* startup code, note that it's called __start on MIPS */ 182 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector __start(void) 182 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector __start(void) 183 183 { 184 184 __asm__ volatile ( 185 185 ".set push\n" ··· 194 194 "li $t0, -8\n" 195 195 "and $sp, $sp, $t0\n" /* $sp must be 8-byte aligned */ 196 196 "addiu $sp, $sp, -16\n" /* the callee expects to save a0..a3 there */ 197 - "jal _start_c\n" /* transfer to c runtime */ 197 + "lui $t9, %hi(_start_c)\n" /* ABI requires current function address in $t9 */ 198 + "ori $t9, %lo(_start_c)\n" 199 + "jalr $t9\n" /* transfer to c runtime */ 198 200 " nop\n" /* delayed slot */ 199 201 ".set pop\n" 200 202 ); 201 - __builtin_unreachable(); 203 + __nolibc_entrypoint_epilogue(); 202 204 } 203 205 204 206 #endif /* _NOLIBC_ARCH_MIPS_H */
+3 -3
tools/include/nolibc/arch-powerpc.h
··· 172 172 _ret; \ 173 173 }) 174 174 175 - #ifndef __powerpc64__ 175 + #if !defined(__powerpc64__) && !defined(__clang__) 176 176 /* FIXME: For 32-bit PowerPC, with newer gcc compilers (e.g. gcc 13.1.0), 177 177 * "omit-frame-pointer" fails with __attribute__((no_stack_protector)) but 178 178 * works with __attribute__((__optimize__("-fno-stack-protector"))) ··· 184 184 #endif /* !__powerpc64__ */ 185 185 186 186 /* startup code */ 187 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void) 187 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 188 188 { 189 189 #ifdef __powerpc64__ 190 190 #if _CALL_ELF == 2 ··· 215 215 "bl _start_c\n" /* transfer to c runtime */ 216 216 ); 217 217 #endif 218 - __builtin_unreachable(); 218 + __nolibc_entrypoint_epilogue(); 219 219 } 220 220 221 221 #endif /* _NOLIBC_ARCH_POWERPC_H */
+2 -2
tools/include/nolibc/arch-riscv.h
··· 140 140 }) 141 141 142 142 /* startup code */ 143 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void) 143 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 144 144 { 145 145 __asm__ volatile ( 146 146 ".option push\n" ··· 151 151 "andi sp, a0, -16\n" /* sp must be 16-byte aligned */ 152 152 "call _start_c\n" /* transfer to c runtime */ 153 153 ); 154 - __builtin_unreachable(); 154 + __nolibc_entrypoint_epilogue(); 155 155 } 156 156 157 157 #endif /* _NOLIBC_ARCH_RISCV_H */
+2 -2
tools/include/nolibc/arch-s390.h
··· 139 139 }) 140 140 141 141 /* startup code */ 142 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void) 142 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 143 143 { 144 144 __asm__ volatile ( 145 145 "lgr %r2, %r15\n" /* save stack pointer to %r2, as arg1 of _start_c */ ··· 147 147 "xc 0(8,%r15), 0(%r15)\n" /* clear backchain */ 148 148 "brasl %r14, _start_c\n" /* transfer to c runtime */ 149 149 ); 150 - __builtin_unreachable(); 150 + __nolibc_entrypoint_epilogue(); 151 151 } 152 152 153 153 struct s390_mmap_arg_struct {
+4 -4
tools/include/nolibc/arch-x86_64.h
··· 161 161 * 2) The deepest stack frame should be zero (the %rbp). 162 162 * 163 163 */ 164 - void __attribute__((weak, noreturn, optimize("Os", "omit-frame-pointer"))) __no_stack_protector _start(void) 164 + void __attribute__((weak, noreturn)) __nolibc_entrypoint __no_stack_protector _start(void) 165 165 { 166 166 __asm__ volatile ( 167 167 "xor %ebp, %ebp\n" /* zero the stack frame */ ··· 170 170 "call _start_c\n" /* transfer to c runtime */ 171 171 "hlt\n" /* ensure it does not return */ 172 172 ); 173 - __builtin_unreachable(); 173 + __nolibc_entrypoint_epilogue(); 174 174 } 175 175 176 176 #define NOLIBC_ARCH_HAS_MEMMOVE ··· 193 193 "movq %rdi, %rdx\n\t" 194 194 "subq %rsi, %rdx\n\t" 195 195 "cmpq %rcx, %rdx\n\t" 196 - "jb .Lbackward_copy\n\t" 196 + "jb 1f\n\t" 197 197 "rep movsb\n\t" 198 198 "retq\n" 199 - ".Lbackward_copy:" 199 + "1:" /* backward copy */ 200 200 "leaq -1(%rdi, %rcx, 1), %rdi\n\t" 201 201 "leaq -1(%rsi, %rcx, 1), %rsi\n\t" 202 202 "std\n\t"
+17 -7
tools/include/nolibc/compiler.h
··· 6 6 #ifndef _NOLIBC_COMPILER_H 7 7 #define _NOLIBC_COMPILER_H 8 8 9 + #if defined(__has_attribute) 10 + # define __nolibc_has_attribute(attr) __has_attribute(attr) 11 + #else 12 + # define __nolibc_has_attribute(attr) 0 13 + #endif 14 + 15 + #if __nolibc_has_attribute(naked) 16 + # define __nolibc_entrypoint __attribute__((naked)) 17 + # define __nolibc_entrypoint_epilogue() 18 + #else 19 + # define __nolibc_entrypoint __attribute__((optimize("Os", "omit-frame-pointer"))) 20 + # define __nolibc_entrypoint_epilogue() __builtin_unreachable() 21 + #endif /* __nolibc_has_attribute(naked) */ 22 + 9 23 #if defined(__SSP__) || defined(__SSP_STRONG__) || defined(__SSP_ALL__) || defined(__SSP_EXPLICIT__) 10 24 11 25 #define _NOLIBC_STACKPROTECTOR 12 26 13 27 #endif /* defined(__SSP__) ... */ 14 28 15 - #if defined(__has_attribute) 16 - # if __has_attribute(no_stack_protector) 17 - # define __no_stack_protector __attribute__((no_stack_protector)) 18 - # else 19 - # define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector"))) 20 - # endif 29 + #if __nolibc_has_attribute(no_stack_protector) 30 + # define __no_stack_protector __attribute__((no_stack_protector)) 21 31 #else 22 32 # define __no_stack_protector __attribute__((__optimize__("-fno-stack-protector"))) 23 - #endif /* defined(__has_attribute) */ 33 + #endif /* __nolibc_has_attribute(no_stack_protector) */ 24 34 25 35 #endif /* _NOLIBC_COMPILER_H */
+13 -12
tools/include/nolibc/crt.h
··· 13 13 static void __stack_chk_init(void); 14 14 static void exit(int); 15 15 16 - extern void (*const __preinit_array_start[])(void) __attribute__((weak)); 17 - extern void (*const __preinit_array_end[])(void) __attribute__((weak)); 16 + extern void (*const __preinit_array_start[])(int, char **, char**) __attribute__((weak)); 17 + extern void (*const __preinit_array_end[])(int, char **, char**) __attribute__((weak)); 18 18 19 - extern void (*const __init_array_start[])(void) __attribute__((weak)); 20 - extern void (*const __init_array_end[])(void) __attribute__((weak)); 19 + extern void (*const __init_array_start[])(int, char **, char**) __attribute__((weak)); 20 + extern void (*const __init_array_end[])(int, char **, char**) __attribute__((weak)); 21 21 22 22 extern void (*const __fini_array_start[])(void) __attribute__((weak)); 23 23 extern void (*const __fini_array_end[])(void) __attribute__((weak)); 24 24 25 - __attribute__((weak)) 25 + __attribute__((weak,used)) 26 26 void _start_c(long *sp) 27 27 { 28 28 long argc; 29 29 char **argv; 30 30 char **envp; 31 31 int exitcode; 32 - void (* const *func)(void); 32 + void (* const *ctor_func)(int, char **, char **); 33 + void (* const *dtor_func)(void); 33 34 const unsigned long *auxv; 34 35 /* silence potential warning: conflicting types for 'main' */ 35 36 int _nolibc_main(int, char **, char **) __asm__ ("main"); ··· 67 66 ; 68 67 _auxv = auxv; 69 68 70 - for (func = __preinit_array_start; func < __preinit_array_end; func++) 71 - (*func)(); 72 - for (func = __init_array_start; func < __init_array_end; func++) 73 - (*func)(); 69 + for (ctor_func = __preinit_array_start; ctor_func < __preinit_array_end; ctor_func++) 70 + (*ctor_func)(argc, argv, envp); 71 + for (ctor_func = __init_array_start; ctor_func < __init_array_end; ctor_func++) 72 + (*ctor_func)(argc, argv, envp); 74 73 75 74 /* go to application */ 76 75 exitcode = _nolibc_main(argc, argv, envp); 77 76 78 - for (func = __fini_array_end; func > __fini_array_start;) 79 - (*--func)(); 77 + for (dtor_func = __fini_array_end; dtor_func > __fini_array_start;) 78 + (*--dtor_func)(); 80 79 81 80 exit(exitcode); 82 81 }
+2 -1
tools/include/nolibc/nolibc.h
··· 74 74 * -I../nolibc -o hello hello.c -lgcc 75 75 * 76 76 * The available standard (but limited) include files are: 77 - * ctype.h, errno.h, signal.h, stdarg.h, stdio.h, stdlib.h, string.h, time.h 77 + * ctype.h, errno.h, signal.h, stdarg.h, stdbool.h stdio.h, stdlib.h, 78 + * string.h, time.h 78 79 * 79 80 * In addition, the following ones are expected to be provided by the compiler: 80 81 * float.h, stddef.h
+2 -2
tools/include/nolibc/stackprotector.h
··· 18 18 * triggering stack protector errors themselves 19 19 */ 20 20 21 - __attribute__((weak,noreturn,section(".text.nolibc_stack_chk"))) 21 + __attribute__((weak,used,noreturn,section(".text.nolibc_stack_chk"))) 22 22 void __stack_chk_fail(void) 23 23 { 24 24 pid_t pid; ··· 34 34 __stack_chk_fail(); 35 35 } 36 36 37 - __attribute__((weak,section(".data.nolibc_stack_chk"))) 37 + __attribute__((weak,used,section(".data.nolibc_stack_chk"))) 38 38 uintptr_t __stack_chk_guard; 39 39 40 40 static __no_stack_protector void __stack_chk_init(void)
+16
tools/include/nolibc/stdbool.h
··· 1 + /* SPDX-License-Identifier: LGPL-2.1 OR MIT */ 2 + /* 3 + * Boolean types support for NOLIBC 4 + * Copyright (C) 2024 Thomas Weißschuh <linux@weissschuh.net> 5 + */ 6 + 7 + #ifndef _NOLIBC_STDBOOL_H 8 + #define _NOLIBC_STDBOOL_H 9 + 10 + #define bool _Bool 11 + #define true 1 12 + #define false 0 13 + 14 + #define __bool_true_false_are_defined 1 15 + 16 + #endif /* _NOLIBC_STDBOOL_H */
+1
tools/include/nolibc/string.h
··· 7 7 #ifndef _NOLIBC_STRING_H 8 8 #define _NOLIBC_STRING_H 9 9 10 + #include "arch.h" 10 11 #include "std.h" 11 12 12 13 static void *malloc(size_t len);
+28 -13
tools/testing/selftests/nolibc/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 # Makefile for nolibc tests 3 - include ../../../scripts/Makefile.include 4 - include ../../../scripts/utilities.mak 5 - # We need this for the "cc-option" macro. 6 - include ../../../build/Build.include 3 + # we're in ".../tools/testing/selftests/nolibc" 4 + ifeq ($(srctree),) 5 + srctree := $(patsubst %/tools/testing/selftests/,%,$(dir $(CURDIR))) 6 + endif 7 + 8 + include $(srctree)/tools/scripts/utilities.mak 9 + # We need this for the "__cc-option" macro. 10 + include $(srctree)/scripts/Makefile.compiler 7 11 8 12 ifneq ($(O),) 9 13 ifneq ($(call is-absolute,$(O)),y) 10 14 $(error Only absolute O= parameters are supported) 11 15 endif 12 - endif 13 - 14 - # we're in ".../tools/testing/selftests/nolibc" 15 - ifeq ($(srctree),) 16 - srctree := $(patsubst %/tools/testing/selftests/,%,$(dir $(CURDIR))) 16 + objtree := $(O) 17 + else 18 + objtree ?= $(srctree) 17 19 endif 18 20 19 21 ifeq ($(ARCH),) ··· 23 21 ARCH = $(SUBARCH) 24 22 endif 25 23 26 - objtree ?= $(srctree) 24 + cc-option = $(call __cc-option, $(CC),$(CLANG_CROSS_FLAGS),$(1),$(2)) 27 25 28 26 # XARCH extends the kernel's ARCH with a few variants of the same 29 27 # architecture that only differ by the configuration, the toolchain ··· 157 155 $(CFLAGS_$(XARCH)) $(CFLAGS_STACKPROTECTOR) $(CFLAGS_EXTRA) 158 156 LDFLAGS := 159 157 158 + LIBGCC := -lgcc 159 + 160 + ifneq ($(LLVM),) 161 + # Not needed for clang 162 + LIBGCC := 163 + endif 164 + 165 + # Modify CFLAGS based on LLVM= 166 + include $(srctree)/tools/scripts/Makefile.include 167 + 168 + # GCC uses "s390", clang "systemz" 169 + CLANG_CROSS_FLAGS := $(subst --target=s390-linux,--target=systemz-linux,$(CLANG_CROSS_FLAGS)) 170 + 160 171 REPORT ?= awk '/\[OK\][\r]*$$/{p++} /\[FAIL\][\r]*$$/{if (!f) printf("\n"); f++; print;} /\[SKIPPED\][\r]*$$/{s++} \ 161 172 END{ printf("\n%3d test(s): %3d passed, %3d skipped, %3d failed => status: ", p+s+f, p, s, f); \ 162 - if (f) printf("failure\n"); else if (s) printf("warning\n"); else printf("success\n");; \ 173 + if (f || !p) printf("failure\n"); else if (s) printf("warning\n"); else printf("success\n");; \ 163 174 printf("\nSee all results in %s\n", ARGV[1]); }' 164 175 165 176 help: ··· 219 204 ifneq ($(NOLIBC_SYSROOT),0) 220 205 nolibc-test: nolibc-test.c nolibc-test-linkage.c sysroot/$(ARCH)/include 221 206 $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \ 222 - -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include nolibc-test.c nolibc-test-linkage.c -lgcc 207 + -nostdlib -nostdinc -static -Isysroot/$(ARCH)/include nolibc-test.c nolibc-test-linkage.c $(LIBGCC) 223 208 else 224 209 nolibc-test: nolibc-test.c nolibc-test-linkage.c 225 210 $(QUIET_CC)$(CC) $(CFLAGS) $(LDFLAGS) -o $@ \ 226 - -nostdlib -static -include $(srctree)/tools/include/nolibc/nolibc.h nolibc-test.c nolibc-test-linkage.c -lgcc 211 + -nostdlib -static -include $(srctree)/tools/include/nolibc/nolibc.h nolibc-test.c nolibc-test-linkage.c $(LIBGCC) 227 212 endif 228 213 229 214 libc-test: nolibc-test.c nolibc-test-linkage.c
+5 -4
tools/testing/selftests/nolibc/nolibc-test.c
··· 542 542 { 543 543 int ret = 0; 544 544 545 - llen += printf(" = <%s> ", expr); 545 + llen += printf(" = <%s> ", expr ? expr : "(null)"); 546 546 if (expr) { 547 547 ret = 1; 548 548 result(llen, FAIL); ··· 561 561 { 562 562 int ret = 0; 563 563 564 - llen += printf(" = <%s> ", expr); 564 + llen += printf(" = <%s> ", expr ? expr : "(null)"); 565 565 if (!expr) { 566 566 ret = 1; 567 567 result(llen, FAIL); ··· 686 686 } 687 687 688 688 __attribute__((constructor)) 689 - static void constructor2(void) 689 + static void constructor2(int argc, char **argv, char **envp) 690 690 { 691 - constructor_test_value *= 2; 691 + if (argc && argv && envp) 692 + constructor_test_value *= 2; 692 693 } 693 694 694 695 int run_startup(int min, int max)
+12 -4
tools/testing/selftests/nolibc/run-tests.sh
··· 15 15 build_location="$(realpath "${cache_dir}"/nolibc-tests/)" 16 16 perform_download=0 17 17 test_mode=system 18 - CFLAGS_EXTRA="-Werror" 18 + werror=1 19 + llvm= 19 20 archs="i386 x86_64 arm64 arm mips32le mips32be ppc ppc64 ppc64le riscv s390 loongarch" 20 21 21 - TEMP=$(getopt -o 'j:d:c:b:a:m:peh' -n "$0" -- "$@") 22 + TEMP=$(getopt -o 'j:d:c:b:a:m:pelh' -n "$0" -- "$@") 22 23 23 24 eval set -- "$TEMP" 24 25 unset TEMP ··· 43 42 -b [DIR] Build location (default: ${build_location}) 44 43 -m [MODE] Test mode user/system (default: ${test_mode}) 45 44 -e Disable -Werror 45 + -l Build with LLVM/clang 46 46 EOF 47 47 } 48 48 ··· 71 69 test_mode="$2" 72 70 shift 2; continue ;; 73 71 '-e') 74 - CFLAGS_EXTRA="" 72 + werror=0 73 + shift; continue ;; 74 + '-l') 75 + llvm=1 75 76 shift; continue ;; 76 77 '-h') 77 78 print_usage ··· 145 140 ct_abi=$(crosstool_abi "$1") 146 141 cross_compile=$(realpath "${download_location}gcc-${crosstool_version}-nolibc/${ct_arch}-${ct_abi}/bin/${ct_arch}-${ct_abi}-") 147 142 build_dir="${build_location}/${arch}" 148 - MAKE=(make -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" O="${build_dir}") 143 + if [ "$werror" -ne 0 ]; then 144 + CFLAGS_EXTRA="$CFLAGS_EXTRA -Werror" 145 + fi 146 + MAKE=(make -j"${nproc}" XARCH="${arch}" CROSS_COMPILE="${cross_compile}" LLVM="${llvm}" O="${build_dir}") 149 147 150 148 mkdir -p "$build_dir" 151 149 if [ "$test_mode" = "system" ] && [ ! -f "${build_dir}/.config" ]; then