|
| 1 | +# Linux Kernel-style Toolchain Configuration |
| 2 | +# ============================================ |
| 3 | +# |
| 4 | +# This file implements toolchain detection and configuration following |
| 5 | +# Linux kernel conventions. Supports native and cross-compilation builds. |
| 6 | +# |
| 7 | +# Usage: |
| 8 | +# make # Native build with system compiler |
| 9 | +# make CROSS_COMPILE=arm-none-eabi- # Cross-compile for ARM bare-metal |
| 10 | +# make CC=clang # Use specific compiler |
| 11 | +# make CC=emcc # Build for WebAssembly with Emscripten |
| 12 | +# |
| 13 | +# Reference: https://www.kernel.org/doc/html/latest/kbuild/kbuild.html |
| 14 | + |
| 15 | +# Compiler identification flags |
1 | 16 | CC_IS_CLANG := |
2 | 17 | CC_IS_GCC := |
| 18 | +CC_IS_EMCC := |
3 | 19 |
|
4 | | -# FIXME: Cross-compilation using Clang is not supported. |
5 | | -ifdef CROSS_COMPILE |
6 | | -CC := $(CROSS_COMPILE)gcc |
| 20 | +# Detect host architecture for platform-specific optimizations |
| 21 | +HOSTARCH := $(shell uname -m) |
| 22 | + |
| 23 | +# Set CC based on CROSS_COMPILE or default compiler |
| 24 | +# Check if CC comes from Make's default or command line/environment |
| 25 | +ifeq ($(origin CC),default) |
| 26 | + # CC is Make's built-in default, override it |
| 27 | + ifdef CROSS_COMPILE |
| 28 | + CC := $(CROSS_COMPILE)gcc |
| 29 | + else |
| 30 | + CC := cc |
| 31 | + endif |
7 | 32 | endif |
8 | 33 |
|
9 | | -override CC := $(shell which $(CC)) |
10 | | -ifndef CC |
11 | | -$(error "Valid C compiler not found.") |
| 34 | +# Resolve CC to absolute path and validate |
| 35 | +CC_PATH := $(shell which $(CC) 2>/dev/null) |
| 36 | +ifeq ($(CC_PATH),) |
| 37 | + $(error Compiler '$(CC)' not found. Please install the toolchain or check your PATH.) |
12 | 38 | endif |
| 39 | +override CC := $(CC_PATH) |
13 | 40 |
|
14 | | -ifneq ($(shell $(CC) --version | head -n 1 | grep clang),) |
15 | | -CC_IS_CLANG := 1 |
16 | | -else ifneq ($(shell $(CC) --version | grep "Free Software Foundation"),) |
17 | | -CC_IS_GCC := 1 |
| 41 | +# Compiler type detection (Emscripten, Clang, GCC) |
| 42 | +CC_VERSION := $(shell $(CC) --version 2>/dev/null) |
| 43 | +ifneq ($(findstring emcc,$(CC_VERSION)),) |
| 44 | + CC_IS_EMCC := 1 |
| 45 | +else ifneq ($(findstring clang,$(CC_VERSION)),) |
| 46 | + CC_IS_CLANG := 1 |
| 47 | +else ifneq ($(findstring Free Software Foundation,$(CC_VERSION)),) |
| 48 | + CC_IS_GCC := 1 |
18 | 49 | endif |
19 | 50 |
|
20 | | -ifeq ("$(CC_IS_CLANG)$(CC_IS_GCC)", "") |
21 | | -$(warning Unsupported C compiler) |
| 51 | +# Validate compiler type |
| 52 | +ifeq ($(CC_IS_CLANG)$(CC_IS_GCC)$(CC_IS_EMCC),) |
| 53 | + $(warning Unsupported C compiler: $(CC)) |
22 | 54 | endif |
23 | 55 |
|
| 56 | +# C++ compiler setup |
24 | 57 | ifndef CXX |
25 | | -CXX := $(CROSS_COMPILE)g++ |
26 | | -endif |
27 | | -ifeq ("$(CC_IS_CLANG)", "1") |
28 | | -override CXX := $(subst clang,clang++,$(CC)) |
| 58 | + ifeq ($(CC_IS_CLANG),1) |
| 59 | + override CXX := $(subst clang,clang++,$(CC)) |
| 60 | + else ifeq ($(CC_IS_EMCC),1) |
| 61 | + override CXX := em++ |
| 62 | + else |
| 63 | + CXX := $(CROSS_COMPILE)g++ |
| 64 | + endif |
29 | 65 | endif |
30 | 66 |
|
| 67 | +# Target toolchain configuration |
| 68 | +# These tools are used for building the target binaries (potentially cross-compiled) |
| 69 | + |
31 | 70 | ifndef CPP |
32 | 71 | CPP := $(CC) -E |
33 | 72 | endif |
34 | 73 |
|
35 | | -ifndef LD |
36 | | -LD := $(CROSS_COMPILE)ld |
37 | | -endif |
38 | | - |
39 | | -ifndef AR |
40 | | -AR := $(CROSS_COMPILE)ar |
41 | | -endif |
42 | | - |
43 | | -ifndef RANLIB |
44 | | -RANLIB := $(CROSS_COMPILE)ranlib |
45 | | -endif |
46 | | - |
47 | | -ifndef STRIP |
48 | | -STRIP := $(CROSS_COMPILE)strip -sx |
49 | | -endif |
50 | | - |
51 | | -ifndef OBJCOPY |
52 | | -OBJCOPY := $(CROSS_COMPILE)objcopy |
53 | | -endif |
| 74 | +# Emscripten uses its own toolchain (emar, emranlib, etc.) |
| 75 | +# For other compilers, use CROSS_COMPILE prefix |
| 76 | +ifeq ($(CC_IS_EMCC),1) |
| 77 | + # Emscripten toolchain |
| 78 | + ifndef AR |
| 79 | + AR := emar |
| 80 | + endif |
| 81 | + ifndef RANLIB |
| 82 | + RANLIB := emranlib |
| 83 | + endif |
| 84 | + ifndef STRIP |
| 85 | + STRIP := emstrip |
| 86 | + endif |
| 87 | + # Emscripten doesn't use traditional ld/objcopy |
| 88 | + LD := emcc |
| 89 | + OBJCOPY := true |
| 90 | +else |
| 91 | + # Traditional GCC/Clang toolchain |
| 92 | + # Use $(origin) to detect if variables come from Make's built-in defaults |
| 93 | + ifeq ($(origin LD),default) |
| 94 | + LD := $(CROSS_COMPILE)ld |
| 95 | + endif |
| 96 | + ifeq ($(origin AR),default) |
| 97 | + AR := $(CROSS_COMPILE)ar |
| 98 | + endif |
| 99 | + ifeq ($(origin RANLIB),default) |
| 100 | + RANLIB := $(CROSS_COMPILE)ranlib |
| 101 | + endif |
| 102 | + ifndef STRIP |
| 103 | + STRIP := $(CROSS_COMPILE)strip -sx |
| 104 | + endif |
| 105 | + ifndef OBJCOPY |
| 106 | + OBJCOPY := $(CROSS_COMPILE)objcopy |
| 107 | + endif |
| 108 | +endif |
| 109 | + |
| 110 | +# Host toolchain configuration |
| 111 | +# These tools are used for building host utilities (always native compilation) |
| 112 | +# Useful when cross-compiling: target tools build for embedded, host tools for development machine |
54 | 113 |
|
55 | 114 | ifndef HOSTCC |
56 | 115 | HOSTCC := $(HOST_COMPILE)gcc |
@@ -83,3 +142,31 @@ endif |
83 | 142 | ifndef HOSTOBJCOPY |
84 | 143 | HOSTOBJCOPY := $(HOST_COMPILE)objcopy |
85 | 144 | endif |
| 145 | + |
| 146 | +# Platform-specific compiler optimizations |
| 147 | +# Based on target architecture and compiler capabilities |
| 148 | + |
| 149 | +# macOS-specific linker flags |
| 150 | +# Xcode 15+ generates warnings about duplicate library options |
| 151 | +# Only apply to native macOS builds (not cross-compilation) |
| 152 | +ifeq ($(shell uname -s),Darwin) |
| 153 | + ifndef CROSS_COMPILE |
| 154 | + # Check if ld supports -no_warn_duplicate_libraries |
| 155 | + LD_SUPPORTS_NO_WARN := $(shell $(CC) -Wl,-no_warn_duplicate_libraries 2>&1 | grep -q "unknown option" && echo 0 || echo 1) |
| 156 | + ifeq ($(LD_SUPPORTS_NO_WARN),1) |
| 157 | + LDFLAGS += -Wl,-no_warn_duplicate_libraries |
| 158 | + endif |
| 159 | + endif |
| 160 | +endif |
| 161 | + |
| 162 | +# Toolchain information display |
| 163 | +ifdef CROSS_COMPILE |
| 164 | + $(info Cross-compiling with: $(CROSS_COMPILE)) |
| 165 | + $(info Target toolchain: $(CC)) |
| 166 | +endif |
| 167 | + |
| 168 | +ifeq ($(CC_IS_EMCC),1) |
| 169 | + $(info WebAssembly build with Emscripten) |
| 170 | + $(info Compiler: $(CC)) |
| 171 | + $(info Toolchain: emar, emranlib, emstrip) |
| 172 | +endif |
0 commit comments