Commit 2ce079f0 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'kbuild-misc-v4.15' of...

Merge tag 'kbuild-misc-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild

Pull Kbuild misc updates from Masahiro Yamada:

 - Clean up and fix RPM package build

 - Fix a warning in DEB package build

 - Improve coccicheck script

 - Improve some semantic patches

* tag 'kbuild-misc-v4.15' of git://git.kernel.org/pub/scm/linux/kernel/git/masahiroy/linux-kbuild:
  docs: dev-tools: coccinelle: delete out of date wiki reference
  coccinelle: orplus: reorganize to improve performance
  coccinelle: use exists to improve efficiency
  builddeb: Pass the kernel:debarch substvar to dpkg-genchanges
  Coccinelle: use false positive annotation
  coccinelle: fix verbose message about .cocci file being run
  coccinelle: grep Options and Requires fields more precisely
  Coccinelle: make DEBUG_FILE option more useful
  coccinelle: api: detect identical chip data arrays
  coccinelle: Improve setup_timer.cocci matching
  Coccinelle: setup_timer: improve messages from setup_timer
  kbuild: rpm-pkg: do not force -jN in submake
  kbuild: rpm-pkg: keep spec file until make mrproper
  kbuild: rpm-pkg: fix jobserver unavailable warning
  kbuild: rpm-pkg: replace $RPM_BUILD_ROOT with %{buildroot}
  kbuild: rpm-pkg: fix build error when CONFIG_MODULES is disabled
  kbuild: rpm-pkg: refactor mkspec with here doc
  kbuild: rpm-pkg: clean up mkspec
  kbuild: rpm-pkg: install vmlinux.bz2 unconditionally
  kbuild: rpm-pkg: remove ppc64 specific image handling
