]> git.ipfire.org Git - ipfire-3.x.git/blob - kernel/scripts/configure
json-c: Update to version 0.17-20230812
[ipfire-3.x.git] / kernel / scripts / configure
1 #!/bin/bash
2 ###############################################################################
3 # IPFire.org - An Open Source Firewall Solution #
4 # Copyright (C) - IPFire Development Team <info@ipfire.org> #
5 ###############################################################################
6
7 BASEDIR="$(dirname "${0}")"
8 SCRIPTS_DIR="${BASEDIR}"
9
10 CONFIGS=(
11 # x86_64
12 "x86_64:generic"
13
14 # aarch64
15 "aarch64:generic"
16 )
17
18 search_kernel_dir() {
19 local dir
20 for dir in /builddir/source/linux-*; do
21 if [ -d "${dir}" ]; then
22 echo "${dir}"
23 break
24 fi
25 done
26 }
27
28 arches() {
29 local config
30 for config in ${CONFIGS[@]}; do
31 echo "${config%:*}"
32 done
33 }
34
35 flavours_for_arch() {
36 local arch="${1}"
37
38 local config
39 for config in ${CONFIGS[@]}; do
40 if [ "${arch}:" = "${config%:*}:" ]; then
41 echo "${config#*:}"
42 fi
43 done
44 }
45
46 configs() {
47 local arch="${1}"
48 local flavour="${2}"
49 shift 2
50
51 # Add any extra files first
52 local configs=( "$@" )
53
54 # Add the generic configuration
55 configs+=( "config-generic" )
56
57 # If flavour is not generic, we add *-generic
58 if [ "${flavour}" != "generic" ]; then
59 configs+=( "config-${arch}-generic" )
60 fi
61
62 # Add the architecture/flavour configuration
63 configs+=( "config-${arch}-${flavour}" )
64
65 # Return the result
66 echo "${configs[@]}"
67
68 return 0
69 }
70
71 get_kernel_arch() {
72 local arch="${1}"
73
74 case "${arch}" in
75 aarch64)
76 echo "arm64"
77 ;;
78 x86_64)
79 echo "x86"
80 ;;
81 *)
82 echo "${arch}"
83 ;;
84 esac
85 }
86
87 kernel_config() {
88 local arch="${1}"
89 local action="${2}"
90 local config_in="${3}"
91 local config_out="${4}"
92
93 echo "Running 'make ${action}' for ${arch}..."
94
95 local kernel_arch="$(get_kernel_arch "${arch}")"
96
97 pushd "${KERNEL_DIR}" >/dev/null
98
99 cat "${config_in}" > ".config"
100
101 # Run the configuration program
102 make ARCH="${kernel_arch}" "${action}"
103
104 # Write back the configuration file
105 cat ".config" > "${config_out}"
106
107 popd >/dev/null
108 }
109
110 merge_config() {
111 local arch="${1}"
112 local flavour="${2}"
113 local output="${3}"
114 shift 3
115
116 local arg
117 for arg in arch flavour output; do
118 if [ -z "${!arg}" ]; then
119 echo >&2 "merge usage: <arch> <flavour> <output filename>"
120 return 2
121 fi
122 done
123
124 local configs="$(configs "${arch}" "${flavour}" "$@")"
125
126 # Merge the configuration files from its elementary configuration
127 # files.
128 local tmp_out="$(mktemp)"
129 local tmp_in="$(mktemp)"
130
131 local config
132 for config in ${configs}; do
133 cat "${tmp_out}" > "${tmp_in}"
134
135 if ! perl "${SCRIPTS_DIR}/merge.pl" \
136 "${tmp_in}" "${config}" > "${tmp_out}"; then
137 echo >&2 "Could not merge configuration for ${arch} ${flavour}"
138 rm -f "${tmp_in}" "${tmp_out}"
139 return 1
140 fi
141 done
142
143 cat "${tmp_out}" > "${output}"
144 rm -f "${tmp_in}" "${tmp_out}"
145 }
146
147 # This function runs an interactive "make oldconfig"
148 make_config() {
149 local action="${1}"
150 local arch="${2}"
151
152 # Default to x86_64 when no arch is given
153 if [ -z "${arch}" ]; then
154 arch="x86_64"
155 fi
156
157 # Detect kernel arch
158 local flavour="generic"
159
160 # Create a temporary directory
161 local tmpdir="$(mktemp -d)"
162
163 # Merge configuration
164 if ! merge_config "${arch}" "${flavour}" "${tmpdir}/.config.old"; then
165 echo "Could not merge configuration for ${arch} (${flavour})" >&2
166 return 1
167 fi
168
169 # Open the kernel configuration editor (in the given mode)
170 if ! kernel_config "${arch}" "${action}" "${tmpdir}/.config.old" "${tmpdir}/.config"; then
171 echo >&2 "Kernel configuration editing has been unsuccessful"
172 rm -rf "${tmpdir}"
173 return 1
174 fi
175
176 # Diff the old and changed configuration
177 if ! python3 "${SCRIPTS_DIR}/configdiff.py" \
178 "${tmpdir}/.config.old" "${tmpdir}/.config" > "${tmpdir}/diff"; then
179 rm -rf "${tmpdir}"
180 return 1
181 fi
182
183 # Check if the diff contains any data
184 if [ ! -s "${tmpdir}/diff" ]; then
185 echo "No changes found"
186 return 0
187 fi
188
189 # Apply the diff to all configurations
190 if ! diff_configs "${tmpdir}/diff"; then
191 rm -rf "${tmpdir}"
192 return 1
193 fi
194
195 # Cleanup
196 rm -rf "${tmpdir}"
197
198 return 0
199 }
200
201 diff_configs() {
202 local tmpdir="$(mktemp -d)"
203
204 local configs=()
205
206 local config
207 for config in ${CONFIGS[@]}; do
208 arch="${config%:*}"
209 flavour="${config#*:}"
210
211 # Generate the filename
212 local filename="${tmpdir}/full-${arch}-${flavour}"
213
214 # Merge configuration
215 if ! merge_config "${arch}" "${flavour}" "${filename}" "$@"; then
216 rm -rf "${tmpdir}"
217 return 1
218 fi
219
220 # Run "oldconfig" to ensure there are no gaps in other architectures
221 kernel_config "${arch}" "oldconfig" "${filename}" "${filename}"
222
223 # Collect all *-generic configurations
224 case "${flavour}" in
225 generic)
226 configs+=( "${filename}" )
227 ;;
228 esac
229 done
230
231 # Generate config-generic
232 if ! python3 "${SCRIPTS_DIR}/configcommon.py" "${configs[@]}" \
233 > "${tmpdir}/config-generic"; then
234 echo >&2 "Could not generate config-generic"
235 rm -rf "${tmpdir}"
236 return 1
237 fi
238
239 local arch
240 for arch in $(arches); do
241 # Fetch all flavours
242 local flavours="$(flavours_for_arch "${arch}")"
243
244 local flavour
245 for flavour in ${flavours}; do
246 local base_config="${tmpdir}/config-${arch}-generic"
247
248 # config-${arch}-generic is handled in a special way and diffed
249 # directly against config-generic
250 case "${flavour}" in
251 generic)
252 base_config="${tmpdir}/config-generic"
253 ;;
254 esac
255
256 # Diff configurations
257 if ! python3 "${SCRIPTS_DIR}/configdiff.py" \
258 "${base_config}" \
259 "${tmpdir}/full-${arch}-${flavour}" \
260 > "${tmpdir}/config-${arch}-${flavour}"; then
261 echo >&2 "Could not generate config-${arch}-${flavour}"
262 rm -rf "${tmpdir}"
263 return 1
264 fi
265 done
266 done
267
268 # List any changes and copy back the result
269 for config in config-*; do
270 if ! cmp "${tmpdir}/${config}" "${config}" &>/dev/null; then
271 echo "${config} has changed"
272 fi
273
274 # Copy back configuration
275 cat "${tmpdir}/${config}" > "${config}"
276 done
277
278 # Cleanup
279 rm -rf "${tmpdir}"
280
281 return 0
282 }
283
284 KERNEL_DIR="$(search_kernel_dir)"
285
286 main() {
287 local action
288
289 # Parse commandline
290 local arg
291 while [ $# -gt 0 ]; do
292 arg="${1}"
293 shift
294
295 case "${arg}" in
296 --kernel-dir=*)
297 KERNEL_DIR="${arg#--kernel-dir=}"
298 ;;
299
300 listnewconfig|menuconfig|merge|oldconfig|olddefconfig)
301 action="${arg}"
302 break
303 ;;
304
305 help|"")
306 echo "${0} - available commands:"
307 echo " * merge <arch> <flavour> <output filename>"
308 echo " * menuconfig"
309 echo " * oldconfig"
310 echo " * olddefconfig"
311 return 0
312 ;;
313 esac
314 done
315
316 # Check if KERNEL_DIR has been set and exists
317 if [ -z "${KERNEL_DIR}" -o ! -d "${KERNEL_DIR}" ]; then
318 echo >&2 "KERNEL_DIR was not set or does not exist!"
319 return 2
320 fi
321
322 case "${action}" in
323 merge)
324 merge_config "$@"
325 return $?
326 ;;
327
328 listnewconfig|menuconfig|oldconfig|olddefconfig)
329 make_config "${action}" "$@"
330 return $?
331 ;;
332
333 # Handle no or invalid actions
334 *)
335 echo >&2 "No action given... Try ${0} help."
336 return 2
337 ;;
338 esac
339 }
340
341 main "$@" || exit $?