Whamcloud - gitweb
Merge in external patches support
[fs/lustre-release.git] / build / lmake
1 #!/bin/sh
2
3 # option variables
4 DESTDIR=
5 KERNELDIR=
6 TARGET=
7 # Not sure what to put here
8 # TARGET_ARCH=$(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
9 TARGET_ARCH=
10 TARGET_CONFIG=
11 JOBS=1
12 CONFIGURE_FLAGS=
13
14 # commands to run
15 BUILD_LUSTRE=0
16 BUILD_KERNEL=0
17 DEPEND_KERNEL=0
18 INSTALL_LUSTRE=0
19 INSTALL_KERNEL=0
20 SAVE_HEADERS=0
21 UNPACK_KERNEL=0
22
23 # provided by target file
24 KERNEL=
25 SERIES=
26 CONFIG=
27 VERSION=
28 EXTRA_VERSION=
29
30 BASE_ARCHS=
31 BIGMEM_ARCHS=
32 BOOT_ARCHS=
33 JENSEN_ARCHS=
34 SMP_ARCHS=
35 BIGSMP_ARCHS=
36 UP_ARCHS=
37
38 RHBUILD=0
39 SUSEBUILD=0
40
41 # flat-out globals
42 TOPDIR=
43 TARGET_FILE=
44 KERNEL_FILE=
45 SERIES_FILE=
46 CONFIG_FILE=
47
48 canon()
49 {
50     pushd $1 >/dev/null
51     echo $PWD
52     popd >/dev/null
53 }
54 TOPDIR=$(canon "${0%%${0##*/}}/..")
55
56 cleanup()
57 {
58     true
59 }
60
61 fatal()
62 {
63     cleanup
64     [ "$2" ] && echo
65     [ "$2" ] && echo "${0##*/}: $2"
66     exit $1
67 }
68
69 list_targets()
70 {
71     echo -n "Available targets:"
72     for target in $TOPDIR/lustre/kernel_patches/targets/*.target ; do
73         target_file=${target##*/}
74         echo -n " ${target_file%%.target}"
75     done
76     echo
77 }
78
79
80 usage()
81 {
82     cat <<EOF
83 Usage: ${0##*/} [OPTION]... [-- <lustre configure options>]
84
85 Options:
86
87   --build
88     same as --build-kernel --build-lustre --unpack-kernel
89
90   --build-lustre
91     configure and compile lustre.  Requires that --build-kernel was
92     already run.
93
94   --build-kernel
95     configure and compile a kernel.  Implies --depend-kernel.
96     Requires that --unpack-kernel was already run.
97
98   --depend-kernel)
99     Prepares a kernel tree for building (similar to make mrproper
100     oldconfig dep).  Requires that --unpack-kernel was already run.
101
102   --destdir=DESTDIR
103     Root directory to install into (like DESTDIR with auto*).
104
105   --extraversion=EXTRAVERSION
106     Overrides the target kernel\'s EXTRAVERSION text.
107
108   -h, --help
109     Display this message.
110
111   --install
112     same as --install-kernel --install-lustre
113
114   --install-lustre
115     run make install in the Lustre tree.
116
117   --install-kernel
118     install the kernel image and modules.
119
120   -j jobs
121     This works just like the -j option to make, and is passed to make
122     when building.
123
124   --kerneldir=KERNELDIR
125     Directory containing linux source tarballs.
126
127   --target=TARGET
128     Name of the configuration to use.  The available targets are
129     listed below.
130
131   --target-arch=ARCH
132     Specifies an architecture to use when choosing a kernel config
133     file.  Default is i386.
134
135   --target-config=CONFIG
136     Specifies a special option (such as smp, bigsmp, bigmem, or BOOT)
137     to use when choosing a kernel config file.  This also modifies the
138     kernel version and modules directory.
139
140   --unpack-kernel
141     Untars and patches the kernel source.
142
143   The order that commands (--build-lustre, --unpack-kernel) are
144   specified on the command line is ignored; ${0##*/} will always
145   execute them in the correct order (unpack, then build, then install
146   etc.).
147
148 EOF
149     list_targets
150
151     fatal "$1" "$2"
152 }
153
154 check_options()
155 {
156     (( $BUILD_LUSTRE || $BUILD_KERNEL || $DEPEND_KERNEL || \
157             $INSTALL_LUSTRE || $INSTALL_KERNEL || $SAVE_HEADERS || \
158             $UNPACK_KERNEL )) || \
159                 fatal 1 "No commands specified."
160
161     if (( $UNPACK_KERNEL )) ; then
162         [ "$KERNELDIR" ] || \
163             fatal 1 "A kernel directory must be specified with --kerneldir."
164         [ -d "$KERNELDIR" ] || \
165             fatal 1 "$KERNELDIR is not a directory."
166     fi
167
168     if (( $INSTALL_LUSTRE || $INSTALL_KERNEL || $SAVE_HEADERS )) ; then
169         [ -z "$DESTDIR" -o -d "$DESTDIR" ] || \
170             fatal 1 "$DESTDIR is not a directory."
171     fi
172
173     [ "$TARGET" ] || usage 1 "A target must be specified with --target."
174     TARGET_FILE="$TOPDIR/lustre/kernel_patches/targets/$TARGET.target"
175     [ -r "$TARGET_FILE" ] || \
176         fatal 1 "Target '$TARGET' was not found.  Try --list-targets."
177
178     if [ -z "$JOBS" -o "$JOBS" -lt "1" ] ; then
179         JOBS=1
180     fi
181 }
182
183 get_lustre_version()
184 {
185     for series in $SERIES ; do
186         SERIES_FILE="$TOPDIR/lustre/kernel_patches/series/$series"
187         lustre_patch=$(grep lustre_version "$SERIES_FILE" 2>/dev/null)
188         [ "$lustre_patch" ] && break
189     done
190     [ "$lustre_patch" ] || \
191         fatal 1 "Could not determine Lustre version from $SERIES series."
192
193     awk '/^\+#define LUSTRE_KERNEL_VERSION /{ print $3 }' \
194         "$TOPDIR/lustre/kernel_patches/patches/$lustre_patch" 2>/dev/null
195 }
196
197 load_target()
198 {
199     EXTRA_VERSION_save="$EXTRA_VERSION"
200
201     . "$TARGET_FILE"
202
203     [ "$KERNEL" ] || fatal 1 "Target $TARGET did not specify a kernel."
204 # Suse 2.6 has our patches in already
205 #    [ "$SERIES" ] || fatal 1 "Target $TARGET did not specify a patch series."
206 #    [ "$CONFIG" ] || fatal 1 "Target $TARGET did not specify a kernel config."
207     [ "$VERSION" ] || fatal 1 "Target $TARGET did not specify the kernel version."
208     
209     if [ "$KERNELDIR" ] ; then
210         KERNEL_FILE="$KERNELDIR/$KERNEL"
211         [ -r "$KERNELDIR/$KERNEL" ] || \
212             fatal 1 "Target $TARGET's kernel file $KERNEL not found in kernel directory $KERNELDIR."
213     fi
214
215     if [ "$SERIES" ] ; then
216         for series in $SERIES ; do
217             SERIES_FILE="$TOPDIR/lustre/kernel_patches/series/$series"
218             [ -r "$SERIES_FILE" ] || \
219                 fatal 1 "Target $TARGET's series $SERIES missing from $TOPDIR/lustre/kernel_patches/series."
220         done
221     fi
222
223     TARGET_ARCH=${TARGET_ARCH:-$BASE_ARCHS}
224     CONFIG_TARGET="$TARGET-${TARGET_ARCH}${TARGET_CONFIG:+-$TARGET_CONFIG}"
225     CONFIG_FILE="$TOPDIR/lustre/kernel_patches/kernel_configs/kernel-$VERSION-$CONFIG_TARGET.config"
226     [ -r "$CONFIG_FILE" ] ||
227         fatal 1 "Target $TARGET's config file $CONFIG_FILE missing from $TOPDIR/lustre/kernel_patches/configs."
228
229     if [ "$EXTRA_VERSION_save" ] ; then
230         EXTRA_VERSION="$EXTRA_VERSION_save"
231     else
232         EXTRA_VERSION="${EXTRA_VERSION}_lustre.$(get_lustre_version)"
233     fi
234 }
235
236 tarflags()
237 {
238     case "$1" in
239         '')
240             fatal 1 "tarflags(): File name argument missing."
241             ;;
242         *.tar.gz)
243             echo 'zxf'
244             ;;
245         *.tar.bz2)
246             echo 'jxf'
247             ;;
248         *)
249             fatal 1 "tarflags(): Unrecognized tar extension in file: $1"
250             ;;
251     esac
252 }
253
254 untar()
255 {
256     echo "Untarring ${1##*/}..."
257     tar $(tarflags $1) $1
258 }
259
260
261 extract_kernel()
262 {
263     (( $UNPACK_KERNEL )) || return 0
264     pushd "$TOPDIR" >/dev/null
265     if [ -d linux ] ; then
266         [ -L linux ] && rm -rf $(readlink linux)
267         rm -rf linux
268     fi
269     untar "$KERNEL_FILE"
270     [ -d linux ] || ln -sf linux* linux
271     popd >/dev/null
272 }
273
274 patch_kernel()
275 {
276     (( $UNPACK_KERNEL )) || return 0
277     [ "$SERIES" ] || return 0
278     pushd "$TOPDIR/linux" >/dev/null
279     for series in $SERIES ; do
280         echo -n "Applying series $series:"
281         SERIES_FILE="$TOPDIR/lustre/kernel_patches/series/$series"
282         for patch in $(<"$SERIES_FILE") ; do
283             PATCH_FILE="$TOPDIR/lustre/kernel_patches/patches/$patch"
284             [ -r "$PATCH_FILE" ] || \
285                 fatal 1 "Patch file not found: $patch"
286             echo -n " $patch"
287             patch -s -p1 < "$PATCH_FILE" || fatal 1 "Error applying patch $patch."
288         done
289         echo
290     done
291     popd >/dev/null
292 }
293
294 set_make()
295 {
296     MAKE="make -s"
297     if [ "$CC" ] ; then
298         MAKE="$MAKE CC=$CC"
299     fi
300     if [ "$ARCH" ] ; then
301         MAKE_ARCH="$MAKE ARCH=$ARCH"
302     else
303         case $TARGET_ARCH in
304             i?86)
305                 ;;
306             *)
307                 MAKE_ARCH="$MAKE ARCH=$TARGET_ARCH"
308                 ;;
309         esac
310     fi
311     MAKE_J="$MAKE -j $JOBS"
312 }
313
314 depend_kernel()
315 {
316     (( $DEPEND_KERNEL )) || return 0
317     # we need to override $CC at make time, since there is no
318     # configure
319     set_make
320     pushd "$TOPDIR/linux" >/dev/null
321     echo "Overriding EXTRAVERSION in kernel..."
322     perl -p -i -e "s/^EXTRAVERSION.*/EXTRAVERSION = -${EXTRA_VERSION}${TARGET_CONFIG}/" Makefile
323     echo "Making depend in $PWD..."
324     $MAKE mrproper || fatal 1 "Error running make mrproper"
325     cp "$CONFIG_FILE" .config
326     for oc in oldconfig_nonint silentoldconfig oldconfig ; do
327         if grep -q "$oc" Makefile ; then
328             OLDCONFIG="$oc"
329             break
330         fi
331     done
332     $MAKE $OLDCONFIG || fatal 1 "Error running make oldconfig"
333     case "$VERSION" in
334         2.6*)
335             SYMLINKS="include/asm"
336             ;;
337         2.4*)
338             SYMLINKS="symlinks"
339             ;;
340     esac
341     $MAKE $SYMLINKS
342     $MAKE_J dep || fatal 1 "Error running make dep"
343     $MAKE include/linux/version.h || fatal 1 "Error making include/linux/version.h"
344 }
345
346 build_kernel()
347 {
348     (( $BUILD_KERNEL )) || return 0
349     set_make
350     echo "Building kernel in $PWD..."
351     case "$TARGET_ARCH" in
352         i386 | i586 | i686 | athlon | x86_64)
353             $MAKE_J bzImage || fatal 1 "Error making bzImage."
354             ;;
355         ppc | ppc64)
356             $MAKE_J vmlinux || fatal 1 "Error making vmlinux."
357             ;;
358         *)
359             $MAKE_J boot || fatal 1 "Error making boot."
360             ;;
361     esac
362     $MAKE_J modules || fatal 1 "Error building modules."
363
364     popd >/dev/null
365 }
366
367 configure_lustre()
368 {
369     (( $BUILD_LUSTRE )) || return 0
370     pushd "$TOPDIR" >/dev/null
371     [ -f Makefile ] && make -s clean
372     [ -f configure ] || sh ./autogen.sh
373     ./configure --with-linux=$PWD/linux $CONFIGURE_FLAGS || \
374         fatal 1 "Error configuring Lustre."
375     popd >/dev/null
376 }
377
378 build_lustre()
379 {
380     (( $BUILD_LUSTRE )) || return 0
381     set_make
382     pushd "$TOPDIR" >/dev/null
383     $MAKE_J || fatal 1 "Error building Lustre."
384     popd >/dev/null
385 }
386
387 install_kernel()
388 {
389     (( $INSTALL_KERNEL )) || return 0
390     set_make
391     FULL_VERSION="${VERSION}-${EXTRA_VERSION}${TARGET_CONFIG}"
392     pushd "$TOPDIR/linux" >/dev/null
393     mkdir -p "$DESTDIR/boot"
394
395     install -m 644 System.map "$DESTDIR/boot/System.map-${FULL_VERSION}"
396     # install -m 644 module-info ...
397     install -m 644 "$CONFIG_FILE" "$DESTDIR/boot/config-${FULL_VERSION}"
398
399     mkdir -p "$DESTDIR/dev/shm"
400     mkdir -p "$DESTDIR/lib/modules/${FULL_VERSION}"
401
402     $MAKE INSTALL_MOD_PATH="$DESTDIR" KERNELRELEASE="$FULL_VERSION" \
403         -s modules_install || \
404         fatal 1 "Error installing modules."
405
406     case "$TARGET_ARCH" in
407         i386 | i586 | i686 | athlon)
408             cp arch/i386/boot/bzImage "$DESTDIR/boot/vmlinuz-${FULL_VERSION}"
409             cp vmlinux "$DESTDIR/lib/modules/${FULL_VERSION}/"
410             ln -sf "../lib/modules/${FULL_VERSION}/vmlinux" "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
411             ;;
412         x86_64)
413             cp arch/x86_64/boot/bzImage "$DESTDIR/boot/vmlinuz-${FULL_VERSION}"
414             cp vmlinux "$DESTDIR/lib/modules/${FULL_VERSION}/"
415             ln -sf "../lib/modules/${FULL_VERSION}/vmlinux" "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
416             ;;
417         ppc | ppc64)
418             cp vmlinux "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
419             ln -sf "$DESTDIR/boot/vmlinux-${FULL_VERSION}" "../lib/modules/${FULL_VERSION}/vmlinux" 
420             ;;
421         ia64)
422             gzip -cfv vmlinux > vmlinuz
423             mkdir -p "$DESTDIR/boot/efi/redhat"
424             install -m 755 vmlinux "$DESTDIR/lib/modules/${FULL_VERSION}/"
425             install -m 755 vmlinuz "$DESTDIR/boot/efi/redhat/vmlinuz-${FULL_VERSION}"
426             ln -sf "../../../lib/modules/${FULL_VERSION}/vmlinux" "$DESTDIR/boot/efi/redhat/vmlinux-${FULL_VERSION}"
427             ln -sf "efi/redhat/vmlinux-${FULL_VERSION}" "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
428             ln -sf "efi/redhat/vmlinuz-${FULL_VERSION}" "$DESTDIR/boot/vmlinuz-${FULL_VERSION}"
429             ;;
430         *)
431             cp vmlinuz "$DESTDIR/boot/vmlinuz-${FULL_VERSION}"
432             cp vmlinux "$DESTDIR/lib/modules/${FULL_VERSION}/vmlinux-${FULL_VERSION}"
433             ln -sf "../lib/modules/${FULL_VERSION}/vmlinux-${FULL_VERSION}" "$DESTDIR/boot/vmlinux-${FULL_VERSION}"
434
435             ;;
436     esac
437     if [ -e init/kerntypes.o ] ; then
438         cp init/kerntypes.o "$DESTDIR/boot/Kerntypes-${FULL_VERSION}"
439     fi
440
441     popd >/dev/null
442 }
443
444 install_lustre()
445 {
446     (( $INSTALL_LUSTRE )) || return 0
447     set_make
448     FULL_VERSION="${VERSION}-${EXTRA_VERSION}${TARGET_CONFIG}"
449     pushd "$TOPDIR" >/dev/null
450     $MAKE -s install "DESTDIR=$DESTDIR" KERNELRELEASE="$FULL_VERSION" || fatal 1 "Error installing Lustre."
451     popd >/dev/null
452 }
453
454 build_kms()
455 {
456     (( $BUILD_KERNEL )) || return 0
457     (( $SUSEBUILD )) || return 0
458     set_make
459     FULL_VERSION="${VERSION}-${EXTRA_VERSION}${TARGET_CONFIG}"
460     mkdir -p "${TOPDIR}/modules-${FULL_VERSION}"
461     for dir in /usr/src/kernel-modules/* ; do
462         # we are replacing lustre-lite, so don't include it
463         if [ ${dir##*/} != "lustre-lite" -a -e $dir/Makefile ]; then
464             build_dir="${TOPDIR}/modules-${FULL_VERSION}/${dir##*/}"
465             cp -a $dir $build_dir
466             # these modules are terrible, and don't all build
467             $MAKE_J -C $build_dir modules KERNEL_SOURCE="${TOPDIR}/linux"
468         fi
469     done
470 }
471
472 symver()
473 {
474     local file=$1 name=${1%.ko}
475     nm $file \
476     | sed -ne 's,^0*\([0-9a-f]\{8\}\) A __crc_\(.*\),0x\1\t\2\t'"$name"',p'
477 }
478
479 install_kms()
480 {
481     (( $INSTALL_KERNEL )) || return 0
482     (( $SUSEBUILD )) || return 0
483     set_make
484     FULL_VERSION="${VERSION}-${EXTRA_VERSION}${TARGET_CONFIG}"
485     for build_dir in "${TOPDIR}/modules-${FULL_VERSION}/*" ; do
486         [ -d $build_dir ] || continue
487         # these modules are terrible, and don't all build
488         $MAKE -C $build_dir KERNEL_SOURCE="${TOPDIR}/linux" INSTALL_MOD_PATH="$DESTDIR" 
489     done
490     (   symver vmlinux
491         moddir="${DESTDIR}/lib/modules/${FULL_VERSION}"
492         cd $moddir/kernel
493         for module in $(find * -name '*.ko'); do
494             symver $module
495         done
496         cd $moddir
497         for module in $(find * -path 'kernel/*' -prune -o \
498                            -name '*.ko' -print); do
499             symver $module
500         done
501     ) | sort -u -k2 \
502         | gzip -c9 > "${DESTDIR}/boot/symvers-${VERSION}-${EXTRA_VERSION}-${TARGET_ARCH}${TARGET_CONFIG}.gz"
503 }
504
505 save_headers()
506 {
507     echo "Saving headers for $1 $2..."
508     pushd linux >/dev/null
509
510     KVERREL="${VERSION}-${EXTRA_VERSION}"
511     # deal with the kernel headers that are version specific
512     
513     saveddir="$RPM_BUILD_ROOT/usr/src/linux-${KVERREL}/savedheaders/$2/$1"
514     mkdir -p "$saveddir"
515     install -m 644 include/linux/autoconf.h "$saveddir/autoconf.h"
516     install -m 644 include/linux/version.h  "$saveddir/version.h"
517     mv include/linux/modules "$saveddir/"
518     echo $2 $1 ../../savedheaders/$2/$1/ >>  $RPM_BUILD_ROOT/usr/src/linux-${KVERREL}/savedheaders/list
519     popd >/dev/null
520 }
521
522 save_all_headers()
523 {
524     (( $SAVE_HEADERS )) || return 0
525
526     for arch in $BIGMEM_ARCHS ; do
527         save_headers bigmem $arch
528     done
529
530     for arch in $BOOT_ARCHS ; do
531         save_headers BOOT $arch
532     done
533
534     for arch in $JENSEN_ARCHS ; do
535         save_headers jensen $arch
536     done
537
538     for arch in $SMP_ARCHS ; do
539         save_headers smp $arch
540     done
541
542     for arch in $BIGSMP_ARCHS ; do
543         save_headers bigsmp $arch
544     done
545     for arch in $UP_ARCHS ; do
546         save_headers up $arch
547     done
548 }
549
550 longopts="build,build-lustre,build-kernel,depend-kernel,destdir:,extraversion:"
551 longopts="$longopts,help,install,install-lustre,install-kernel,kerneldir:"
552 longopts="$longopts,save-headers,target:,target-arch:,target-config:,unpack-kernel"
553
554 options=$(getopt -o hj: -l "$longopts" -- "$@")
555
556 eval set -- "$options"
557     
558 while [ "$1" ] ; do
559     case "$1" in
560         '')
561             usage 1
562             ;;
563         --build)
564             BUILD_LUSTRE=1
565             BUILD_KERNEL=1
566             DEPEND_KERNEL=1
567             UNPACK_KERNEL=1
568             shift
569             ;;
570         --build-lustre)
571             BUILD_LUSTRE=1
572             shift
573             ;;
574         --build-kernel)
575             BUILD_KERNEL=1
576             DEPEND_KERNEL=1
577             shift
578             ;;
579         --depend-kernel)
580             DEPEND_KERNEL=1
581             shift
582             ;;
583         --destdir)
584             DESTDIR=$2
585             shift 2
586             ;;
587         --extraversion)
588             EXTRA_VERSION=$2
589             shift 2
590             ;;
591         --help | -h)
592             usage 0
593             ;;
594         --install)
595             INSTALL_LUSTRE=1
596             INSTALL_KERNEL=1
597             shift
598             ;;
599         --install-lustre)
600             INSTALL_LUSTRE=1
601             shift
602             ;;
603         --install-kernel)
604             INSTALL_KERNEL=1
605             shift
606             ;;
607         -j)
608             JOBS=$2
609             shift 2
610             ;;
611         --kerneldir)
612             KERNELDIR=$2
613             shift 2
614             ;;
615         --save-headers)
616             SAVE_HEADERS=1
617             shift
618             ;;
619         --target)
620             TARGET=$2
621             shift 2
622             ;;
623         --target-arch)
624             TARGET_ARCH=$2
625             shift 2
626             ;;
627         --target-config)
628             TARGET_CONFIG=$2
629             shift 2
630             ;;
631         --unpack-kernel)
632             UNPACK_KERNEL=1
633             shift
634             ;;
635         --)
636             shift
637             CONFIGURE_FLAGS=$@
638             break
639             ;; 
640         *)
641             usage 1 "Unrecognized option: $1"
642             ;;
643     esac
644 done
645
646 check_options
647 load_target
648
649 extract_kernel
650 patch_kernel
651
652 depend_kernel
653 build_kernel
654
655 configure_lustre
656 build_lustre
657
658 build_kms
659
660 install_kernel
661 install_lustre
662
663 install_kms
664
665 save_all_headers
666
667 exit 0