parents 09bd7c75 e9e716ff
......@@ -55,6 +55,11 @@ modules.builtin
/System.map
/Module.markers
#
# RPM spec file (make rpm-pkg)
#
/*.spec
#
# Debian directory (make deb-pkg)
#
......
......@@ -33,9 +33,6 @@ of many distributions, e.g. :
You can get the latest version released from the Coccinelle homepage at
http://coccinelle.lip6.fr/
Information and tips about Coccinelle are also provided on the wiki
pages at http://cocci.ekstranet.diku.dk/wiki/doku.php
Once you have it, run the following command::
./configure
......
......@@ -123,15 +123,8 @@ run_cmd_parmap() {
if [ $VERBOSE -ne 0 ] ; then
echo "Running ($NPROC in parallel): $@"
fi
if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
if [ -f $DEBUG_FILE ]; then
echo "Debug file $DEBUG_FILE exists, bailing"
exit
fi
else
DEBUG_FILE="/dev/null"
fi
$@ 2>$DEBUG_FILE
echo $@ >>$DEBUG_FILE
$@ 2>>$DEBUG_FILE
if [[ $? -ne 0 ]]; then
echo "coccicheck failed"
exit $?
......@@ -176,8 +169,8 @@ OPTIONS="$OPTIONS $SPFLAGS"
coccinelle () {
COCCI="$1"
OPT=`grep "Option" $COCCI | cut -d':' -f2`
REQ=`grep "Requires" $COCCI | cut -d':' -f2 | sed "s| ||"`
OPT=`grep "Options:" $COCCI | cut -d':' -f2`
REQ=`grep "Requires:" $COCCI | cut -d':' -f2 | sed "s| ||"`
REQ_NUM=$(echo $REQ | ${DIR}/scripts/ld-version.sh)
if [ "$REQ_NUM" != "0" ] ; then
if [ "$SPATCH_VERSION_NUM" -lt "$REQ_NUM" ] ; then
......@@ -194,7 +187,7 @@ coccinelle () {
if [ $VERBOSE -ne 0 -a $ONLINE -eq 0 ] ; then
FILE=`echo $COCCI | sed "s|$srctree/||"`
FILE=${COCCI#$srctree/}
echo "Processing `basename $COCCI`"
echo "with option(s) \"$OPT\""
......@@ -247,6 +240,15 @@ coccinelle () {
}
if [ "$DEBUG_FILE" != "/dev/null" -a "$DEBUG_FILE" != "" ]; then
if [ -f $DEBUG_FILE ]; then
echo "Debug file $DEBUG_FILE exists, bailing"
exit
fi
else
DEBUG_FILE="/dev/null"
fi
if [ "$COCCI" = "" ] ; then
for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
coccinelle $f
......
/// Detect BQ27XXX_DATA structures with identical registers, dm registers or
/// properties.
//# Doesn't unfold macros used in register or property fields.
//# Requires OCaml scripting
///
// Confidence: High
// Copyright: (C) 2017 Julia Lawall, Inria/LIP6, GPLv2.
// URL: http://coccinelle.lip6.fr/
// Requires: 1.0.7
// Keywords: BQ27XXX_DATA
virtual report
@initialize:ocaml@
@@
let print_report p msg =
let p = List.hd p in
Printf.printf "%s:%d:%d-%d: %s" p.file p.line p.col p.col_end msg
@str depends on report@
type t;
identifier i,i1,i2;
expression e1,e2;
@@
t i[] = {
...,
[e1] = BQ27XXX_DATA(i1,...),
...,
[e2] = BQ27XXX_DATA(i2,...),
...,
};
@script:ocaml tocheck@
i1 << str.i1;
i2 << str.i2;
i1regs; i2regs;
i1dmregs; i2dmregs;
i1props; i2props;
@@
if not(i1 = i2)
then
begin
i1regs := make_ident (i1 ^ "_regs");
i2regs := make_ident (i2 ^ "_regs");
i1dmregs := make_ident (i1 ^ "_dm_regs");
i2dmregs := make_ident (i2 ^ "_dm_regs");
i1props := make_ident (i1 ^ "_props");
i2props := make_ident (i2 ^ "_props")
end
(* ---------------------------------------------------------------- *)
@getregs1@
typedef u8;
identifier tocheck.i1regs;
initializer list i1regs_vals;
position p1;
@@
u8 i1regs@p1[...] = { i1regs_vals, };
@getregs2@
identifier tocheck.i2regs;
initializer list i2regs_vals;
position p2;
@@
u8 i2regs@p2[...] = { i2regs_vals, };
@script:ocaml@
(_,i1regs_vals) << getregs1.i1regs_vals;
(_,i2regs_vals) << getregs2.i2regs_vals;
i1regs << tocheck.i1regs;
i2regs << tocheck.i2regs;
p1 << getregs1.p1;
p2 << getregs2.p2;
@@
if i1regs < i2regs &&
List.sort compare i1regs_vals = List.sort compare i2regs_vals
then
let msg =
Printf.sprintf
"WARNING %s and %s (line %d) are identical\n"
i1regs i2regs (List.hd p2).line in
print_report p1 msg
(* ---------------------------------------------------------------- *)
@getdmregs1@
identifier tocheck.i1dmregs;
initializer list i1dmregs_vals;
position p1;
@@
struct bq27xxx_dm_reg i1dmregs@p1[] = { i1dmregs_vals, };
@getdmregs2@
identifier tocheck.i2dmregs;
initializer list i2dmregs_vals;
position p2;
@@
struct bq27xxx_dm_reg i2dmregs@p2[] = { i2dmregs_vals, };
@script:ocaml@
(_,i1dmregs_vals) << getdmregs1.i1dmregs_vals;
(_,i2dmregs_vals) << getdmregs2.i2dmregs_vals;
i1dmregs << tocheck.i1dmregs;
i2dmregs << tocheck.i2dmregs;
p1 << getdmregs1.p1;
p2 << getdmregs2.p2;
@@
if i1dmregs < i2dmregs &&
List.sort compare i1dmregs_vals = List.sort compare i2dmregs_vals
then
let msg =
Printf.sprintf
"WARNING %s and %s (line %d) are identical\n"
i1dmregs i2dmregs (List.hd p2).line in
print_report p1 msg
(* ---------------------------------------------------------------- *)
@getprops1@
identifier tocheck.i1props;
initializer list[n1] i1props_vals;
position p1;
@@
enum power_supply_property i1props@p1[] = { i1props_vals, };
@getprops2@
identifier tocheck.i2props;
initializer list[n2] i2props_vals;
position p2;
@@
enum power_supply_property i2props@p2[] = { i2props_vals, };
@script:ocaml@
(_,i1props_vals) << getprops1.i1props_vals;
(_,i2props_vals) << getprops2.i2props_vals;
i1props << tocheck.i1props;
i2props << tocheck.i2props;
p1 << getprops1.p1;
p2 << getprops2.p2;
@@
if i1props < i2props &&
List.sort compare i1props_vals = List.sort compare i2props_vals
then
let msg =
Printf.sprintf
"WARNING %s and %s (line %d) are identical\n"
i1props i2props (List.hd p2).line in
print_report p1 msg
......@@ -2,6 +2,7 @@
/// and data fields
// Confidence: High
// Copyright: (C) 2016 Vaishali Thakkar, Oracle. GPLv2
// Copyright: (C) 2017 Kees Cook, Google. GPLv2
// Options: --no-includes --include-headers
// Keywords: init_timer, setup_timer
......@@ -10,60 +11,123 @@ virtual context
virtual org
virtual report
// Match the common cases first to avoid Coccinelle parsing loops with
// "... when" clauses.
@match_immediate_function_data_after_init_timer
depends on patch && !context && !org && !report@
expression e, func, da;
@@
-init_timer (&e);
+setup_timer (&e, func, da);
-init_timer
+setup_timer
( \(&e\|e\)
+, func, da
);
(
-\(e.function\|e->function\) = func;
-\(e.data\|e->data\) = da;
|
-\(e.data\|e->data\) = da;
-\(e.function\|e->function\) = func;
)
@match_immediate_function_data_before_init_timer
depends on patch && !context && !org && !report@
expression e, func, da;
@@
(
-\(e.function\|e->function\) = func;
-\(e.data\|e->data\) = da;
|
-\(e.data\|e->data\) = da;
-\(e.function\|e->function\) = func;
)
-init_timer
+setup_timer
( \(&e\|e\)
+, func, da
);
@match_function_and_data_after_init_timer
depends on patch && !context && !org && !report@
expression e, e2, e3, e4, e5, func, da;
@@
-init_timer
+setup_timer
( \(&e\|e\)
+, func, da
);
... when != func = e2
when != da = e3
(
-e.function = func;
... when != da = e4
-e.data = da;
|
-e->function = func;
... when != da = e4
-e->data = da;
|
-e.data = da;
... when != func = e5
-e.function = func;
|
-e->data = da;
... when != func = e5
-e->function = func;
)
@match_function_and_data_after_init_timer
@match_function_and_data_before_init_timer
depends on patch && !context && !org && !report@
expression e1, e2, e3, e4, e5, a, b;
expression e, e2, e3, e4, e5, func, da;
@@
-init_timer (&e1);
+setup_timer (&e1, a, b);
... when != a = e2
when != b = e3
(
-e1.function = a;
... when != b = e4
-e1.data = b;
-e.function = func;
... when != da = e4
-e.data = da;
|
-e1.data = b;
... when != a = e5
-e1.function = a;
-e->function = func;
... when != da = e4
-e->data = da;
|
-e.data = da;
... when != func = e5
-e.function = func;
|
-e->data = da;
... when != func = e5
-e->function = func;
)
... when != func = e2
when != da = e3
-init_timer
+setup_timer
( \(&e\|e\)
+, func, da
);
@r1 exists@
expression t;
identifier f;
position p;
@@
f(...) { ... when any
init_timer@p(...)
init_timer@p(\(&t\|t\))
... when any
}
@r2 exists@
expression r1.t;
identifier g != r1.f;
struct timer_list t;
expression e8;
@@
g(...) { ... when any
t.data = e8
\(t.data\|t->data\) = e8
... when any
}
......@@ -77,14 +141,31 @@ p << r1.p;
cocci.include_match(False)
@r3 depends on patch && !context && !org && !report@
expression e6, e7, c;
expression r1.t, func, e7;
position r1.p;
@@
-init_timer@p (&e6);
+setup_timer (&e6, c, 0UL);
... when != c = e7
-e6.function = c;
(
-init_timer@p(&t);
+setup_timer(&t, func, 0UL);
... when != func = e7
-t.function = func;
|
-t.function = func;
... when != func = e7
-init_timer@p(&t);
+setup_timer(&t, func, 0UL);
|
-init_timer@p(t);
+setup_timer(t, func, 0UL);
... when != func = e7
-t->function = func;
|
-t->function = func;
... when != func = e7
-init_timer@p(t);
+setup_timer(t, func, 0UL);
)
// ----------------------------------------------------------------------------
......@@ -104,11 +185,9 @@ position j0, j1, j2;
)
@match_function_and_data_after_init_timer_context
depends on !patch &&
!match_immediate_function_data_after_init_timer_context &&
(context || org || report)@
depends on !patch && (context || org || report)@
expression a, b, e1, e2, e3, e4, e5;
position j0, j1, j2;
position j0 != match_immediate_function_data_after_init_timer_context.j0,j1,j2;
@@
* init_timer@j0 (&e1);
......@@ -124,13 +203,12 @@ position j0, j1, j2;
* e1@j2.function = a;
)
@r3_context depends on !patch &&
!match_immediate_function_data_after_init_timer_context &&
!match_function_and_data_after_init_timer_context &&
(context || org || report)@
@r3_context depends on !patch && (context || org || report)@
expression c, e6, e7;
position r1.p;
position j0, j1;
position j0 !=
{match_immediate_function_data_after_init_timer_context.j0,
match_function_and_data_after_init_timer_context.j0}, j1;
@@
* init_timer@j0@p (&e6);
......
......@@ -15,7 +15,7 @@ virtual context
virtual org
virtual report
@r@
@r exists@
iterator name list_for_each_entry;
expression x,E;
position p1,p2;
......
......@@ -3,10 +3,10 @@
/// Sometimes, code after an if that is indented is actually intended to be
/// part of the if branch.
///
/// This has a high rate of false positives, because Coccinelle's column
/// calculation does not distinguish between spaces and tabs, so code that
/// is not visually aligned may be considered to be in the same column.
///
//# This has a high rate of false positives, because Coccinelle's column
//# calculation does not distinguish between spaces and tabs, so code that
//# is not visually aligned may be considered to be in the same column.
//
// Confidence: Low
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
......
......@@ -14,7 +14,19 @@ virtual report
virtual context
@r@
constant c;
constant c,c1;
identifier i,i1;
position p;
@@
(
c1 + c - 1
|
c1@i1 +@p c@i
)
@s@
constant r.c, r.c1;
identifier i;
expression e;
@@
......@@ -27,28 +39,31 @@ e & c@i
e |= c@i
|
e &= c@i
|
e | c1@i
|
e & c1@i
|
e |= c1@i
|
e &= c1@i
)
@s@
constant r.c,c1;
identifier i1;
position p;
@depends on s@
position r.p;
constant c1,c2;
@@
(
c1 + c - 1
|
*c1@i1 +@p c
)
* c1 +@p c2
@script:python depends on org@
p << s.p;
@script:python depends on s && org@
p << r.p;
@@
cocci.print_main("sum of probable bitmasks, consider |",p)
@script:python depends on report@
p << s.p;
@script:python depends on s && report@
p << r.p;
@@
msg = "WARNING: sum of probable bitmasks, consider |"
......
......@@ -10,7 +10,7 @@
// Copyright: (C) 2012 Julia Lawall, INRIA/LIP6. GPLv2.
// Copyright: (C) 2012 Gilles Muller, INRIA/LiP6. GPLv2.
// URL: http://coccinelle.lip6.fr/
// Comments: Requires Coccinelle version 1.0.0-rc20 or later
// Requires: 1.0.0
// Options:
virtual patch
......
......@@ -50,17 +50,18 @@ rpm-pkg rpm: FORCE
$(MAKE) clean
$(CONFIG_SHELL) $(MKSPEC) >$(objtree)/kernel.spec
$(call cmd,src_tar,$(KERNELPATH),kernel.spec)
rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz
rm $(KERNELPATH).tar.gz kernel.spec
+rpmbuild $(RPMOPTS) --target $(UTS_MACHINE) -ta $(KERNELPATH).tar.gz \
--define='_smp_mflags %{nil}'
# binrpm-pkg
# ---------------------------------------------------------------------------
binrpm-pkg: FORCE
$(MAKE) KBUILD_SRC=
$(CONFIG_SHELL) $(MKSPEC) prebuilt > $(objtree)/binkernel.spec
rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
+rpmbuild $(RPMOPTS) --define "_builddir $(objtree)" --target \
$(UTS_MACHINE) -bb $(objtree)/binkernel.spec
rm binkernel.spec
clean-files += $(objtree)/*.spec
# Deb target
# ---------------------------------------------------------------------------
......
......@@ -408,9 +408,9 @@ EOF
dpkg-source -cdebian/control -ldebian/changelog --format="3.0 (custom)" --target-format="3.0 (quilt)" \
-b / ../${sourcename}_${version}.orig.tar.gz ../${sourcename}_${packageversion}.debian.tar.gz
mv ${sourcename}_${packageversion}*dsc ..
dpkg-genchanges > ../${sourcename}_${packageversion}_${debarch}.changes
dpkg-genchanges -Vkernel:debarch="${debarch}" > ../${sourcename}_${packageversion}_${debarch}.changes
else
dpkg-genchanges -b > ../${sourcename}_${packageversion}_${debarch}.changes
dpkg-genchanges -b -Vkernel:debarch="${debarch}" > ../${sourcename}_${packageversion}_${debarch}.changes
fi
exit 0
......@@ -10,156 +10,135 @@
#
# how we were called determines which rpms we build and how we build them
if [ "$1" = "prebuilt" ]; then
PREBUILT=true
if [ "$1" = prebuilt ]; then
S=DEL
else
PREBUILT=false
S=
fi
# starting to output the spec
if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then
PROVIDES=kernel-drm
fi
PROVIDES="$PROVIDES kernel-$KERNELRELEASE"
__KERNELRELEASE=`echo $KERNELRELEASE | sed -e "s/-/_/g"`
echo "Name: kernel"
echo "Summary: The Linux Kernel"
echo "Version: $__KERNELRELEASE"
echo "Release: $(cat .version 2>/dev/null || echo 1)"
echo "License: GPL"
echo "Group: System Environment/Kernel"
echo "Vendor: The Linux Community"
echo "URL: http://www.kernel.org"
if ! $PREBUILT; then
echo "Source: kernel-$__KERNELRELEASE.tar.gz"
fi
echo "BuildRoot: %{_tmppath}/%{name}-%{PACKAGE_VERSION}-root"
echo "Provides: $PROVIDES"
echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :"
echo "%define debug_package %{nil}"
echo ""
echo "%description"
echo "The Linux Kernel, the operating system core itself"
echo ""
echo "%package headers"
echo "Summary: Header files for the Linux kernel for use by glibc"
echo "Group: Development/System"
echo "Obsoletes: kernel-headers"
echo "Provides: kernel-headers = %{version}"
echo "%description headers"
echo "Kernel-headers includes the C header files that specify the interface"
echo "between the Linux kernel and userspace libraries and programs. The"
echo "header files define structures and constants that are needed for"
echo "building most standard programs and are also needed for rebuilding the"
echo "glibc package."
echo ""
echo "%package devel"
echo "Summary: Development package for building kernel modules to match the $__KERNELRELEASE kernel"
echo "Group: System Environment/Kernel"
echo "AutoReqProv: no"
echo "%description -n kernel-devel"
echo "This package provides kernel headers and makefiles sufficient to build modules"
echo "against the $__KERNELRELEASE kernel package."
echo ""
if ! $PREBUILT; then
echo "%prep"
echo "%setup -q"
echo ""
if grep -q CONFIG_MODULES=y .config; then
M=
else
M=DEL
fi
echo "%build"
if ! $PREBUILT; then
echo "make clean && make %{?_smp_mflags} KBUILD_BUILD_VERSION=%{release}"
echo ""
if grep -q CONFIG_DRM=y .config; then
PROVIDES=kernel-drm
fi
echo "%install"
echo 'KBUILD_IMAGE=$(make image_name)'
echo "%ifarch ia64"
echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules'
echo "%else"
echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
echo "%endif"
echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{?_smp_mflags} KBUILD_SRC= modules_install'
echo "%ifarch ia64"
echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/efi/vmlinuz-$KERNELRELEASE"
echo 'ln -s '"efi/vmlinuz-$KERNELRELEASE" '$RPM_BUILD_ROOT'"/boot/"
echo "%else"
echo "%ifarch ppc64"
echo "cp vmlinux arch/powerpc/boot"
echo "cp arch/powerpc/boot/"'$KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE"
echo "%else"
echo 'cp $KBUILD_IMAGE $RPM_BUILD_ROOT'"/boot/vmlinuz-$KERNELRELEASE"
echo "%endif"
echo "%endif"
echo 'make %{?_smp_mflags} INSTALL_HDR_PATH=$RPM_BUILD_ROOT/usr KBUILD_SRC= headers_install'
echo 'cp System.map $RPM_BUILD_ROOT'"/boot/System.map-$KERNELRELEASE"
echo 'cp .config $RPM_BUILD_ROOT'"/boot/config-$KERNELRELEASE"
echo "%ifnarch ppc64"
echo 'bzip2 -9 --keep vmlinux'
echo 'mv vmlinux.bz2 $RPM_BUILD_ROOT'"/boot/vmlinux-$KERNELRELEASE.bz2"
echo "%endif"
if ! $PREBUILT; then
echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/build"
echo 'rm -f $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE/source"
echo "mkdir -p "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE"
echo "EXCLUDES=\"$RCS_TAR_IGNORE --exclude .tmp_versions --exclude=*vmlinux* --exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation --exclude .config.old --exclude .missing-syscalls.d\""
echo "tar "'$EXCLUDES'" -cf- . | (cd "'$RPM_BUILD_ROOT'"/usr/src/kernels/$KERNELRELEASE;tar xvf -)"
echo 'cd $RPM_BUILD_ROOT'"/lib/modules/$KERNELRELEASE"
echo "ln -sf /usr/src/kernels/$KERNELRELEASE build"
echo "ln -sf /usr/src/kernels/$KERNELRELEASE source"
fi
PROVIDES="$PROVIDES kernel-$KERNELRELEASE"
__KERNELRELEASE=$(echo $KERNELRELEASE | sed -e "s/-/_/g")
EXCLUDES="$RCS_TAR_IGNORE --exclude=.tmp_versions --exclude=*vmlinux* \
--exclude=*.o --exclude=*.ko --exclude=*.cmd --exclude=Documentation \
--exclude=.config.old --exclude=.missing-syscalls.d"
echo ""
echo "%clean"
echo 'rm -rf $RPM_BUILD_ROOT'
echo ""
echo "%post"
echo "if [ -x /sbin/installkernel -a -r /boot/vmlinuz-$KERNELRELEASE -a -r /boot/System.map-$KERNELRELEASE ]; then"
echo "cp /boot/vmlinuz-$KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm"
echo "cp /boot/System.map-$KERNELRELEASE /boot/.System.map-$KERNELRELEASE-rpm"
echo "rm -f /boot/vmlinuz-$KERNELRELEASE /boot/System.map-$KERNELRELEASE"
echo "/sbin/installkernel $KERNELRELEASE /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm"
echo "rm -f /boot/.vmlinuz-$KERNELRELEASE-rpm /boot/.System.map-$KERNELRELEASE-rpm"
echo "fi"
echo ""
echo "%preun"
echo "if [ -x /sbin/new-kernel-pkg ]; then"
echo "new-kernel-pkg --remove $KERNELRELEASE --rminitrd --initrdfile=/boot/initramfs-$KERNELRELEASE.img"
echo "fi"
echo ""
echo "%postun"
echo "if [ -x /sbin/update-bootloader ]; then"
echo "/sbin/update-bootloader --remove $KERNELRELEASE"
echo "fi"
echo ""
echo "%files"
echo '%defattr (-, root, root)'
echo "/lib/modules/$KERNELRELEASE"
echo "%exclude /lib/modules/$KERNELRELEASE/build"
echo "%exclude /lib/modules/$KERNELRELEASE/source"
echo "/boot/*"
echo ""
echo "%files headers"
echo '%defattr (-, root, root)'
echo "/usr/include"
echo ""
if ! $PREBUILT; then
echo "%files devel"
echo '%defattr (-, root, root)'