Commit 6e936d3e authored by Linus Torvalds's avatar Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild

* git://git.kernel.org/pub/scm/linux/kernel/git/sam/kbuild: (28 commits)
  kbuild: add distclean info to 'make help' and more details for 'clean'
  dontdiff: add utsrelease.h
  kbuild: fix "mkdir -p" usage in scripts/package/mkspec
  kbuild: correct and clarify versioning info in Makefile
  kbuild: fixup Documentation/kbuild/modules.txt
  kbuild: Extend kbuild/defconfig tags support to exuberant ctags
  kbuild: fix for some typos in Documentation/makefiles.txt
  kbuild: clarify "make C=" build option
  Documentaion: update Documentation/Changes with minimum versions
  kbuild: update help in top level Makefile
  kbuild: fail kernel compilation in case of unresolved module symbols
  kbuild: remove debug left-over from Makefile.host
  kbuild: create output directory for hostprogs with O=.. build
  kbuild: add missing return statement in modpost.c:secref_whitelist()
  kbuild: preperly align SYSMAP output
  kbuild: make -rR is now default
  kbuild: make V=2 tell why a target is rebuild
  kbuild: modpost on vmlinux regardless of CONFIG_MODULES
  kbuild: ignore references from ".pci_fixup" to ".init.text"
  kbuild: linguistic fixes for Documentation/kbuild/makefiles.txt
  ...
parents a68aa1cc 5cc8d246
...@@ -37,15 +37,14 @@ o e2fsprogs 1.29 # tune2fs ...@@ -37,15 +37,14 @@ o e2fsprogs 1.29 # tune2fs
o jfsutils 1.1.3 # fsck.jfs -V o jfsutils 1.1.3 # fsck.jfs -V
o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs o reiserfsprogs 3.6.3 # reiserfsck -V 2>&1|grep reiserfsprogs
o xfsprogs 2.6.0 # xfs_db -V o xfsprogs 2.6.0 # xfs_db -V
o pcmciautils 004 o pcmciautils 004 # pccardctl -V
o pcmcia-cs 3.1.21 # cardmgr -V
o quota-tools 3.09 # quota -V o quota-tools 3.09 # quota -V
o PPP 2.4.0 # pppd --version o PPP 2.4.0 # pppd --version
o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version o isdn4k-utils 3.1pre1 # isdnctrl 2>&1|grep version
o nfs-utils 1.0.5 # showmount --version o nfs-utils 1.0.5 # showmount --version
o procps 3.2.0 # ps --version o procps 3.2.0 # ps --version
o oprofile 0.9 # oprofiled --version o oprofile 0.9 # oprofiled --version
o udev 071 # udevinfo -V o udev 081 # udevinfo -V
Kernel compilation Kernel compilation
================== ==================
...@@ -268,7 +267,7 @@ active clients. ...@@ -268,7 +267,7 @@ active clients.
To enable this new functionality, you need to: To enable this new functionality, you need to:
mount -t nfsd nfsd /proc/fs/nfs mount -t nfsd nfsd /proc/fs/nfsd
before running exportfs or mountd. It is recommended that all NFS before running exportfs or mountd. It is recommended that all NFS
services be protected from the internet-at-large by a firewall where services be protected from the internet-at-large by a firewall where
......
...@@ -135,6 +135,7 @@ tags ...@@ -135,6 +135,7 @@ tags
times.h* times.h*
tkparse tkparse
trix_boot.h trix_boot.h
utsrelease.h*
version.h* version.h*
vmlinux vmlinux
vmlinux-* vmlinux-*
......
...@@ -67,19 +67,19 @@ applicable everywhere (see syntax). ...@@ -67,19 +67,19 @@ applicable everywhere (see syntax).
- default value: "default" <expr> ["if" <expr>] - default value: "default" <expr> ["if" <expr>]
A config option can have any number of default values. If multiple A config option can have any number of default values. If multiple
default values are visible, only the first defined one is active. default values are visible, only the first defined one is active.
Default values are not limited to the menu entry, where they are Default values are not limited to the menu entry where they are
defined, this means the default can be defined somewhere else or be defined. This means the default can be defined somewhere else or be
overridden by an earlier definition. overridden by an earlier definition.
The default value is only assigned to the config symbol if no other The default value is only assigned to the config symbol if no other
value was set by the user (via the input prompt above). If an input value was set by the user (via the input prompt above). If an input
prompt is visible the default value is presented to the user and can prompt is visible the default value is presented to the user and can
be overridden by him. be overridden by him.
Optionally dependencies only for this default value can be added with Optionally, dependencies only for this default value can be added with
"if". "if".
- dependencies: "depends on"/"requires" <expr> - dependencies: "depends on"/"requires" <expr>
This defines a dependency for this menu entry. If multiple This defines a dependency for this menu entry. If multiple
dependencies are defined they are connected with '&&'. Dependencies dependencies are defined, they are connected with '&&'. Dependencies
are applied to all other options within this menu entry (which also are applied to all other options within this menu entry (which also
accept an "if" expression), so these two examples are equivalent: accept an "if" expression), so these two examples are equivalent:
...@@ -153,7 +153,7 @@ Nonconstant symbols are the most common ones and are defined with the ...@@ -153,7 +153,7 @@ Nonconstant symbols are the most common ones and are defined with the
'config' statement. Nonconstant symbols consist entirely of alphanumeric 'config' statement. Nonconstant symbols consist entirely of alphanumeric
characters or underscores. characters or underscores.
Constant symbols are only part of expressions. Constant symbols are Constant symbols are only part of expressions. Constant symbols are
always surrounded by single or double quotes. Within the quote any always surrounded by single or double quotes. Within the quote, any
other character is allowed and the quotes can be escaped using '\'. other character is allowed and the quotes can be escaped using '\'.
Menu structure Menu structure
...@@ -237,7 +237,7 @@ choices: ...@@ -237,7 +237,7 @@ choices:
<choice block> <choice block>
"endchoice" "endchoice"
This defines a choice group and accepts any of above attributes as This defines a choice group and accepts any of the above attributes as
options. A choice can only be of type bool or tristate, while a boolean options. A choice can only be of type bool or tristate, while a boolean
choice only allows a single config entry to be selected, a tristate choice only allows a single config entry to be selected, a tristate
choice also allows any number of config entries to be set to 'm'. This choice also allows any number of config entries to be set to 'm'. This
......
...@@ -86,7 +86,7 @@ any kernel Makefiles (or any other source files). ...@@ -86,7 +86,7 @@ any kernel Makefiles (or any other source files).
*Normal developers* are people who work on features such as device *Normal developers* are people who work on features such as device
drivers, file systems, and network protocols. These people need to drivers, file systems, and network protocols. These people need to
maintain the kbuild Makefiles for the subsystem that they are maintain the kbuild Makefiles for the subsystem they are
working on. In order to do this effectively, they need some overall working on. In order to do this effectively, they need some overall
knowledge about the kernel Makefiles, plus detailed knowledge about the knowledge about the kernel Makefiles, plus detailed knowledge about the
public interface for kbuild. public interface for kbuild.
...@@ -104,10 +104,10 @@ This document is aimed towards normal developers and arch developers. ...@@ -104,10 +104,10 @@ This document is aimed towards normal developers and arch developers.
=== 3 The kbuild files === 3 The kbuild files
Most Makefiles within the kernel are kbuild Makefiles that use the Most Makefiles within the kernel are kbuild Makefiles that use the
kbuild infrastructure. This chapter introduce the syntax used in the kbuild infrastructure. This chapter introduces the syntax used in the
kbuild makefiles. kbuild makefiles.
The preferred name for the kbuild files are 'Makefile' but 'Kbuild' can The preferred name for the kbuild files are 'Makefile' but 'Kbuild' can
be used and if both a 'Makefile' and a 'Kbuild' file exists then the 'Kbuild' be used and if both a 'Makefile' and a 'Kbuild' file exists, then the 'Kbuild'
file will be used. file will be used.
Section 3.1 "Goal definitions" is a quick intro, further chapters provide Section 3.1 "Goal definitions" is a quick intro, further chapters provide
...@@ -124,7 +124,7 @@ more details, with real examples. ...@@ -124,7 +124,7 @@ more details, with real examples.
Example: Example:
obj-y += foo.o obj-y += foo.o
This tell kbuild that there is one object in that directory named This tell kbuild that there is one object in that directory, named
foo.o. foo.o will be built from foo.c or foo.S. foo.o. foo.o will be built from foo.c or foo.S.
If foo.o shall be built as a module, the variable obj-m is used. If foo.o shall be built as a module, the variable obj-m is used.
...@@ -140,7 +140,7 @@ more details, with real examples. ...@@ -140,7 +140,7 @@ more details, with real examples.
--- 3.2 Built-in object goals - obj-y --- 3.2 Built-in object goals - obj-y
The kbuild Makefile specifies object files for vmlinux The kbuild Makefile specifies object files for vmlinux
in the lists $(obj-y). These lists depend on the kernel in the $(obj-y) lists. These lists depend on the kernel
configuration. configuration.
Kbuild compiles all the $(obj-y) files. It then calls Kbuild compiles all the $(obj-y) files. It then calls
...@@ -155,7 +155,7 @@ more details, with real examples. ...@@ -155,7 +155,7 @@ more details, with real examples.
(module_init() / __initcall) will be called during boot in the (module_init() / __initcall) will be called during boot in the
order they appear. So keep in mind that changing the link order they appear. So keep in mind that changing the link
order may e.g. change the order in which your SCSI order may e.g. change the order in which your SCSI
controllers are detected, and thus you disks are renumbered. controllers are detected, and thus your disks are renumbered.
Example: Example:
#drivers/isdn/i4l/Makefile #drivers/isdn/i4l/Makefile
...@@ -206,8 +206,8 @@ more details, with real examples. ...@@ -206,8 +206,8 @@ more details, with real examples.
ext2-y := balloc.o bitmap.o ext2-y := balloc.o bitmap.o
ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o
In this example xattr.o is only part of the composite object In this example, xattr.o is only part of the composite object
ext2.o, if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'. ext2.o if $(CONFIG_EXT2_FS_XATTR) evaluates to 'y'.
Note: Of course, when you are building objects into the kernel, Note: Of course, when you are building objects into the kernel,
the syntax above will also work. So, if you have CONFIG_EXT2_FS=y, the syntax above will also work. So, if you have CONFIG_EXT2_FS=y,
...@@ -221,16 +221,16 @@ more details, with real examples. ...@@ -221,16 +221,16 @@ more details, with real examples.
--- 3.5 Library file goals - lib-y --- 3.5 Library file goals - lib-y
Objects listed with obj-* are used for modules or Objects listed with obj-* are used for modules, or
combined in a built-in.o for that specific directory. combined in a built-in.o for that specific directory.
There is also the possibility to list objects that will There is also the possibility to list objects that will
be included in a library, lib.a. be included in a library, lib.a.
All objects listed with lib-y are combined in a single All objects listed with lib-y are combined in a single
library for that directory. library for that directory.
Objects that are listed in obj-y and additional listed in Objects that are listed in obj-y and additionaly listed in
lib-y will not be included in the library, since they will anyway lib-y will not be included in the library, since they will anyway
be accessible. be accessible.
For consistency objects listed in lib-m will be included in lib.a. For consistency, objects listed in lib-m will be included in lib.a.
Note that the same kbuild makefile may list files to be built-in Note that the same kbuild makefile may list files to be built-in
and to be part of a library. Therefore the same directory and to be part of a library. Therefore the same directory
...@@ -241,11 +241,11 @@ more details, with real examples. ...@@ -241,11 +241,11 @@ more details, with real examples.
lib-y := checksum.o delay.o lib-y := checksum.o delay.o
This will create a library lib.a based on checksum.o and delay.o. This will create a library lib.a based on checksum.o and delay.o.
For kbuild to actually recognize that there is a lib.a being build For kbuild to actually recognize that there is a lib.a being built,
the directory shall be listed in libs-y. the directory shall be listed in libs-y.
See also "6.3 List directories to visit when descending". See also "6.3 List directories to visit when descending".
Usage of lib-y is normally restricted to lib/ and arch/*/lib. Use of lib-y is normally restricted to lib/ and arch/*/lib.
--- 3.6 Descending down in directories --- 3.6 Descending down in directories
...@@ -255,7 +255,7 @@ more details, with real examples. ...@@ -255,7 +255,7 @@ more details, with real examples.
invoke make recursively in subdirectories, provided you let it know of invoke make recursively in subdirectories, provided you let it know of
them. them.
To do so obj-y and obj-m are used. To do so, obj-y and obj-m are used.
ext2 lives in a separate directory, and the Makefile present in fs/ ext2 lives in a separate directory, and the Makefile present in fs/
tells kbuild to descend down using the following assignment. tells kbuild to descend down using the following assignment.
...@@ -353,8 +353,8 @@ more details, with real examples. ...@@ -353,8 +353,8 @@ more details, with real examples.
Special rules are used when the kbuild infrastructure does Special rules are used when the kbuild infrastructure does
not provide the required support. A typical example is not provide the required support. A typical example is
header files generated during the build process. header files generated during the build process.
Another example is the architecture specific Makefiles which Another example are the architecture specific Makefiles which
needs special rules to prepare boot images etc. need special rules to prepare boot images etc.
Special rules are written as normal Make rules. Special rules are written as normal Make rules.
Kbuild is not executing in the directory where the Makefile is Kbuild is not executing in the directory where the Makefile is
...@@ -387,22 +387,22 @@ more details, with real examples. ...@@ -387,22 +387,22 @@ more details, with real examples.
--- 3.11 $(CC) support functions --- 3.11 $(CC) support functions
The kernel may be build with several different versions of The kernel may be built with several different versions of
$(CC), each supporting a unique set of features and options. $(CC), each supporting a unique set of features and options.
kbuild provide basic support to check for valid options for $(CC). kbuild provide basic support to check for valid options for $(CC).
$(CC) is useally the gcc compiler, but other alternatives are $(CC) is useally the gcc compiler, but other alternatives are
available. available.
as-option as-option
as-option is used to check if $(CC) when used to compile as-option is used to check if $(CC) -- when used to compile
assembler (*.S) files supports the given option. An optional assembler (*.S) files -- supports the given option. An optional
second option may be specified if first option are not supported. second option may be specified if the first option is not supported.
Example: Example:
#arch/sh/Makefile #arch/sh/Makefile
cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),) cflags-y += $(call as-option,-Wa$(comma)-isa=$(isa-y),)
In the above example cflags-y will be assinged the the option In the above example, cflags-y will be assigned the option
-Wa$(comma)-isa=$(isa-y) if it is supported by $(CC). -Wa$(comma)-isa=$(isa-y) if it is supported by $(CC).
The second argument is optional, and if supplied will be used The second argument is optional, and if supplied will be used
if first argument is not supported. if first argument is not supported.
...@@ -422,7 +422,7 @@ more details, with real examples. ...@@ -422,7 +422,7 @@ more details, with real examples.
if first argument is not supported. if first argument is not supported.
cc-option cc-option
cc-option is used to check if $(CC) support a given option, and not cc-option is used to check if $(CC) supports a given option, and not
supported to use an optional second option. supported to use an optional second option.
Example: Example:
...@@ -430,8 +430,8 @@ more details, with real examples. ...@@ -430,8 +430,8 @@ more details, with real examples.
cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586) cflags-y += $(call cc-option,-march=pentium-mmx,-march=i586)
In the above example cflags-y will be assigned the option In the above example cflags-y will be assigned the option
-march=pentium-mmx if supported by $(CC), otherwise -march-i586. -march=pentium-mmx if supported by $(CC), otherwise -march=i586.
The second argument to cc-option is optional, and if omitted The second argument to cc-option is optional, and if omitted,
cflags-y will be assigned no value if first option is not supported. cflags-y will be assigned no value if first option is not supported.
cc-option-yn cc-option-yn
...@@ -444,14 +444,15 @@ more details, with real examples. ...@@ -444,14 +444,15 @@ more details, with real examples.
aflags-$(biarch) += -a32 aflags-$(biarch) += -a32
cflags-$(biarch) += -m32 cflags-$(biarch) += -m32
In the above example $(biarch) is set to y if $(CC) supports the -m32 In the above example, $(biarch) is set to y if $(CC) supports the -m32
option. When $(biarch) equals to y the expanded variables $(aflags-y) option. When $(biarch) equals 'y', the expanded variables $(aflags-y)
and $(cflags-y) will be assigned the values -a32 and -m32. and $(cflags-y) will be assigned the values -a32 and -m32,
respectively.
cc-option-align cc-option-align
gcc version >= 3.0 shifted type of options used to speify gcc versions >= 3.0 changed the type of options used to specify
alignment of functions, loops etc. $(cc-option-align) whrn used alignment of functions, loops etc. $(cc-option-align), when used
as prefix to the align options will select the right prefix: as prefix to the align options, will select the right prefix:
gcc < 3.00 gcc < 3.00
cc-option-align = -malign cc-option-align = -malign
gcc >= 3.00 gcc >= 3.00
...@@ -460,15 +461,15 @@ more details, with real examples. ...@@ -460,15 +461,15 @@ more details, with real examples.
Example: Example:
CFLAGS += $(cc-option-align)-functions=4 CFLAGS += $(cc-option-align)-functions=4
In the above example the option -falign-functions=4 is used for In the above example, the option -falign-functions=4 is used for
gcc >= 3.00. For gcc < 3.00 -malign-functions=4 is used. gcc >= 3.00. For gcc < 3.00, -malign-functions=4 is used.
cc-version cc-version
cc-version return a numerical version of the $(CC) compiler version. cc-version returns a numerical version of the $(CC) compiler version.
The format is <major><minor> where both are two digits. So for example The format is <major><minor> where both are two digits. So for example
gcc 3.41 would return 0341. gcc 3.41 would return 0341.
cc-version is useful when a specific $(CC) version is faulty in one cc-version is useful when a specific $(CC) version is faulty in one
area, for example the -mregparm=3 were broken in some gcc version area, for example -mregparm=3 was broken in some gcc versions
even though the option was accepted by gcc. even though the option was accepted by gcc.
Example: Example:
...@@ -477,18 +478,18 @@ more details, with real examples. ...@@ -477,18 +478,18 @@ more details, with real examples.
if [ $(call cc-version) -ge 0300 ] ; then \ if [ $(call cc-version) -ge 0300 ] ; then \
echo "-mregparm=3"; fi ;) echo "-mregparm=3"; fi ;)
In the above example -mregparm=3 is only used for gcc version greater In the above example, -mregparm=3 is only used for gcc version greater
than or equal to gcc 3.0. than or equal to gcc 3.0.
cc-ifversion cc-ifversion
cc-ifversion test the version of $(CC) and equals last argument if cc-ifversion tests the version of $(CC) and equals last argument if
version expression is true. version expression is true.
Example: Example:
#fs/reiserfs/Makefile #fs/reiserfs/Makefile
EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0402, -O1) EXTRA_CFLAGS := $(call cc-ifversion, -lt, 0402, -O1)
In this example EXTRA_CFLAGS will be assigned the value -O1 if the In this example, EXTRA_CFLAGS will be assigned the value -O1 if the
$(CC) version is less than 4.2. $(CC) version is less than 4.2.
cc-ifversion takes all the shell operators: cc-ifversion takes all the shell operators:
-eq, -ne, -lt, -le, -gt, and -ge -eq, -ne, -lt, -le, -gt, and -ge
...@@ -529,7 +530,7 @@ Both possibilities are described in the following. ...@@ -529,7 +530,7 @@ Both possibilities are described in the following.
Host programs can be made up based on composite objects. Host programs can be made up based on composite objects.
The syntax used to define composite objects for host programs is The syntax used to define composite objects for host programs is
similar to the syntax used for kernel objects. similar to the syntax used for kernel objects.
$(<executeable>-objs) list all objects used to link the final $(<executeable>-objs) lists all objects used to link the final
executable. executable.
Example: Example:
...@@ -538,9 +539,9 @@ Both possibilities are described in the following. ...@@ -538,9 +539,9 @@ Both possibilities are described in the following.
lxdialog-objs := checklist.o lxdialog.o lxdialog-objs := checklist.o lxdialog.o
Objects with extension .o are compiled from the corresponding .c Objects with extension .o are compiled from the corresponding .c
files. In the above example checklist.c is compiled to checklist.o files. In the above example, checklist.c is compiled to checklist.o
and lxdialog.c is compiled to lxdialog.o. and lxdialog.c is compiled to lxdialog.o.
Finally the two .o files are linked to the executable, lxdialog. Finally, the two .o files are linked to the executable, lxdialog.
Note: The syntax <executable>-y is not permitted for host-programs. Note: The syntax <executable>-y is not permitted for host-programs.
--- 4.3 Defining shared libraries --- 4.3 Defining shared libraries
...@@ -594,7 +595,7 @@ Both possibilities are described in the following. ...@@ -594,7 +595,7 @@ Both possibilities are described in the following.
The programs will always be compiled utilising $(HOSTCC) passed The programs will always be compiled utilising $(HOSTCC) passed
the options specified in $(HOSTCFLAGS). the options specified in $(HOSTCFLAGS).
To set flags that will take effect for all host programs created To set flags that will take effect for all host programs created
in that Makefile use the variable HOST_EXTRACFLAGS. in that Makefile, use the variable HOST_EXTRACFLAGS.
Example: Example:
#scripts/lxdialog/Makefile #scripts/lxdialog/Makefile
...@@ -613,7 +614,8 @@ Both possibilities are described in the following. ...@@ -613,7 +614,8 @@ Both possibilities are described in the following.
#scripts/kconfig/Makefile #scripts/kconfig/Makefile
HOSTLOADLIBES_qconf := -L$(QTDIR)/lib HOSTLOADLIBES_qconf := -L$(QTDIR)/lib
When linking qconf it will be passed the extra option "-L$(QTDIR)/lib". When linking qconf, it will be passed the extra option
"-L$(QTDIR)/lib".
--- 4.6 When host programs are actually built --- 4.6 When host programs are actually built
...@@ -648,7 +650,7 @@ Both possibilities are described in the following. ...@@ -648,7 +650,7 @@ Both possibilities are described in the following.
--- 4.7 Using hostprogs-$(CONFIG_FOO) --- 4.7 Using hostprogs-$(CONFIG_FOO)
A typcal pattern in a Kbuild file lok like this: A typical pattern in a Kbuild file looks like this:
Example: Example:
#scripts/Makefile #scripts/Makefile
...@@ -656,13 +658,13 @@ Both possibilities are described in the following. ...@@ -656,13 +658,13 @@ Both possibilities are described in the following.
Kbuild knows about both 'y' for built-in and 'm' for module. Kbuild knows about both 'y' for built-in and 'm' for module.
So if a config symbol evaluate to 'm', kbuild will still build So if a config symbol evaluate to 'm', kbuild will still build
the binary. In other words Kbuild handle hostprogs-m exactly the binary. In other words, Kbuild handles hostprogs-m exactly
like hostprogs-y. But only hostprogs-y is recommend used like hostprogs-y. But only hostprogs-y is recommended to be used
when no CONFIG symbol are involved. when no CONFIG symbols are involved.
=== 5 Kbuild clean infrastructure === 5 Kbuild clean infrastructure
"make clean" deletes most generated files in the src tree where the kernel "make clean" deletes most generated files in the obj tree where the kernel
is compiled. This includes generated files such as host programs. is compiled. This includes generated files such as host programs.
Kbuild knows targets listed in $(hostprogs-y), $(hostprogs-m), $(always), Kbuild knows targets listed in $(hostprogs-y), $(hostprogs-m), $(always),
$(extra-y) and $(targets). They are all deleted during "make clean". $(extra-y) and $(targets). They are all deleted during "make clean".
...@@ -680,7 +682,8 @@ When executing "make clean", the two files "devlist.h classlist.h" will ...@@ -680,7 +682,8 @@ When executing "make clean", the two files "devlist.h classlist.h" will
be deleted. Kbuild will assume files to be in same relative directory as the be deleted. Kbuild will assume files to be in same relative directory as the
Makefile except if an absolute path is specified (path starting with '/'). Makefile except if an absolute path is specified (path starting with '/').
To delete a directory hirachy use: To delete a directory hierarchy use:
Example: Example:
#scripts/package/Makefile #scripts/package/Makefile
clean-dirs := $(objtree)/debian/ clean-dirs := $(objtree)/debian/
...@@ -723,29 +726,29 @@ be visited during "make clean". ...@@ -723,29 +726,29 @@ be visited during "make clean".
The top level Makefile sets up the environment and does the preparation, The top level Makefile sets up the environment and does the preparation,
before starting to descend down in the individual directories. before starting to descend down in the individual directories.
The top level makefile contains the generic part, whereas the The top level makefile contains the generic part, whereas
arch/$(ARCH)/Makefile contains what is required to set-up kbuild arch/$(ARCH)/Makefile contains what is required to set up kbuild
to the said architecture. for said architecture.
To do so arch/$(ARCH)/Makefile sets a number of variables, and defines To do so, arch/$(ARCH)/Makefile sets up a number of variables and defines
a few targets. a few targets.
When kbuild executes the following steps are followed (roughly): When kbuild executes, the following steps are followed (roughly):
1) Configuration of the kernel => produced .config 1) Configuration of the kernel => produce .config
2) Store kernel version in include/linux/version.h 2) Store kernel version in include/linux/version.h
3) Symlink include/asm to include/asm-$(ARCH) 3) Symlink include/asm to include/asm-$(ARCH)
4) Updating all other prerequisites to the target prepare: 4) Updating all other prerequisites to the target prepare:
- Additional prerequisites are specified in arch/$(ARCH)/Makefile - Additional prerequisites are specified in arch/$(ARCH)/Makefile
5) Recursively descend down in all directories listed in 5) Recursively descend down in all directories listed in
init-* core* drivers-* net-* libs-* and build all targets. init-* core* drivers-* net-* libs-* and build all targets.
- The value of the above variables are extended in arch/$(ARCH)/Makefile. - The values of the above variables are expanded in arch/$(ARCH)/Makefile.
6) All object files are then linked and the resulting file vmlinux is 6) All object files are then linked and the resulting file vmlinux is
located at the root of the src tree. located at the root of the obj tree.
The very first objects linked are listed in head-y, assigned by The very first objects linked are listed in head-y, assigned by
arch/$(ARCH)/Makefile. arch/$(ARCH)/Makefile.
7) Finally the architecture specific part does any required post processing 7) Finally, the architecture specific part does any required post processing
and builds the final bootimage. and builds the final bootimage.
- This includes building boot records - This includes building boot records
- Preparing initrd images and the like - Preparing initrd images and thelike
--- 6.1 Set variables to tweak the build to the architecture --- 6.1 Set variables to tweak the build to the architecture
...@@ -770,7 +773,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -770,7 +773,7 @@ When kbuild executes the following steps are followed (roughly):
LDFLAGS_vmlinux Options for $(LD) when linking vmlinux LDFLAGS_vmlinux Options for $(LD) when linking vmlinux
LDFLAGS_vmlinux is used to specify additional flags to pass to LDFLAGS_vmlinux is used to specify additional flags to pass to
the linker when linking the final vmlinux. the linker when linking the final vmlinux image.
LDFLAGS_vmlinux uses the LDFLAGS_$@ support. LDFLAGS_vmlinux uses the LDFLAGS_$@ support.
Example: Example:
...@@ -780,7 +783,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -780,7 +783,7 @@ When kbuild executes the following steps are followed (roughly):
OBJCOPYFLAGS objcopy flags OBJCOPYFLAGS objcopy flags
When $(call if_changed,objcopy) is used to translate a .o file, When $(call if_changed,objcopy) is used to translate a .o file,
then the flags specified in OBJCOPYFLAGS will be used. the flags specified in OBJCOPYFLAGS will be used.
$(call if_changed,objcopy) is often used to generate raw binaries on $(call if_changed,objcopy) is often used to generate raw binaries on
vmlinux. vmlinux.
...@@ -792,7 +795,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -792,7 +795,7 @@ When kbuild executes the following steps are followed (roughly):
$(obj)/image: vmlinux FORCE $(obj)/image: vmlinux FORCE
$(call if_changed,objcopy) $(call if_changed,objcopy)
In this example the binary $(obj)/image is a binary version of In this example, the binary $(obj)/image is a binary version of
vmlinux. The usage of $(call if_changed,xxx) will be described later. vmlinux. The usage of $(call if_changed,xxx) will be described later.
AFLAGS $(AS) assembler flags AFLAGS $(AS) assembler flags
...@@ -809,7 +812,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -809,7 +812,7 @@ When kbuild executes the following steps are followed (roughly):
Default value - see top level Makefile Default value - see top level Makefile
Append or modify as required per architecture. Append or modify as required per architecture.
Often the CFLAGS variable depends on the configuration. Often, the CFLAGS variable depends on the configuration.
Example: Example:
#arch/i386/Makefile #arch/i386/Makefile
...@@ -830,7 +833,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -830,7 +833,7 @@ When kbuild executes the following steps are followed (roughly):
... ...
The first examples utilises the trick that a config option expands The first example utilises the trick that a config option expands
to 'y' when selected. to 'y' when selected.
CFLAGS_KERNEL $(CC) options specific for built-in CFLAGS_KERNEL $(CC) options specific for built-in
...@@ -846,15 +849,15 @@ When kbuild executes the following steps are followed (roughly): ...@@ -846,15 +849,15 @@ When kbuild executes the following steps are followed (roughly):
--- 6.2 Add prerequisites to archprepare: --- 6.2 Add prerequisites to archprepare:
The archprepare: rule is used to list prerequisites that needs to be The archprepare: rule is used to list prerequisites that need to be
built before starting to descend down in the subdirectories. built before starting to descend down in the subdirectories.
This is usual header files containing assembler constants. This is usually used for header files containing assembler constants.
Example: Example:
#arch/arm/Makefile #arch/arm/Makefile
archprepare: maketools archprepare: maketools
In this example the file target maketools will be processed In this example, the file target maketools will be processed
before descending down in the subdirectories. before descending down in the subdirectories.
See also chapter XXX-TODO that describe how kbuild supports See also chapter XXX-TODO that describe how kbuild supports
generating offset header files. generating offset header files.
...@@ -870,15 +873,16 @@ When kbuild executes the following steps are followed (roughly): ...@@ -870,15 +873,16 @@ When kbuild executes the following steps are followed (roughly):
head-y, init-y, core-y, libs-y, drivers-y, net-y head-y, init-y, core-y, libs-y, drivers-y, net-y
$(head-y) list objects to be linked first in vmlinux. $(head-y) lists objects to be linked first in vmlinux.
$(libs-y) list directories where a lib.a archive can be located. $(libs-y) lists directories where a lib.a archive can be located.
The rest list directories where a built-in.o object file can be located. The rest lists directories where a built-in.o object file can be
located.
$(init-y) objects will be located after $(head-y). $(init-y) objects will be located after $(head-y).
Then the rest follows in this order: Then the rest follows in this order:
$(core-y), $(libs-y), $(drivers-y) and $(net-y). $(core-y), $(libs-y), $(drivers-y) and $(net-y).
The top level Makefile define values for all generic directories, The top level Makefile defines values for all generic directories,
and arch/$(ARCH)/Makefile only adds architecture specific directories. and arch/$(ARCH)/Makefile only adds architecture specific directories.
Example: Example:
...@@ -915,21 +919,21 @@ When kbuild executes the following steps are followed (roughly): ...@@ -915,21 +919,21 @@ When kbuild executes the following steps are followed (roughly):
"$(Q)$(MAKE) $(build)=<dir>" is the recommended way to invoke "$(Q)$(MAKE) $(build)=<dir>" is the recommended way to invoke
make in a subdirectory. make in a subdirectory.
There are no rules for naming of the architecture specific targets, There are no rules for naming architecture specific targets,
but executing "make help" will list all relevant targets. but executing "make help" will list all relevant targets.
To support this $(archhelp) must be defined. To support this, $(archhelp) must be defined.
Example: Example:
#arch/i386/Makefile #arch/i386/Makefile
define archhelp define archhelp
echo '* bzImage - Image (arch/$(ARCH)/boot/bzImage)' echo '* bzImage - Image (arch/$(ARCH)/boot/bzImage)'
endef endif
When make is executed without arguments, the first goal encountered When make is executed without arguments, the first goal encountered
will be built. In the top level Makefile the first goal present will be built. In the top level Makefile the first goal present
is all:. is all:.
An architecture shall always per default build a bootable image. An architecture shall always, per default, build a bootable image.
In "make help" the default goal is highlighted with a '*'. In "make help", the default goal is highlighted with a '*'.
Add a new prerequisite to all: to select a default goal different Add a new prerequisite to all: to select a default goal different
from vmlinux. from vmlinux.
...@@ -955,7 +959,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -955,7 +959,7 @@ When kbuild executes the following steps are followed (roughly):
#arch/i386/kernel/Makefile #arch/i386/kernel/Makefile
extra-y := head.o init_task.o extra-y := head.o init_task.o
In this example extra-y is used to list object files that In this example, extra-y is used to list object files that
shall be built, but shall not be linked as part of built-in.o. shall be built, but shall not be linked as part of built-in.o.
...@@ -972,8 +976,8 @@ When kbuild executes the following steps are followed (roughly): ...@@ -972,8 +976,8 @@ When kbuild executes the following steps are followed (roughly):
target: source(s) FORCE target: source(s) FORCE
$(call if_changed,ld/objcopy/gzip) $(call if_changed,ld/objcopy/gzip)
When the rule is evaluated it is checked to see if any files When the rule is evaluated, it is checked to see if any files
needs an update, or the commandline has changed since last needs an update, or the command line has changed since the last
invocation. The latter will force a rebuild if any options invocation. The latter will force a rebuild if any options
to the executable have changed. to the executable have changed.
Any target that utilises if_changed must be listed in $(targets), Any target that utilises if_changed must be listed in $(targets),
...@@ -991,7 +995,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -991,7 +995,7 @@ When kbuild executes the following steps are followed (roughly):
#WRONG!# $(call if_changed, ld/objcopy/gzip) #WRONG!# $(call if_changed, ld/objcopy/gzip)
ld ld
Link target. Often LDFLAGS_$@ is used to set specific options to ld. Link target. Often, LDFLAGS_$@ is used to set specific options to ld.
objcopy objcopy
Copy binary. Uses OBJCOPYFLAGS usually specified in Copy binary. Uses OBJCOPYFLAGS usually specified in
...@@ -1010,10 +1014,10 @@ When kbuild executes the following steps are followed (roughly): ...@@ -1010,10 +1014,10 @@ When kbuild executes the following steps are followed (roughly):
$(obj)/setup $(obj)/bootsect: %: %.o FORCE $(obj)/setup $(obj)/bootsect: %: %.o FORCE
$(call if_changed,ld) $(call if_changed,ld)
In this example there are two possible targets, requiring different In this example, there are two possible targets, requiring different
options to the linker. the linker options are specified using the options to the linker. The linker options are specified using the
LDFLAGS_$@ syntax - one for each potential target. LDFLAGS_$@ syntax - one for each potential target.
$(targets) are assinged all potential targets, herby kbuild knows $(targets) are assinged all potential targets, by which kbuild knows
the targets and will: the targets and will:
1) check for commandline changes 1) check for commandline changes
2) delete target during make clean 2) delete target during make clean
...@@ -1027,7 +1031,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -1027,7 +1031,7 @@ When kbuild executes the following steps are followed (roughly):
--- 6.7 Custom kbuild commands --- 6.7 Custom kbuild commands
When kbuild is executing with KBUILD_VERBOSE=0 then only a shorthand When kbuild is executing with KBUILD_VERBOSE=0, then only a shorthand
of a command is normally displayed. of a command is normally displayed.
To enable this behaviour for custom commands kbuild requires To enable this behaviour for custom commands kbuild requires
two variables to be set: two variables to be set:
...@@ -1045,7 +1049,7 @@ When kbuild executes the following steps are followed (roughly): ...@@ -1045,7 +1049,7 @@ When kbuild executes the following steps are followed (roughly):
$(call if_changed,image) $(call if_changed,image)
@echo 'Kernel: $@ is ready' @echo 'Kernel: $@ is ready'
When updating the $(obj)/bzImage target the line: When updating the $(obj)/bzImage target, the line
BUILD arch/i386/boot/bzImage BUILD arch/i386/boot/bzImage
...@@ -1054,11 +1058,11 @@ When kbuild executes the following steps are followed (roughly): ...@@ -1054,11 +1058,11 @@ When kbuild executes the following steps are followed (roughly):
--- 6.8 Preprocessing linker scripts --- 6.8 Preprocessing linker scripts
When the vmlinux image is build the linker script: When the vmlinux image is built, the linker script
arch/$(ARCH)/kernel/vmlinux.lds is used. arch/$(ARCH)/kernel/vmlinux.lds is used.
The script is a preprocessed variant of the file vmlinux.lds.S The script is a preprocessed variant of the file vmlinux.lds.S
located in the same directory. located in the same directory.
kbuild knows .lds file and includes a rule *lds.S -> *lds. kbuild knows .lds files and includes a rule *lds.S -> *lds.
Example: Example:
#arch/i386/kernel/Makefile #arch/i386/kernel/Makefile
...@@ -1067,12 +1071,12 @@ When kbuild executes the following steps are followed (roughly): ...@@ -1067,12 +1071,12 @@ When kbuild executes the following steps are followed (roughly):
#Makefile #Makefile
export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH) export CPPFLAGS_vmlinux.lds += -P -C -U$(ARCH)
The assigment to $(always) is used to tell kbuild to build the The assignment to $(always) is used to tell kbuild to build the
target: vmlinux.lds. target vmlinux.lds.
The assignment to $(CPPFLAGS_vmlinux.lds) tell kbuild to use the The assignment to $(CPPFLAGS_vmlinux.lds) tells kbuild to use the
specified options when building the target vmlinux.lds. specified options when building the target vmlinux.lds.
When building the *.lds target kbuild used the variakles: When building the *.lds target, kbuild uses the variables:
CPPFLAGS : Set in top-level Makefile CPPFLAGS : Set in top-level Makefile
EXTRA_CPPFLAGS : May be set in the kbuild makefile EXTRA_CPPFLAGS : May be set in the kbuild makefile
CPPFLAGS_$(@F) : Target specific flags. CPPFLAGS_$(@F) : Target specific flags.
...@@ -1147,7 +1151,7 @@ The top Makefile exports the following variables: ...@@ -1147,7 +1151,7 @@ The top Makefile exports the following variables:
=== 8 Makefile language === 8 Makefile language
The kernel Makefiles are designed to run with GNU Make. The Makefiles The kernel Makefiles are designed to be run with GNU Make. The Makefiles
use only the documented features of GNU Make, but they do use many use only the documented features of GNU Make, but they do use many
GNU extensions. GNU extensions.
...@@ -1169,10 +1173,13 @@ is the right choice. ...@@ -1169,10 +1173,13 @@ is the right choice.
Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net> Original version made by Michael Elizabeth Chastain, <mailto:mec@shout.net>
Updates by Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de> Updates by Kai Germaschewski <kai@tp1.ruhr-uni-bochum.de>
Updates by Sam Ravnborg <sam@ravnborg.org> Updates by Sam Ravnborg <sam@ravnborg.org>
Language QA by Jan Engelhardt <jengelh@gmx.de>
=== 10 TODO === 10 TODO
- Describe how kbuild support shipped files with _shipped. - Describe how kbuild supports shipped files with _shipped.
- Generating offset header files. - Generating offset header files.
- Add more variables to section 7? - Add more variables to section 7?
In this document you will find information about: In this document you will find information about:
- how to build external modules - how to build external modules
- how to make your module use kbuild infrastructure - how to make your module use the kbuild infrastructure
- how kbuild will install a kernel - how kbuild will install a kernel
- how to install modules in a non-standard location - how to install modules in a non-standard location
...@@ -24,7 +24,7 @@ In this document you will find information about: ...@@ -24,7 +24,7 @@ In this document you will find information about:
--- 6.1 INSTALL_MOD_PATH --- 6.1 INSTALL_MOD_PATH
--- 6.2 INSTALL_MOD_DIR --- 6.2 INSTALL_MOD_DIR
=== 7. Module versioning & Module.symvers === 7. Module versioning & Module.symvers
--- 7.1 Symbols fron the kernel (vmlinux + modules) --- 7.1 Symbols from the kernel (vmlinux + modules)
--- 7.2 Symbols and external modules --- 7.2 Symbols and external modules
--- 7.3 Symbols from another external module --- 7.3 Symbols from another external module
=== 8. Tips & Tricks === 8. Tips & Tricks
...@@ -36,13 +36,13 @@ In this document you will find information about: ...@@ -36,13 +36,13 @@ In this document you will find information about:
kbuild includes functionality for building modules both kbuild includes functionality for building modules both
within the kernel source tree and outside the kernel source tree. within the kernel source tree and outside the kernel source tree.
The latter is usually referred to as external modules and is used The latter is usually referred to as external or "out-of-tree"
both during development and for modules that are not planned to be modules and is used both during development and for modules that
included in the kernel tree. are not planned to be included in the kernel tree.
What is covered within this file is mainly information to authors What is covered within this file is mainly information to authors
of modules. The author of an external modules should supply of modules. The author of an external module should supply
a makefile that hides most of the complexity so one only has to type a makefile that hides most of the complexity, so one only has to type
'make' to build the module. A complete example will be present in 'make' to build the module. A complete example will be present in
chapter 4, "Creating a kbuild file for an external module". chapter 4, "Creating a kbuild file for an external module".
...@@ -63,14 +63,15 @@ when building an external module. ...@@ -63,14 +63,15 @@ when building an external module.
For the running kernel use: For the running kernel use:
make -C /lib/modules/`uname -r`/build M=`pwd` make -C /lib/modules/`uname -r`/build M=`pwd`
For the above command to succeed the kernel must have been built with For the above command to succeed, the kernel must have been
modules enabled. built with modules enabled.
To install the modules that were just built: To install the modules that were just built:
make -C <path-to-kernel> M=`pwd` modules_install make -C <path-to-kernel> M=`pwd` modules_install
More complex examples later, the above should get you going. More complex examples will be shown later, the above should
be enough to get you started.
--- 2.2 Available targets --- 2.2 Available targets
...@@ -89,13 +90,13 @@ when building an external module. ...@@ -89,13 +90,13 @@ when building an external module.
Same functionality as if no target was specified. Same functionality as if no target was specified.
See description above. See description above.
make -C $KDIR M=$PWD modules_install make -C $KDIR M=`pwd` modules_install
Install the external module(s). Install the external module(s).
Installation default is in /lib/modules/<kernel-version>/extra, Installation default is in /lib/modules/<kernel-version>/extra,
but may be prefixed with INSTALL_MOD_PATH - see separate but may be prefixed with INSTALL_MOD_PATH - see separate
chapter. chapter.
make -C $KDIR M=$PWD clean make -C $KDIR M=`pwd` clean
Remove all generated files for the module - the kernel Remove all generated files for the module - the kernel
source directory is not modified. source directory is not modified.
...@@ -129,17 +130,16 @@ when building an external module. ...@@ -129,17 +130,16 @@ when building an external module.
To make sure the kernel contains the information required to To make sure the kernel contains the information required to
build external modules the target 'modules_prepare' must be used. build external modules the target 'modules_prepare' must be used.
'module_prepare' solely exists as a simple way to prepare 'module_prepare' exists solely as a simple way to prepare
a kernel for building external modules. a kernel source tree for building external modules.
Note: modules_prepare will not build Module.symvers even if Note: modules_prepare will not build Module.symvers even if
CONFIG_MODULEVERSIONING is set. CONFIG_MODULEVERSIONING is set. Therefore a full kernel build
Therefore a full kernel build needs to be executed to make needs to be executed to make module versioning work.
module versioning work.
--- 2.5 Building separate files for a module --- 2.5 Building separate files for a module
It is possible to build single files which is part of a module. It is possible to build single files which are part of a module.
This works equal for the kernel, a module and even for external This works equally well for the kernel, a module and even for
modules. external modules.
Examples (module foo.ko, consist of bar.o, baz.o): Examples (module foo.ko, consist of bar.o, baz.o):
make -C $KDIR M=`pwd` bar.lst make -C $KDIR M=`pwd` bar.lst
make -C $KDIR M=`pwd` bar.o make -C $KDIR M=`pwd` bar.o
...@@ -151,7 +151,7 @@ when building an external module. ...@@ -151,7 +151,7 @@ when building an external module.
This example shows the actual commands to be executed when building This example shows the actual commands to be executed when building
an external module for the currently running kernel. an external module for the currently running kernel.
In the example below the distribution is supposed to use the In the example below, the distribution is supposed to use the
facility to locate output files for a kernel compile in a different facility to locate output files for a kernel compile in a different
directory than the kernel source - but the examples will also work directory than the kernel source - but the examples will also work
when the source and the output files are mixed in the same directory. when the source and the output files are mixed in the same directory.
...@@ -170,14 +170,14 @@ the following commands to build the module: ...@@ -170,14 +170,14 @@ the following commands to build the module:
O=/lib/modules/`uname-r`/build \ O=/lib/modules/`uname-r`/build \
M=`pwd` M=`pwd`
Then to install the module use the following command: Then, to install the module use the following command:
make -C /usr/src/`uname -r`/source \ make -C /usr/src/`uname -r`/source \
O=/lib/modules/`uname-r`/build \ O=/lib/modules/`uname-r`/build \
M=`pwd` \ M=`pwd` \
modules_install modules_install
If one looks closely you will see that this is the same commands as If you look closely you will see that this is the same command as
listed before - with the directories spelled out. listed before - with the directories spelled out.
The above are rather long commands, and the following chapter The above are rather long commands, and the following chapter
...@@ -230,7 +230,7 @@ following files: ...@@ -230,7 +230,7 @@ following files:
endif endif
In example 1 the check for KERNELRELEASE is used to separate In example 1, the check for KERNELRELEASE is used to separate
the two parts of the Makefile. kbuild will only see the two the two parts of the Makefile. kbuild will only see the two
assignments whereas make will see everything except the two assignments whereas make will see everything except the two
kbuild assignments. kbuild assignments.
...@@ -255,7 +255,7 @@ following files: ...@@ -255,7 +255,7 @@ following files:
echo "X" > 8123_bin_shipped echo "X" > 8123_bin_shipped
In example 2 we are down to two fairly simple files and for simple In example 2, we are down to two fairly simple files and for simple
files as used in this example the split is questionable. But some files as used in this example the split is questionable. But some
external modules use Makefiles of several hundred lines and here it external modules use Makefiles of several hundred lines and here it
really pays off to separate the kbuild part from the rest. really pays off to separate the kbuild part from the rest.
...@@ -282,8 +282,8 @@ following files: ...@@ -282,8 +282,8 @@ following files:
endif endif
The trick here is to include the Kbuild file from Makefile so The trick here is to include the Kbuild file from Makefile, so
if an older version of kbuild picks up the Makefile the Kbuild if an older version of kbuild picks up the Makefile, the Kbuild
file will be included. file will be included.
--- 4.2 Binary blobs included in a module --- 4.2 Binary blobs included in a module
...@@ -301,18 +301,19 @@ following files: ...@@ -301,18 +301,19 @@ following files:
obj-m := 8123.o obj-m := 8123.o
8123-y := 8123_if.o 8123_pci.o 8123_bin.o 8123-y := 8123_if.o 8123_pci.o 8123_bin.o
In example 4 there is no distinction between the ordinary .c/.h files In example 4, there is no distinction between the ordinary .c/.h files
and the binary file. But kbuild will pick up different rules to create and the binary file. But kbuild will pick up different rules to create
the .o file. the .o file.
=== 5. Include files === 5. Include files
Include files are a necessity when a .c file uses something from another .c Include files are a necessity when a .c file uses something from other .c
files (not strictly in the sense of .c but if good programming practice is files (not strictly in the sense of C, but if good programming practice is
used). Any module that consist of more than one .c file will have a .h file used). Any module that consists of more than one .c file will have a .h file
for one of the .c files. for one of the .c files.
- If the .h file only describes a module internal interface then the .h file
- If the .h file only describes a module internal interface, then the .h file
shall be placed in the same directory as the .c files. shall be placed in the same directory as the .c files.
- If the .h files describe an interface used by other parts of the kernel - If the .h files describe an interface used by other parts of the kernel
located in different directories, the .h files shall be located in located in different directories, the .h files shall be located in
...@@ -323,11 +324,11 @@ under include/ such as include/scsi. Another exception is arch-specific ...@@ -323,11 +324,11 @@ under include/ such as include/scsi. Another exception is arch-specific
.h files which are located under include/asm-$(ARCH)/*. .h files which are located under include/asm-$(ARCH)/*.
External modules have a tendency to locate include files in a separate include/ External modules have a tendency to locate include files in a separate include/
directory and therefore needs to deal with this in their kbuild file. directory and therefore need to deal with this in their kbuild file.
--- 5.1 How to include files from the kernel include dir --- 5.1 How to include files from the kernel include dir
When a module needs to include a file from include/linux/ then one When a module needs to include a file from include/linux/, then one
just uses: just uses:
#include <linux/modules.h> #include <linux/modules.h>
...@@ -348,7 +349,7 @@ directory and therefore needs to deal with this in their kbuild file. ...@@ -348,7 +349,7 @@ directory and therefore needs to deal with this in their kbuild file.
The trick here is to use either EXTRA_CFLAGS (take effect for all .c The trick here is to use either EXTRA_CFLAGS (take effect for all .c
files) or CFLAGS_$F.o (take effect only for a single file). files) or CFLAGS_$F.o (take effect only for a single file).
In our example if we move 8123_if.h to a subdirectory named include/ In our example, if we move 8123_if.h to a subdirectory named include/
the resulting Kbuild file would look like: the resulting Kbuild file would look like:
--> filename: Kbuild --> filename: Kbuild
...@@ -362,9 +363,9 @@ directory and therefore needs to deal with this in their kbuild file. ...@@ -362,9 +363,9 @@ directory and therefore needs to deal with this in their kbuild file.
--- 5.3 External modules using several directories --- 5.3 External modules using several directories
If an external module does not follow the usual kernel style but If an external module does not follow the usual kernel style, but
decide to spread files over several directories then kbuild can decides to spread files over several directories, then kbuild can
support this too. handle this too.
Consider the following example: Consider the following example:
...@@ -374,7 +375,7 @@ directory and therefore needs to deal with this in their kbuild file. ...@@ -374,7 +375,7 @@ directory and therefore needs to deal with this in their kbuild file.
| +- hal/include/hardwareif.h | +- hal/include/hardwareif.h
+- include/complex.h +- include/complex.h
To build a single module named complex.ko we then need the following To build a single module named complex.ko, we then need the following
kbuild file: kbuild file:
Kbuild: Kbuild:
...@@ -387,12 +388,12 @@ directory and therefore needs to deal with this in their kbuild file. ...@@ -387,12 +388,12 @@ directory and therefore needs to deal with this in their kbuild file.
kbuild knows how to handle .o files located in another directory - kbuild knows how to handle .o files located in another directory -
although this is NOT reccommended practice. The syntax is to specify although this is NOT recommended practice. The syntax is to specify
the directory relative to the directory where the Kbuild file is the directory relative to the directory where the Kbuild file is
located. located.
To find the .h files we have to explicitly tell kbuild where to look To find the .h files, we have to explicitly tell kbuild where to look
for the .h files. When kbuild executes current directory is always for the .h files. When kbuild executes, the current directory is always
the root of the kernel tree (argument to -C) and therefore we have to the root of the kernel tree (argument to -C) and therefore we have to
tell kbuild how to find the .h files using absolute paths. tell kbuild how to find the .h files using absolute paths.
$(src) will specify the absolute path to the directory where the $(src) will specify the absolute path to the directory where the
...@@ -412,7 +413,7 @@ External modules are installed in the directory: ...@@ -412,7 +413,7 @@ External modules are installed in the directory:
--- 6.1 INSTALL_MOD_PATH --- 6.1 INSTALL_MOD_PATH
Above are the default directories, but as always some level of Above are the default directories, but as always, some level of
customization is possible. One can prefix the path using the variable customization is possible. One can prefix the path using the variable
INSTALL_MOD_PATH: INSTALL_MOD_PATH:
...@@ -420,17 +421,17 @@ External modules are installed in the directory: ...@@ -420,17 +421,17 @@ External modules are installed in the directory:
=> Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel
INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the
example above be specified on the command line when calling make. example above, can be specified on the command line when calling make.
INSTALL_MOD_PATH has effect both when installing modules included in INSTALL_MOD_PATH has effect both when installing modules included in
the kernel as well as when installing external modules. the kernel as well as when installing external modules.
--- 6.2 INSTALL_MOD_DIR --- 6.2 INSTALL_MOD_DIR
When installing external modules they are default installed in a When installing external modules they are by default installed to a
directory under /lib/modules/$(KERNELRELEASE)/extra, but one may wish directory under /lib/modules/$(KERNELRELEASE)/extra, but one may wish
to locate modules for a specific functionality in a separate to locate modules for a specific functionality in a separate
directory. For this purpose one can use INSTALL_MOD_DIR to specify an directory. For this purpose, one can use INSTALL_MOD_DIR to specify an
alternative name than 'extra'. alternative name to 'extra'.
$ make INSTALL_MOD_DIR=gandalf -C KERNELDIR \ $ make INSTALL_MOD_DIR=gandalf -C KERNELDIR \
M=`pwd` modules_install M=`pwd` modules_install
...@@ -444,16 +445,16 @@ Module versioning is enabled by the CONFIG_MODVERSIONS tag. ...@@ -444,16 +445,16 @@ Module versioning is enabled by the CONFIG_MODVERSIONS tag.
Module versioning is used as a simple ABI consistency check. The Module Module versioning is used as a simple ABI consistency check. The Module
versioning creates a CRC value of the full prototype for an exported symbol and versioning creates a CRC value of the full prototype for an exported symbol and
when a module is loaded/used then the CRC values contained in the kernel are when a module is loaded/used then the CRC values contained in the kernel are
compared with similar values in the module. If they are not equal then the compared with similar values in the module. If they are not equal, then the
kernel refuses to load the module. kernel refuses to load the module.
Module.symvers contains a list of all exported symbols from a kernel build. Module.symvers contains a list of all exported symbols from a kernel build.
--- 7.1 Symbols fron the kernel (vmlinux + modules) --- 7.1 Symbols fron the kernel (vmlinux + modules)
During a kernel build a file named Module.symvers will be generated. During a kernel build, a file named Module.symvers will be generated.
Module.symvers contains all exported symbols from the kernel and Module.symvers contains all exported symbols from the kernel and
compiled modules. For each symbols the corresponding CRC value compiled modules. For each symbols, the corresponding CRC value
is stored too. is stored too.
The syntax of the Module.symvers file is: The syntax of the Module.symvers file is:
...@@ -461,27 +462,27 @@ Module.symvers contains a list of all exported symbols from a kernel build. ...@@ -461,27 +462,27 @@ Module.symvers contains a list of all exported symbols from a kernel build.
Sample: Sample:
0x2d036834 scsi_remove_host drivers/scsi/scsi_mod 0x2d036834 scsi_remove_host drivers/scsi/scsi_mod
For a kernel build without CONFIG_MODVERSIONING enabled the crc For a kernel build without CONFIG_MODVERSIONS enabled, the crc
would read: 0x00000000 would read: 0x00000000
Module.symvers serve two purposes. Module.symvers serves two purposes:
1) It list all exported symbols both from vmlinux and all modules 1) It lists all exported symbols both from vmlinux and all modules
2) It list CRC if CONFIG_MODVERSION is enabled 2) It lists the CRC if CONFIG_MODVERSIONS is enabled
--- 7.2 Symbols and external modules --- 7.2 Symbols and external modules
When building an external module the build system needs access to When building an external module, the build system needs access to
the symbols from the kernel to check if all external symbols are the symbols from the kernel to check if all external symbols are
defined. This is done in the MODPOST step and to obtain all defined. This is done in the MODPOST step and to obtain all
symbols modpost reads Module.symvers from the kernel. symbols, modpost reads Module.symvers from the kernel.
If a Module.symvers file is present in the directory where If a Module.symvers file is present in the directory where
the external module is being build this file will be read too. the external module is being built, this file will be read too.
During the MODPOST step a new Module.symvers file will be written During the MODPOST step, a new Module.symvers file will be written
containing all exported symbols that was not defined in the kernel. containing all exported symbols that were not defined in the kernel.
--- 7.3 Symbols from another external module --- 7.3 Symbols from another external module
Sometimes one external module uses exported symbols from another Sometimes, an external module uses exported symbols from another
external module. Kbuild needs to have full knowledge on all symbols external module. Kbuild needs to have full knowledge on all symbols
to avoid spitting out warnings about undefined symbols. to avoid spitting out warnings about undefined symbols.
Two solutions exist to let kbuild know all symbols of more than Two solutions exist to let kbuild know all symbols of more than
...@@ -490,9 +491,9 @@ Module.symvers contains a list of all exported symbols from a kernel build. ...@@ -490,9 +491,9 @@ Module.symvers contains a list of all exported symbols from a kernel build.
impractical in certain situations. impractical in certain situations.
Use a top-level Kbuild file Use a top-level Kbuild file
If you have two modules: 'foo', 'bar' and 'foo' needs symbols If you have two modules: 'foo' and 'bar', and 'foo' needs
from 'bar' then one can use a common top-level kbuild file so symbols from 'bar', then one can use a common top-level kbuild
both modules are compiled in same build. file so both modules are compiled in same build.
Consider following directory layout: Consider following directory layout:
./foo/ <= contains the foo module ./foo/ <= contains the foo module
...@@ -509,15 +510,15 @@ Module.symvers contains a list of all exported symbols from a kernel build. ...@@ -509,15 +510,15 @@ Module.symvers contains a list of all exported symbols from a kernel build.
knowledge on symbols from both modules. knowledge on symbols from both modules.
Use an extra Module.symvers file Use an extra Module.symvers file
When an external module is build a Module.symvers file is When an external module is built, a Module.symvers file is
generated containing all exported symbols which are not generated containing all exported symbols which are not
defined in the kernel. defined in the kernel.
To get access to symbols from module 'bar' one can copy the To get access to symbols from module 'bar', one can copy the
Module.symvers file from the compilation of the 'bar' module Module.symvers file from the compilation of the 'bar' module
to the directory where the 'foo' module is build. to the directory where the 'foo' module is built.
During the module build kbuild will read the Module.symvers During the module build, kbuild will read the Module.symvers
file in the directory of the external module and when the file in the directory of the external module and when the
build is finished a new Module.symvers file is created build is finished, a new Module.symvers file is created
containing the sum of all symbols defined and not part of the containing the sum of all symbols defined and not part of the
kernel. kernel.
...@@ -525,7 +526,7 @@ Module.symvers contains a list of all exported symbols from a kernel build. ...@@ -525,7 +526,7 @@ Module.symvers contains a list of all exported symbols from a kernel build.
--- 8.1 Testing for CONFIG_FOO_BAR --- 8.1 Testing for CONFIG_FOO_BAR
Modules often needs to check for certain CONFIG_ options to decide if Modules often need to check for certain CONFIG_ options to decide if
a specific feature shall be included in the module. When kbuild is used a specific feature shall be included in the module. When kbuild is used
this is done by referencing the CONFIG_ variable directly. this is done by referencing the CONFIG_ variable directly.
...@@ -537,7 +538,7 @@ Module.symvers contains a list of all exported symbols from a kernel build. ...@@ -537,7 +538,7 @@ Module.symvers contains a list of all exported symbols from a kernel build.
External modules have traditionally used grep to check for specific External modules have traditionally used grep to check for specific
CONFIG_ settings directly in .config. This usage is broken. CONFIG_ settings directly in .config. This usage is broken.
As introduced before external modules shall use kbuild when building As introduced before, external modules shall use kbuild when building
and therefore can use the same methods as in-kernel modules when testing and therefore can use the same methods as in-kernel modules when
for CONFIG_ definitions. testing for CONFIG_ definitions.
...@@ -69,10 +69,10 @@ recompiled, or use "make C=2" to run sparse on the files whether they need to ...@@ -69,10 +69,10 @@ recompiled, or use "make C=2" to run sparse on the files whether they need to
be recompiled or not. The latter is a fast way to check the whole tree if you be recompiled or not. The latter is a fast way to check the whole tree if you
have already built it. have already built it.
The optional make variable CF can be used to pass arguments to sparse. The The optional make variable CHECKFLAGS can be used to pass arguments to sparse.
build system passes -Wbitwise to sparse automatically. To perform endianness The build system passes -Wbitwise to sparse automatically. To perform
checks, you may define __CHECK_ENDIAN__: endianness checks, you may define __CHECK_ENDIAN__:
make C=2 CF="-D__CHECK_ENDIAN__" make C=2 CHECKFLAGS="-D__CHECK_ENDIAN__"
These checks are disabled by default as they generate a host of warnings. These checks are disabled by default as they generate a host of warnings.
...@@ -28,7 +28,7 @@ define cmd_offsets ...@@ -28,7 +28,7 @@ define cmd_offsets
echo "/*"; \ echo "/*"; \
echo " * DO NOT MODIFY."; \ echo " * DO NOT MODIFY."; \
echo " *"; \ echo " *"; \
echo " * This file was generated by $(srctree)/Kbuild"; \ echo " * This file was generated by Kbuild"; \
echo " *"; \ echo " *"; \
echo " */"; \ echo " */"; \
echo ""; \ echo ""; \
......
...@@ -41,9 +41,15 @@ ifndef KBUILD_VERBOSE ...@@ -41,9 +41,15 @@ ifndef KBUILD_VERBOSE
KBUILD_VERBOSE = 0 KBUILD_VERBOSE = 0
endif endif
# Call checker as part of compilation of C files # Call a source code checker (by default, "sparse") as part of the
# Use 'make C=1' to enable checking (sparse, by default) # C compilation.
# Override with 'make C=1 CHECK=checker_executable CHECKFLAGS=....' #
# Use 'make C=1' to enable checking of only re-compiled files.
# Use 'make C=2' to enable checking of *all* source files, regardless
# of whether they are re-compiled or not.
#
# See the file "Documentation/sparse.txt" for more details, including
# where to get the "sparse" utility.
ifdef C ifdef C
ifeq ("$(origin C)", "command line") ifeq ("$(origin C)", "command line")
...@@ -736,6 +742,7 @@ endif # ifdef CONFIG_KALLSYMS ...@@ -736,6 +742,7 @@ endif # ifdef CONFIG_KALLSYMS
# vmlinux image - including updated kernel symbols # vmlinux image - including updated kernel symbols
vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE vmlinux: $(vmlinux-lds) $(vmlinux-init) $(vmlinux-main) $(kallsyms.o) FORCE
$(call if_changed_rule,vmlinux__) $(call if_changed_rule,vmlinux__)
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost $@
$(Q)rm -f .old_version $(Q)rm -f .old_version
# The actual objects are generated when descending, # The actual objects are generated when descending,
...@@ -753,12 +760,34 @@ $(vmlinux-dirs): prepare scripts ...@@ -753,12 +760,34 @@ $(vmlinux-dirs): prepare scripts
$(Q)$(MAKE) $(build)=$@ $(Q)$(MAKE) $(build)=$@
# Build the kernel release string # Build the kernel release string
# The KERNELRELEASE is stored in a file named include/config/kernel.release
# to be used when executing for example make install or make modules_install
# #
# Take the contents of any files called localversion* and the config # The KERNELRELEASE value built here is stored in the file
# variable CONFIG_LOCALVERSION and append them to KERNELRELEASE. # include/config/kernel.release, and is used when executing several
# LOCALVERSION from the command line override all of this # make targets, such as "make install" or "make modules_install."
#
# The eventual kernel release string consists of the following fields,
# shown in a hierarchical format to show how smaller parts are concatenated
# to form the larger and final value, with values coming from places like
# the Makefile, kernel config options, make command line options and/or
# SCM tag information.
#
# $(KERNELVERSION)
# $(VERSION) eg, 2
# $(PATCHLEVEL) eg, 6
# $(SUBLEVEL) eg, 18
# $(EXTRAVERSION) eg, -rc6
# $(localver-full)
# $(localver)
# localversion* (all localversion* files)
# $(CONFIG_LOCALVERSION) (from kernel config setting)
# $(localver-auto) (only if CONFIG_LOCALVERSION_AUTO is set)
# ./scripts/setlocalversion (SCM tag, if one exists)
# $(LOCALVERSION) (from make command line if provided)
#
# Note how the final $(localver-auto) string is included *only* if the
# kernel config option CONFIG_LOCALVERSION_AUTO is selected. Also, at the
# moment, only git is supported but other SCMs can edit the script
# scripts/setlocalversion and add the appropriate checks as needed.
nullstring := nullstring :=
space := $(nullstring) # end of line space := $(nullstring) # end of line
...@@ -893,14 +922,14 @@ INSTALL_HDR_PATH=$(objtree)/usr ...@@ -893,14 +922,14 @@ INSTALL_HDR_PATH=$(objtree)/usr
export INSTALL_HDR_PATH export INSTALL_HDR_PATH
PHONY += headers_install PHONY += headers_install
headers_install: include/linux/version.h headers_install: include/linux/version.h scripts_basic FORCE
$(Q)unifdef -Ux /dev/null $(Q)$(MAKE) $(build)=scripts scripts/unifdef
$(Q)rm -rf $(INSTALL_HDR_PATH)/include $(Q)rm -rf $(INSTALL_HDR_PATH)/include
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.headersinst obj=include $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include
PHONY += headers_check PHONY += headers_check
headers_check: headers_install headers_check: headers_install
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.headersinst obj=include HDRCHECK=1 $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.headersinst obj=include HDRCHECK=1
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# Modules # Modules
...@@ -916,7 +945,7 @@ all: modules ...@@ -916,7 +945,7 @@ all: modules
PHONY += modules PHONY += modules
modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux) modules: $(vmlinux-dirs) $(if $(KBUILD_BUILTIN),vmlinux)
@echo ' Building modules, stage 2.'; @echo ' Building modules, stage 2.';
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
# Target to prepare building external modules # Target to prepare building external modules
...@@ -942,7 +971,7 @@ _modinst_: ...@@ -942,7 +971,7 @@ _modinst_:
rm -f $(MODLIB)/build ; \ rm -f $(MODLIB)/build ; \
ln -s $(objtree) $(MODLIB)/build ; \ ln -s $(objtree) $(MODLIB)/build ; \
fi fi
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
# If System.map exists, run depmod. This deliberately does not have a # If System.map exists, run depmod. This deliberately does not have a
# dependency on System.map since that would run the dependency tree on # dependency on System.map since that would run the dependency tree on
...@@ -1057,8 +1086,10 @@ boards := $(notdir $(boards)) ...@@ -1057,8 +1086,10 @@ boards := $(notdir $(boards))
help: help:
@echo 'Cleaning targets:' @echo 'Cleaning targets:'
@echo ' clean - remove most generated files but keep the config' @echo ' clean - remove most generated files but keep the config and'
@echo ' enough build support to build external modules'
@echo ' mrproper - remove all generated files + config + various backup files' @echo ' mrproper - remove all generated files + config + various backup files'
@echo ' distclean - mrproper + remove editor backup and patch files'
@echo '' @echo ''
@echo 'Configuration targets:' @echo 'Configuration targets:'
@$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help @$(MAKE) -f $(srctree)/scripts/kconfig/Makefile help
...@@ -1100,6 +1131,7 @@ help: ...@@ -1100,6 +1131,7 @@ help:
echo '') echo '')
@echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build' @echo ' make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build'
@echo ' make V=2 [targets] 2 => give reason for rebuild of target'
@echo ' make O=dir [targets] Locate all output files in "dir", including .config' @echo ' make O=dir [targets] Locate all output files in "dir", including .config'
@echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)' @echo ' make C=1 [targets] Check all c source with $$CHECK (sparse by default)'
@echo ' make C=2 [targets] Force check of all c source with $$CHECK' @echo ' make C=2 [targets] Force check of all c source with $$CHECK'
...@@ -1154,7 +1186,7 @@ $(module-dirs): crmodverdir $(objtree)/Module.symvers ...@@ -1154,7 +1186,7 @@ $(module-dirs): crmodverdir $(objtree)/Module.symvers
modules: $(module-dirs) modules: $(module-dirs)
@echo ' Building modules, stage 2.'; @echo ' Building modules, stage 2.';
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
PHONY += modules_install PHONY += modules_install
modules_install: _emodinst_ _emodinst_post modules_install: _emodinst_ _emodinst_post
...@@ -1163,7 +1195,7 @@ install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra) ...@@ -1163,7 +1195,7 @@ install-dir := $(if $(INSTALL_MOD_DIR),$(INSTALL_MOD_DIR),extra)
PHONY += _emodinst_ PHONY += _emodinst_
_emodinst_: _emodinst_:
$(Q)mkdir -p $(MODLIB)/$(install-dir) $(Q)mkdir -p $(MODLIB)/$(install-dir)
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst
# Run depmod only is we have System.map and depmod is executable # Run depmod only is we have System.map and depmod is executable
quiet_cmd_depmod = DEPMOD $(KERNELRELEASE) quiet_cmd_depmod = DEPMOD $(KERNELRELEASE)
...@@ -1264,6 +1296,31 @@ define all-defconfigs ...@@ -1264,6 +1296,31 @@ define all-defconfigs
$(call find-sources,'defconfig') $(call find-sources,'defconfig')
endef endef
define xtags
if $1 --version 2>&1 | grep -iq exuberant; then \
$(all-sources) | xargs $1 -a \
-I __initdata,__exitdata,__acquires,__releases \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
--extra=+f --c-kinds=+px; \
$(all-kconfigs) | xargs $1 -a \
--langdef=kconfig \
--language-force=kconfig \
--regex-kconfig='/^[[:blank:]]*config[[:blank:]]+([[:alnum:]_]+)/\1/'; \
$(all-defconfigs) | xargs $1 -a \
--langdef=dotconfig \
--language-force=dotconfig \
--regex-dotconfig='/^#?[[:blank:]]*(CONFIG_[[:alnum:]_]+)/\1/'; \
elif $1 --version 2>&1 | grep -iq emacs; then \
$(all-sources) | xargs $1 -a; \
$(all-kconfigs) | xargs $1 -a \
--regex='/^[ \t]*config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \
$(all-defconfigs) | xargs $1 -a \
--regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \
else \
$(all-sources) | xargs $1 -a; \
fi
endef
quiet_cmd_cscope-file = FILELST cscope.files quiet_cmd_cscope-file = FILELST cscope.files
cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files cmd_cscope-file = (echo \-k; echo \-q; $(all-sources)) > cscope.files
...@@ -1277,31 +1334,16 @@ cscope: FORCE ...@@ -1277,31 +1334,16 @@ cscope: FORCE
quiet_cmd_TAGS = MAKE $@ quiet_cmd_TAGS = MAKE $@
define cmd_TAGS define cmd_TAGS
rm -f $@; \ rm -f $@; \
ETAGSF=`etags --version | grep -i exuberant >/dev/null && \ $(call xtags,etags)
echo "-I __initdata,__exitdata,__acquires,__releases \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
--extra=+f --c-kinds=+px"`; \
$(all-sources) | xargs etags $$ETAGSF -a; \
if test "x$$ETAGSF" = x; then \
$(all-kconfigs) | xargs etags -a \
--regex='/^config[ \t]+\([a-zA-Z0-9_]+\)/\1/'; \
$(all-defconfigs) | xargs etags -a \
--regex='/^#?[ \t]?\(CONFIG_[a-zA-Z0-9_]+\)/\1/'; \
fi
endef endef
TAGS: FORCE TAGS: FORCE
$(call cmd,TAGS) $(call cmd,TAGS)
quiet_cmd_tags = MAKE $@ quiet_cmd_tags = MAKE $@
define cmd_tags define cmd_tags
rm -f $@; \ rm -f $@; \
CTAGSF=`ctags --version | grep -i exuberant >/dev/null && \ $(call xtags,ctags)
echo "-I __initdata,__exitdata,__acquires,__releases \
-I EXPORT_SYMBOL,EXPORT_SYMBOL_GPL \
--extra=+f --c-kinds=+px"`; \
$(all-sources) | xargs ctags $$CTAGSF -a
endef endef
tags: FORCE tags: FORCE
...@@ -1379,7 +1421,7 @@ endif ...@@ -1379,7 +1421,7 @@ endif
%.ko: prepare scripts FORCE %.ko: prepare scripts FORCE
$(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \ $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
$(build)=$(build-dir) $(@:.ko=.o) $(build)=$(build-dir) $(@:.ko=.o)
$(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modpost $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost
# FIXME Should go into a make.lib or something # FIXME Should go into a make.lib or something
# =========================================================================== # ===========================================================================
......
...@@ -7,10 +7,14 @@ squote := ' ...@@ -7,10 +7,14 @@ squote := '
empty := empty :=
space := $(empty) $(empty) space := $(empty) $(empty)
###
# Name of target with a '.' as filename prefix. foo/bar.o => foo/.bar.o
dot-target = $(dir $@).$(notdir $@)
### ###
# The temporary file to save gcc -MD generated dependencies must not # The temporary file to save gcc -MD generated dependencies must not
# contain a comma # contain a comma
depfile = $(subst $(comma),_,$(@D)/.$(@F).d) depfile = $(subst $(comma),_,$(dot-target).d)
### ###
# filename of target with directory and extension stripped # filename of target with directory and extension stripped
...@@ -119,40 +123,83 @@ objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o))) ...@@ -119,40 +123,83 @@ objectify = $(foreach o,$(1),$(if $(filter /%,$(o)),$(o),$(obj)/$(o)))
ifneq ($(KBUILD_NOCMDDEP),1) ifneq ($(KBUILD_NOCMDDEP),1)
# Check if both arguments has same arguments. Result in empty string if equal # Check if both arguments has same arguments. Result in empty string if equal
# User may override this check using make KBUILD_NOCMDDEP=1 # User may override this check using make KBUILD_NOCMDDEP=1
arg-check = $(strip $(filter-out $(1), $(2)) $(filter-out $(2), $(1)) ) arg-check = $(strip $(filter-out $(cmd_$(1)), $(cmd_$@)) \
$(filter-out $(cmd_$@), $(cmd_$(1))) )
endif endif
# echo command. Short version is $(quiet) equals quiet, otherwise full command # echo command. Short version is $(quiet) equals quiet, otherwise full command
echo-cmd = $(if $($(quiet)cmd_$(1)), \ echo-cmd = $(if $($(quiet)cmd_$(1)), \
echo ' $(call escsq,$($(quiet)cmd_$(1)))';) echo ' $(call escsq,$($(quiet)cmd_$(1)))$(echo-why)';)
# >'< substitution is for echo to work,
# >$< substitution to preserve $ when reloading .cmd file
# note: when using inline perl scripts [perl -e '...$$t=1;...']
# in $(cmd_xxx) double $$ your perl vars
make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1))))) make-cmd = $(subst \#,\\\#,$(subst $$,$$$$,$(call escsq,$(cmd_$(1)))))
# function to only execute the passed command if necessary # Find any prerequisites that is newer than target or that does not exist.
# >'< substitution is for echo to work, >$< substitution to preserve $ when reloading .cmd file # PHONY targets skipped in both cases.
# note: when using inline perl scripts [perl -e '...$$t=1;...'] in $(cmd_xxx) double $$ your perl vars any-prereq = $(filter-out $(PHONY),$?) $(filter-out $(PHONY) $(wildcard $^),$^)
# Execute command if command has changed or prerequisitei(s) are updated
# #
if_changed = $(if $(strip $(filter-out $(PHONY),$?) \ if_changed = $(if $(strip $(any-prereq) $(arg-check)), \
$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
@set -e; \ @set -e; \
$(echo-cmd) $(cmd_$(1)); \ $(echo-cmd) $(cmd_$(1)); \
echo 'cmd_$@ := $(make-cmd)' > $(@D)/.$(@F).cmd) echo 'cmd_$@ := $(make-cmd)' > $(dot-target).cmd)
# execute the command and also postprocess generated .d dependencies # execute the command and also postprocess generated .d dependencies
# file # file
if_changed_dep = $(if $(strip $(filter-out $(PHONY),$?) \ if_changed_dep = $(if $(strip $(any-prereq) $(arg-check) ), \
$(filter-out FORCE $(wildcard $^),$^) \
$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ), \
@set -e; \ @set -e; \
$(echo-cmd) $(cmd_$(1)); \ $(echo-cmd) $(cmd_$(1)); \
scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(@D)/.$(@F).tmp; \ scripts/basic/fixdep $(depfile) $@ '$(make-cmd)' > $(dot-target).tmp;\
rm -f $(depfile); \ rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd) mv -f $(dot-target).tmp $(dot-target).cmd)
# Usage: $(call if_changed_rule,foo) # Usage: $(call if_changed_rule,foo)
# will check if $(cmd_foo) changed, or any of the prequisites changed, # will check if $(cmd_foo) changed, or any of the prequisites changed,
# and if so will execute $(rule_foo) # and if so will execute $(rule_foo)
if_changed_rule = $(if $(strip $(filter-out $(PHONY),$?) \ if_changed_rule = $(if $(strip $(any-prereq) $(arg-check) ), \
$(call arg-check, $(cmd_$(1)), $(cmd_$@)) ),\
@set -e; \ @set -e; \
$(rule_$(1))) $(rule_$(1)))
###
# why - tell why a a target got build
# enabled by make V=2
# Output (listed in the order they are checked):
# (1) - due to target is PHONY
# (2) - due to target missing
# (3) - due to: file1.h file2.h
# (4) - due to command line change
# (5) - due to missing .cmd file
# (6) - due to target not in $(targets)
# (1) PHONY targets are always build
# (2) No target, so we better build it
# (3) Prerequisite is newer than target
# (4) The command line stored in the file named dir/.target.cmd
# differed from actual command line. This happens when compiler
# options changes
# (5) No dir/.target.cmd file (used to store command line)
# (6) No dir/.target.cmd file and target not listed in $(targets)
# This is a good hint that there is a bug in the kbuild file
ifeq ($(KBUILD_VERBOSE),2)
why = \
$(if $(filter $@, $(PHONY)),- due to target is PHONY, \
$(if $(wildcard $@), \
$(if $(strip $(any-prereq)),- due to: $(any-prereq), \
$(if $(arg-check), \
$(if $(cmd_$@),- due to command line change, \
$(if $(filter $@, $(targets)), \
- due to missing .cmd file, \
- due to $(notdir $@) not in $$(targets) \
) \
) \
) \
), \
- due to target missing \
) \
)
echo-why = $(call escsq, $(strip $(why)))
endif
...@@ -15,8 +15,11 @@ hostprogs-$(CONFIG_IKCONFIG) += bin2c ...@@ -15,8 +15,11 @@ hostprogs-$(CONFIG_IKCONFIG) += bin2c
always := $(hostprogs-y) always := $(hostprogs-y)
# The following hostprogs-y programs are only build on demand
hostprogs-y += unifdef
subdir-$(CONFIG_MODVERSIONS) += genksyms subdir-$(CONFIG_MODVERSIONS) += genksyms
subdir-$(CONFIG_MODULES) += mod subdir-y += mod
# Let clean descend into subdirs # Let clean descend into subdirs
subdir- += basic kconfig package subdir- += basic kconfig package
...@@ -191,9 +191,10 @@ define rule_cc_o_c ...@@ -191,9 +191,10 @@ define rule_cc_o_c
$(call echo-cmd,checksrc) $(cmd_checksrc) \ $(call echo-cmd,checksrc) $(cmd_checksrc) \
$(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \ $(call echo-cmd,cc_o_c) $(cmd_cc_o_c); \
$(cmd_modversions) \ $(cmd_modversions) \
scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > $(@D)/.$(@F).tmp; \ scripts/basic/fixdep $(depfile) $@ '$(call make-cmd,cc_o_c)' > \
$(dot-target).tmp; \
rm -f $(depfile); \ rm -f $(depfile); \
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd mv -f $(dot-target).tmp $(dot-target).cmd
endef endef
# Built-in and composite module parts # Built-in and composite module parts
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
# #
# ========================================================================== # ==========================================================================
UNIFDEF := unifdef -U__KERNEL__ UNIFDEF := scripts/unifdef -U__KERNEL__
# Eliminate the contents of (and inclusions of) compiler.h # Eliminate the contents of (and inclusions of) compiler.h
HDRSED := sed -e "s/ inline / __inline__ /g" \ HDRSED := sed -e "s/ inline / __inline__ /g" \
......
...@@ -32,11 +32,6 @@ ...@@ -32,11 +32,6 @@
__hostprogs := $(sort $(hostprogs-y) $(hostprogs-m)) __hostprogs := $(sort $(hostprogs-y) $(hostprogs-m))
# hostprogs-y := tools/build may have been specified. Retreive directory
host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
host-objdirs := $(strip $(sort $(filter-out ./,$(host-objdirs))))
# C code # C code
# Executables compiled from a single .c file # Executables compiled from a single .c file
host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m))) host-csingle := $(foreach m,$(__hostprogs),$(if $($(m)-objs),,$(m)))
...@@ -65,6 +60,21 @@ host-cobjs := $(filter-out %.so,$(host-cobjs)) ...@@ -65,6 +60,21 @@ host-cobjs := $(filter-out %.so,$(host-cobjs))
#Object (.o) files used by the shared libaries #Object (.o) files used by the shared libaries
host-cshobjs := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs)))) host-cshobjs := $(sort $(foreach m,$(host-cshlib),$($(m:.so=-objs))))
# output directory for programs/.o files
# hostprogs-y := tools/build may have been specified. Retreive directory
host-objdirs := $(foreach f,$(__hostprogs), $(if $(dir $(f)),$(dir $(f))))
# directory of .o files from prog-objs notation
host-objdirs += $(foreach f,$(host-cmulti), \
$(foreach m,$($(f)-objs), \
$(if $(dir $(m)),$(dir $(m)))))
# directory of .o files from prog-cxxobjs notation
host-objdirs += $(foreach f,$(host-cxxmulti), \
$(foreach m,$($(f)-cxxobjs), \
$(if $(dir $(m)),$(dir $(m)))))
host-objdirs := $(strip $(sort $(filter-out ./,$(host-objdirs))))
__hostprogs := $(addprefix $(obj)/,$(__hostprogs)) __hostprogs := $(addprefix $(obj)/,$(__hostprogs))
host-csingle := $(addprefix $(obj)/,$(host-csingle)) host-csingle := $(addprefix $(obj)/,$(host-csingle))
host-cmulti := $(addprefix $(obj)/,$(host-cmulti)) host-cmulti := $(addprefix $(obj)/,$(host-cmulti))
......
...@@ -51,19 +51,26 @@ _modpost: $(modules) ...@@ -51,19 +51,26 @@ _modpost: $(modules)
# Step 2), invoke modpost # Step 2), invoke modpost
# Includes step 3,4 # Includes step 3,4
quiet_cmd_modpost = MODPOST quiet_cmd_modpost = MODPOST $(words $(filter-out vmlinux FORCE, $^)) modules
cmd_modpost = scripts/mod/modpost \ cmd_modpost = scripts/mod/modpost \
$(if $(CONFIG_MODVERSIONS),-m) \ $(if $(CONFIG_MODVERSIONS),-m) \
$(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \ $(if $(CONFIG_MODULE_SRCVERSION_ALL),-a,) \
$(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \ $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
$(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \ $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
$(filter-out FORCE,$^) $(if $(KBUILD_EXTMOD),-w) \
$(wildcard vmlinux) $(filter-out FORCE,$^)
PHONY += __modpost PHONY += __modpost
__modpost: $(wildcard vmlinux) $(modules:.ko=.o) FORCE __modpost: $(modules:.ko=.o) FORCE
$(call cmd,modpost) $(call cmd,modpost)
quiet_cmd_kernel-mod = MODPOST $@
cmd_kernel-mod = $(cmd_modpost)
vmlinux: FORCE
$(call cmd,kernel-mod)
# Declare generated files as targets for modpost # Declare generated files as targets for modpost
$(symverfile): __modpost ; $(symverfile): __modpost ;
$(modules:.ko=.mod.c): __modpost ; $(modules:.ko=.mod.c): __modpost ;
......
...@@ -74,6 +74,7 @@ help: ...@@ -74,6 +74,7 @@ help:
@echo ' xconfig - Update current config utilising a QT based front-end' @echo ' xconfig - Update current config utilising a QT based front-end'
@echo ' gconfig - Update current config utilising a GTK based front-end' @echo ' gconfig - Update current config utilising a GTK based front-end'
@echo ' oldconfig - Update current config utilising a provided .config as base' @echo ' oldconfig - Update current config utilising a provided .config as base'
@echo ' silentoldconfig - Same as oldconfig, but quietly'
@echo ' randconfig - New config with random answer to all options' @echo ' randconfig - New config with random answer to all options'
@echo ' defconfig - New config with default answer to all options' @echo ' defconfig - New config with default answer to all options'
@echo ' allmodconfig - New config selecting modules when possible' @echo ' allmodconfig - New config selecting modules when possible'
......
...@@ -193,8 +193,11 @@ int conf_read_simple(const char *name, int def) ...@@ -193,8 +193,11 @@ int conf_read_simple(const char *name, int def)
continue; continue;
*p++ = 0; *p++ = 0;
p2 = strchr(p, '\n'); p2 = strchr(p, '\n');
if (p2) if (p2) {
*p2-- = 0;
if (*p2 == '\r')
*p2 = 0; *p2 = 0;
}
if (def == S_DEF_USER) { if (def == S_DEF_USER) {
sym = sym_find(line + 7); sym = sym_find(line + 7);
if (!sym) { if (!sym) {
...@@ -266,6 +269,7 @@ int conf_read_simple(const char *name, int def) ...@@ -266,6 +269,7 @@ int conf_read_simple(const char *name, int def)
; ;
} }
break; break;
case '\r':
case '\n': case '\n':
break; break;
default: default:
......
...@@ -23,6 +23,8 @@ int have_vmlinux = 0; ...@@ -23,6 +23,8 @@ int have_vmlinux = 0;
static int all_versions = 0; static int all_versions = 0;
/* If we are modposting external module set to 1 */ /* If we are modposting external module set to 1 */
static int external_module = 0; static int external_module = 0;
/* Only warn about unresolved symbols */
static int warn_unresolved = 0;
/* How a symbol is exported */ /* How a symbol is exported */
enum export { enum export {
export_plain, export_unused, export_gpl, export_plain, export_unused, export_gpl,
...@@ -581,8 +583,8 @@ static int strrcmp(const char *s, const char *sub) ...@@ -581,8 +583,8 @@ static int strrcmp(const char *s, const char *sub)
* fromsec = .data * fromsec = .data
* atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one * atsym = *driver, *_template, *_sht, *_ops, *_probe, *probe_one
**/ **/
static int secref_whitelist(const char *tosec, const char *fromsec, static int secref_whitelist(const char *modname, const char *tosec,
const char *atsym) const char *fromsec, const char *atsym)
{ {
int f1 = 1, f2 = 1; int f1 = 1, f2 = 1;
const char **s; const char **s;
...@@ -618,8 +620,16 @@ static int secref_whitelist(const char *tosec, const char *fromsec, ...@@ -618,8 +620,16 @@ static int secref_whitelist(const char *tosec, const char *fromsec,
for (s = pat2sym; *s; s++) for (s = pat2sym; *s; s++)
if (strrcmp(atsym, *s) == 0) if (strrcmp(atsym, *s) == 0)
f1 = 1; f1 = 1;
if (f1 && f2)
return 1;
return f1 && f2; /* Whitelist all references from .pci_fixup section if vmlinux */
if (is_vmlinux(modname)) {
if ((strcmp(fromsec, ".pci_fixup") == 0) &&
(strcmp(tosec, ".init.text") == 0))
return 1;
}
return 0;
} }
/** /**
...@@ -726,7 +736,8 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec, ...@@ -726,7 +736,8 @@ static void warn_sec_mismatch(const char *modname, const char *fromsec,
/* check whitelist - we may ignore it */ /* check whitelist - we may ignore it */
if (before && if (before &&
secref_whitelist(secname, fromsec, elf->strtab + before->st_name)) secref_whitelist(modname, secname, fromsec,
elf->strtab + before->st_name))
return; return;
if (before && after) { if (before && after) {
...@@ -1187,16 +1198,19 @@ static void add_header(struct buffer *b, struct module *mod) ...@@ -1187,16 +1198,19 @@ static void add_header(struct buffer *b, struct module *mod)
/** /**
* Record CRCs for unresolved symbols * Record CRCs for unresolved symbols
**/ **/
static void add_versions(struct buffer *b, struct module *mod) static int add_versions(struct buffer *b, struct module *mod)
{ {
struct symbol *s, *exp; struct symbol *s, *exp;
int err = 0;
for (s = mod->unres; s; s = s->next) { for (s = mod->unres; s; s = s->next) {
exp = find_symbol(s->name); exp = find_symbol(s->name);
if (!exp || exp->module == mod) { if (!exp || exp->module == mod) {
if (have_vmlinux && !s->weak) if (have_vmlinux && !s->weak) {
warn("\"%s\" [%s.ko] undefined!\n", warn("\"%s\" [%s.ko] undefined!\n",
s->name, mod->name); s->name, mod->name);
err = warn_unresolved ? 0 : 1;
}
continue; continue;
} }
s->module = exp->module; s->module = exp->module;
...@@ -1205,7 +1219,7 @@ static void add_versions(struct buffer *b, struct module *mod) ...@@ -1205,7 +1219,7 @@ static void add_versions(struct buffer *b, struct module *mod)
} }
if (!modversions) if (!modversions)
return; return err;
buf_printf(b, "\n"); buf_printf(b, "\n");
buf_printf(b, "static const struct modversion_info ____versions[]\n"); buf_printf(b, "static const struct modversion_info ____versions[]\n");
...@@ -1225,6 +1239,8 @@ static void add_versions(struct buffer *b, struct module *mod) ...@@ -1225,6 +1239,8 @@ static void add_versions(struct buffer *b, struct module *mod)
} }
buf_printf(b, "};\n"); buf_printf(b, "};\n");
return err;
} }
static void add_depends(struct buffer *b, struct module *mod, static void add_depends(struct buffer *b, struct module *mod,
...@@ -1402,8 +1418,9 @@ int main(int argc, char **argv) ...@@ -1402,8 +1418,9 @@ int main(int argc, char **argv)
char *kernel_read = NULL, *module_read = NULL; char *kernel_read = NULL, *module_read = NULL;
char *dump_write = NULL; char *dump_write = NULL;
int opt; int opt;
int err;
while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) { while ((opt = getopt(argc, argv, "i:I:mo:aw")) != -1) {
switch(opt) { switch(opt) {
case 'i': case 'i':
kernel_read = optarg; kernel_read = optarg;
...@@ -1421,6 +1438,9 @@ int main(int argc, char **argv) ...@@ -1421,6 +1438,9 @@ int main(int argc, char **argv)
case 'a': case 'a':
all_versions = 1; all_versions = 1;
break; break;
case 'w':
warn_unresolved = 1;
break;
default: default:
exit(1); exit(1);
} }
...@@ -1441,6 +1461,8 @@ int main(int argc, char **argv) ...@@ -1441,6 +1461,8 @@ int main(int argc, char **argv)
check_exports(mod); check_exports(mod);
} }
err = 0;
for (mod = modules; mod; mod = mod->next) { for (mod = modules; mod; mod = mod->next) {
if (mod->skip) if (mod->skip)
continue; continue;
...@@ -1448,7 +1470,7 @@ int main(int argc, char **argv) ...@@ -1448,7 +1470,7 @@ int main(int argc, char **argv)
buf.pos = 0; buf.pos = 0;
add_header(&buf, mod); add_header(&buf, mod);
add_versions(&buf, mod); err |= add_versions(&buf, mod);
add_depends(&buf, mod, modules); add_depends(&buf, mod, modules);
add_moddevtable(&buf, mod); add_moddevtable(&buf, mod);
add_srcversion(&buf, mod); add_srcversion(&buf, mod);
...@@ -1460,5 +1482,5 @@ int main(int argc, char **argv) ...@@ -1460,5 +1482,5 @@ int main(int argc, char **argv)
if (dump_write) if (dump_write)
write_dump(dump_write); write_dump(dump_write);
return 0; return err;
} }
...@@ -63,9 +63,9 @@ fi ...@@ -63,9 +63,9 @@ fi
echo "%install" echo "%install"
echo "%ifarch ia64" echo "%ifarch ia64"
echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules' echo 'mkdir -p $RPM_BUILD_ROOT/boot/efi $RPM_BUILD_ROOT/lib/modules'
echo "%else" echo "%else"
echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules' echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib/modules'
echo "%endif" echo "%endif"
echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install' echo 'INSTALL_MOD_PATH=$RPM_BUILD_ROOT make %{_smp_mflags} modules_install'
......
/*
* Copyright (c) 2002 - 2005 Tony Finch <dot@dotat.at>. All rights reserved.
*
* This code is derived from software contributed to Berkeley by Dave Yost.
* It was rewritten to support ANSI C by Tony Finch. The original version of
* unifdef carried the following copyright notice. None of its code remains
* in this version (though some of the names remain).
*
* Copyright (c) 1985, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/cdefs.h>
#ifndef lint
#if 0
static const char copyright[] =
"@(#) Copyright (c) 1985, 1993\n\
The Regents of the University of California. All rights reserved.\n";
#endif
#ifdef __IDSTRING
__IDSTRING(Berkeley, "@(#)unifdef.c 8.1 (Berkeley) 6/6/93");
__IDSTRING(NetBSD, "$NetBSD: unifdef.c,v 1.8 2000/07/03 02:51:36 matt Exp $");
__IDSTRING(dotat, "$dotat: things/unifdef.c,v 1.171 2005/03/08 12:38:48 fanf2 Exp $");
#endif
#endif /* not lint */
#ifdef __FBSDID
__FBSDID("$FreeBSD: /repoman/r/ncvs/src/usr.bin/unifdef/unifdef.c,v 1.20 2005/05/21 09:55:09 ru Exp $");
#endif
/*
* unifdef - remove ifdef'ed lines
*
* Wishlist:
* provide an option which will append the name of the
* appropriate symbol after #else's and #endif's
* provide an option which will check symbols after
* #else's and #endif's to see that they match their
* corresponding #ifdef or #ifndef
*
* The first two items above require better buffer handling, which would
* also make it possible to handle all "dodgy" directives correctly.
*/
#include <ctype.h>
#include <err.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
size_t strlcpy(char *dst, const char *src, size_t siz);
/* types of input lines: */
typedef enum {
LT_TRUEI, /* a true #if with ignore flag */
LT_FALSEI, /* a false #if with ignore flag */
LT_IF, /* an unknown #if */
LT_TRUE, /* a true #if */
LT_FALSE, /* a false #if */
LT_ELIF, /* an unknown #elif */
LT_ELTRUE, /* a true #elif */
LT_ELFALSE, /* a false #elif */
LT_ELSE, /* #else */
LT_ENDIF, /* #endif */
LT_DODGY, /* flag: directive is not on one line */
LT_DODGY_LAST = LT_DODGY + LT_ENDIF,
LT_PLAIN, /* ordinary line */
LT_EOF, /* end of file */
LT_COUNT
} Linetype;
static char const * const linetype_name[] = {
"TRUEI", "FALSEI", "IF", "TRUE", "FALSE",
"ELIF", "ELTRUE", "ELFALSE", "ELSE", "ENDIF",
"DODGY TRUEI", "DODGY FALSEI",
"DODGY IF", "DODGY TRUE", "DODGY FALSE",
"DODGY ELIF", "DODGY ELTRUE", "DODGY ELFALSE",
"DODGY ELSE", "DODGY ENDIF",
"PLAIN", "EOF"
};
/* state of #if processing */
typedef enum {
IS_OUTSIDE,
IS_FALSE_PREFIX, /* false #if followed by false #elifs */
IS_TRUE_PREFIX, /* first non-false #(el)if is true */
IS_PASS_MIDDLE, /* first non-false #(el)if is unknown */
IS_FALSE_MIDDLE, /* a false #elif after a pass state */
IS_TRUE_MIDDLE, /* a true #elif after a pass state */
IS_PASS_ELSE, /* an else after a pass state */
IS_FALSE_ELSE, /* an else after a true state */
IS_TRUE_ELSE, /* an else after only false states */
IS_FALSE_TRAILER, /* #elifs after a true are false */
IS_COUNT
} Ifstate;
static char const * const ifstate_name[] = {
"OUTSIDE", "FALSE_PREFIX", "TRUE_PREFIX",
"PASS_MIDDLE", "FALSE_MIDDLE", "TRUE_MIDDLE",
"PASS_ELSE", "FALSE_ELSE", "TRUE_ELSE",
"FALSE_TRAILER"
};
/* state of comment parser */
typedef enum {
NO_COMMENT = false, /* outside a comment */
C_COMMENT, /* in a comment like this one */
CXX_COMMENT, /* between // and end of line */
STARTING_COMMENT, /* just after slash-backslash-newline */
FINISHING_COMMENT, /* star-backslash-newline in a C comment */
CHAR_LITERAL, /* inside '' */
STRING_LITERAL /* inside "" */
} Comment_state;
static char const * const comment_name[] = {
"NO", "C", "CXX", "STARTING", "FINISHING", "CHAR", "STRING"
};
/* state of preprocessor line parser */
typedef enum {
LS_START, /* only space and comments on this line */
LS_HASH, /* only space, comments, and a hash */
LS_DIRTY /* this line can't be a preprocessor line */
} Line_state;
static char const * const linestate_name[] = {
"START", "HASH", "DIRTY"
};
/*
* Minimum translation limits from ISO/IEC 9899:1999 5.2.4.1
*/
#define MAXDEPTH 64 /* maximum #if nesting */
#define MAXLINE 4096 /* maximum length of line */
#define MAXSYMS 4096 /* maximum number of symbols */
/*
* Sometimes when editing a keyword the replacement text is longer, so
* we leave some space at the end of the tline buffer to accommodate this.
*/
#define EDITSLOP 10
/*
* Globals.
*/
static bool complement; /* -c: do the complement */
static bool debugging; /* -d: debugging reports */
static bool iocccok; /* -e: fewer IOCCC errors */
static bool killconsts; /* -k: eval constant #ifs */
static bool lnblank; /* -l: blank deleted lines */
static bool lnnum; /* -n: add #line directives */
static bool symlist; /* -s: output symbol list */
static bool text; /* -t: this is a text file */
static const char *symname[MAXSYMS]; /* symbol name */
static const char *value[MAXSYMS]; /* -Dsym=value */
static bool ignore[MAXSYMS]; /* -iDsym or -iUsym */
static int nsyms; /* number of symbols */
static FILE *input; /* input file pointer */
static const char *filename; /* input file name */
static int linenum; /* current line number */
static char tline[MAXLINE+EDITSLOP];/* input buffer plus space */
static char *keyword; /* used for editing #elif's */
static Comment_state incomment; /* comment parser state */
static Line_state linestate; /* #if line parser state */
static Ifstate ifstate[MAXDEPTH]; /* #if processor state */
static bool ignoring[MAXDEPTH]; /* ignore comments state */
static int stifline[MAXDEPTH]; /* start of current #if */
static int depth; /* current #if nesting */
static int delcount; /* count of deleted lines */
static bool keepthis; /* don't delete constant #if */
static int exitstat; /* program exit status */
static void addsym(bool, bool, char *);
static void debug(const char *, ...);
static void done(void);
static void error(const char *);
static int findsym(const char *);
static void flushline(bool);
static Linetype getline(void);
static Linetype ifeval(const char **);
static void ignoreoff(void);
static void ignoreon(void);
static void keywordedit(const char *);
static void nest(void);
static void process(void);
static const char *skipcomment(const char *);
static const char *skipsym(const char *);
static void state(Ifstate);
static int strlcmp(const char *, const char *, size_t);
static void unnest(void);
static void usage(void);
#define endsym(c) (!isalpha((unsigned char)c) && !isdigit((unsigned char)c) && c != '_')
/*
* The main program.
*/
int
main(int argc, char *argv[])
{
int opt;
while ((opt = getopt(argc, argv, "i:D:U:I:cdeklnst")) != -1)
switch (opt) {
case 'i': /* treat stuff controlled by these symbols as text */
/*
* For strict backwards-compatibility the U or D
* should be immediately after the -i but it doesn't
* matter much if we relax that requirement.
*/
opt = *optarg++;
if (opt == 'D')
addsym(true, true, optarg);
else if (opt == 'U')
addsym(true, false, optarg);
else
usage();
break;
case 'D': /* define a symbol */
addsym(false, true, optarg);
break;
case 'U': /* undef a symbol */
addsym(false, false, optarg);
break;
case 'I':
/* no-op for compatibility with cpp */
break;
case 'c': /* treat -D as -U and vice versa */
complement = true;
break;
case 'd':
debugging = true;
break;
case 'e': /* fewer errors from dodgy lines */
iocccok = true;
break;
case 'k': /* process constant #ifs */
killconsts = true;
break;
case 'l': /* blank deleted lines instead of omitting them */
lnblank = true;
break;
case 'n': /* add #line directive after deleted lines */
lnnum = true;
break;
case 's': /* only output list of symbols that control #ifs */
symlist = true;
break;
case 't': /* don't parse C comments */
text = true;
break;
default:
usage();
}
argc -= optind;
argv += optind;
if (argc > 1) {
errx(2, "can only do one file");
} else if (argc == 1 && strcmp(*argv, "-") != 0) {
filename = *argv;
input = fopen(filename, "r");
if (input == NULL)
err(2, "can't open %s", filename);
} else {
filename = "[stdin]";
input = stdin;
}
process();
abort(); /* bug */
}
static void
usage(void)
{
fprintf(stderr, "usage: unifdef [-cdeklnst] [-Ipath]"
" [-Dsym[=val]] [-Usym] [-iDsym[=val]] [-iUsym] ... [file]\n");
exit(2);
}
/*
* A state transition function alters the global #if processing state
* in a particular way. The table below is indexed by the current
* processing state and the type of the current line.
*
* Nesting is handled by keeping a stack of states; some transition
* functions increase or decrease the depth. They also maintain the
* ignore state on a stack. In some complicated cases they have to
* alter the preprocessor directive, as follows.
*
* When we have processed a group that starts off with a known-false
* #if/#elif sequence (which has therefore been deleted) followed by a
* #elif that we don't understand and therefore must keep, we edit the
* latter into a #if to keep the nesting correct.
*
* When we find a true #elif in a group, the following block will
* always be kept and the rest of the sequence after the next #elif or
* #else will be discarded. We edit the #elif into a #else and the
* following directive to #endif since this has the desired behaviour.
*
* "Dodgy" directives are split across multiple lines, the most common
* example being a multi-line comment hanging off the right of the
* directive. We can handle them correctly only if there is no change
* from printing to dropping (or vice versa) caused by that directive.
* If the directive is the first of a group we have a choice between
* failing with an error, or passing it through unchanged instead of
* evaluating it. The latter is not the default to avoid questions from
* users about unifdef unexpectedly leaving behind preprocessor directives.
*/
typedef void state_fn(void);
/* report an error */
static void Eelif (void) { error("Inappropriate #elif"); }
static void Eelse (void) { error("Inappropriate #else"); }
static void Eendif(void) { error("Inappropriate #endif"); }
static void Eeof (void) { error("Premature EOF"); }
static void Eioccc(void) { error("Obfuscated preprocessor control line"); }
/* plain line handling */
static void print (void) { flushline(true); }
static void drop (void) { flushline(false); }
/* output lacks group's start line */
static void Strue (void) { drop(); ignoreoff(); state(IS_TRUE_PREFIX); }
static void Sfalse(void) { drop(); ignoreoff(); state(IS_FALSE_PREFIX); }
static void Selse (void) { drop(); state(IS_TRUE_ELSE); }
/* print/pass this block */
static void Pelif (void) { print(); ignoreoff(); state(IS_PASS_MIDDLE); }
static void Pelse (void) { print(); state(IS_PASS_ELSE); }
static void Pendif(void) { print(); unnest(); }
/* discard this block */
static void Dfalse(void) { drop(); ignoreoff(); state(IS_FALSE_TRAILER); }
static void Delif (void) { drop(); ignoreoff(); state(IS_FALSE_MIDDLE); }
static void Delse (void) { drop(); state(IS_FALSE_ELSE); }
static void Dendif(void) { drop(); unnest(); }
/* first line of group */
static void Fdrop (void) { nest(); Dfalse(); }
static void Fpass (void) { nest(); Pelif(); }
static void Ftrue (void) { nest(); Strue(); }
static void Ffalse(void) { nest(); Sfalse(); }
/* variable pedantry for obfuscated lines */
static void Oiffy (void) { if (!iocccok) Eioccc(); Fpass(); ignoreon(); }
static void Oif (void) { if (!iocccok) Eioccc(); Fpass(); }
static void Oelif (void) { if (!iocccok) Eioccc(); Pelif(); }
/* ignore comments in this block */
static void Idrop (void) { Fdrop(); ignoreon(); }
static void Itrue (void) { Ftrue(); ignoreon(); }
static void Ifalse(void) { Ffalse(); ignoreon(); }
/* edit this line */
static void Mpass (void) { strncpy(keyword, "if ", 4); Pelif(); }
static void Mtrue (void) { keywordedit("else\n"); state(IS_TRUE_MIDDLE); }
static void Melif (void) { keywordedit("endif\n"); state(IS_FALSE_TRAILER); }
static void Melse (void) { keywordedit("endif\n"); state(IS_FALSE_ELSE); }
static state_fn * const trans_table[IS_COUNT][LT_COUNT] = {
/* IS_OUTSIDE */
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Eendif,
Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eendif,
print, done },
/* IS_FALSE_PREFIX */
{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Strue, Sfalse,Selse, Dendif,
Idrop, Idrop, Fdrop, Fdrop, Fdrop, Mpass, Eioccc,Eioccc,Eioccc,Eioccc,
drop, Eeof },
/* IS_TRUE_PREFIX */
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Dfalse,Dfalse,Dfalse,Delse, Dendif,
Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
print, Eeof },
/* IS_PASS_MIDDLE */
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Pelif, Mtrue, Delif, Pelse, Pendif,
Oiffy, Oiffy, Fpass, Oif, Oif, Pelif, Oelif, Oelif, Pelse, Pendif,
print, Eeof },
/* IS_FALSE_MIDDLE */
{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Pelif, Mtrue, Delif, Pelse, Pendif,
Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eioccc,Eioccc,Eioccc,Eioccc,Eioccc,
drop, Eeof },
/* IS_TRUE_MIDDLE */
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Melif, Melif, Melif, Melse, Pendif,
Oiffy, Oiffy, Fpass, Oif, Oif, Eioccc,Eioccc,Eioccc,Eioccc,Pendif,
print, Eeof },
/* IS_PASS_ELSE */
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Pendif,
Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Pendif,
print, Eeof },
/* IS_FALSE_ELSE */
{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Dendif,
Idrop, Idrop, Fdrop, Fdrop, Fdrop, Eelif, Eelif, Eelif, Eelse, Eioccc,
drop, Eeof },
/* IS_TRUE_ELSE */
{ Itrue, Ifalse,Fpass, Ftrue, Ffalse,Eelif, Eelif, Eelif, Eelse, Dendif,
Oiffy, Oiffy, Fpass, Oif, Oif, Eelif, Eelif, Eelif, Eelse, Eioccc,
print, Eeof },
/* IS_FALSE_TRAILER */
{ Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Dendif,
Idrop, Idrop, Fdrop, Fdrop, Fdrop, Dfalse,Dfalse,Dfalse,Delse, Eioccc,
drop, Eeof }
/*TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF
TRUEI FALSEI IF TRUE FALSE ELIF ELTRUE ELFALSE ELSE ENDIF (DODGY)
PLAIN EOF */
};
/*
* State machine utility functions
*/
static void
done(void)
{
if (incomment)
error("EOF in comment");
exit(exitstat);
}
static void
ignoreoff(void)
{
if (depth == 0)
abort(); /* bug */
ignoring[depth] = ignoring[depth-1];
}
static void
ignoreon(void)
{
ignoring[depth] = true;
}
static void
keywordedit(const char *replacement)
{
size_t size = tline + sizeof(tline) - keyword;
char *dst = keyword;
const char *src = replacement;
if (size != 0) {
while ((--size != 0) && (*src != '\0'))
*dst++ = *src++;
*dst = '\0';
}
print();
}
static void
nest(void)
{
depth += 1;
if (depth >= MAXDEPTH)
error("Too many levels of nesting");
stifline[depth] = linenum;
}
static void
unnest(void)
{
if (depth == 0)
abort(); /* bug */
depth -= 1;
}
static void
state(Ifstate is)
{
ifstate[depth] = is;
}
/*
* Write a line to the output or not, according to command line options.
*/
static void
flushline(bool keep)
{
if (symlist)
return;
if (keep ^ complement) {
if (lnnum && delcount > 0)
printf("#line %d\n", linenum);
fputs(tline, stdout);
delcount = 0;
} else {
if (lnblank)
putc('\n', stdout);
exitstat = 1;
delcount += 1;
}
}
/*
* The driver for the state machine.
*/
static void
process(void)
{
Linetype lineval;
for (;;) {
linenum++;
lineval = getline();
trans_table[ifstate[depth]][lineval]();
debug("process %s -> %s depth %d",
linetype_name[lineval],
ifstate_name[ifstate[depth]], depth);
}
}
/*
* Parse a line and determine its type. We keep the preprocessor line
* parser state between calls in the global variable linestate, with
* help from skipcomment().
*/
static Linetype
getline(void)
{
const char *cp;
int cursym;
int kwlen;
Linetype retval;
Comment_state wascomment;
if (fgets(tline, MAXLINE, input) == NULL)
return (LT_EOF);
retval = LT_PLAIN;
wascomment = incomment;
cp = skipcomment(tline);
if (linestate == LS_START) {
if (*cp == '#') {
linestate = LS_HASH;
cp = skipcomment(cp + 1);
} else if (*cp != '\0')
linestate = LS_DIRTY;
}
if (!incomment && linestate == LS_HASH) {
keyword = tline + (cp - tline);
cp = skipsym(cp);
kwlen = cp - keyword;
/* no way can we deal with a continuation inside a keyword */
if (strncmp(cp, "\\\n", 2) == 0)
Eioccc();
if (strlcmp("ifdef", keyword, kwlen) == 0 ||
strlcmp("ifndef", keyword, kwlen) == 0) {
cp = skipcomment(cp);
if ((cursym = findsym(cp)) < 0)
retval = LT_IF;
else {
retval = (keyword[2] == 'n')
? LT_FALSE : LT_TRUE;
if (value[cursym] == NULL)
retval = (retval == LT_TRUE)
? LT_FALSE : LT_TRUE;
if (ignore[cursym])
retval = (retval == LT_TRUE)
? LT_TRUEI : LT_FALSEI;
}
cp = skipsym(cp);
} else if (strlcmp("if", keyword, kwlen) == 0)
retval = ifeval(&cp);
else if (strlcmp("elif", keyword, kwlen) == 0)
retval = ifeval(&cp) - LT_IF + LT_ELIF;
else if (strlcmp("else", keyword, kwlen) == 0)
retval = LT_ELSE;
else if (strlcmp("endif", keyword, kwlen) == 0)
retval = LT_ENDIF;
else {
linestate = LS_DIRTY;
retval = LT_PLAIN;
}
cp = skipcomment(cp);
if (*cp != '\0') {
linestate = LS_DIRTY;
if (retval == LT_TRUE || retval == LT_FALSE ||
retval == LT_TRUEI || retval == LT_FALSEI)
retval = LT_IF;
if (retval == LT_ELTRUE || retval == LT_ELFALSE)
retval = LT_ELIF;
}
if (retval != LT_PLAIN && (wascomment || incomment)) {
retval += LT_DODGY;
if (incomment)
linestate = LS_DIRTY;
}
/* skipcomment should have changed the state */
if (linestate == LS_HASH)
abort(); /* bug */
}
if (linestate == LS_DIRTY) {
while (*cp != '\0')
cp = skipcomment(cp + 1);
}
debug("parser %s comment %s line",
comment_name[incomment], linestate_name[linestate]);
return (retval);
}
/*
* These are the binary operators that are supported by the expression
* evaluator. Note that if support for division is added then we also
* need short-circuiting booleans because of divide-by-zero.
*/
static int op_lt(int a, int b) { return (a < b); }
static int op_gt(int a, int b) { return (a > b); }
static int op_le(int a, int b) { return (a <= b); }
static int op_ge(int a, int b) { return (a >= b); }
static int op_eq(int a, int b) { return (a == b); }
static int op_ne(int a, int b) { return (a != b); }
static int op_or(int a, int b) { return (a || b); }
static int op_and(int a, int b) { return (a && b); }
/*
* An evaluation function takes three arguments, as follows: (1) a pointer to
* an element of the precedence table which lists the operators at the current
* level of precedence; (2) a pointer to an integer which will receive the
* value of the expression; and (3) a pointer to a char* that points to the
* expression to be evaluated and that is updated to the end of the expression
* when evaluation is complete. The function returns LT_FALSE if the value of
* the expression is zero, LT_TRUE if it is non-zero, or LT_IF if the
* expression could not be evaluated.
*/
struct ops;
typedef Linetype eval_fn(const struct ops *, int *, const char **);
static eval_fn eval_table, eval_unary;
/*
* The precedence table. Expressions involving binary operators are evaluated
* in a table-driven way by eval_table. When it evaluates a subexpression it
* calls the inner function with its first argument pointing to the next
* element of the table. Innermost expressions have special non-table-driven
* handling.
*/
static const struct ops {
eval_fn *inner;
struct op {
const char *str;
int (*fn)(int, int);
} op[5];
} eval_ops[] = {
{ eval_table, { { "||", op_or } } },
{ eval_table, { { "&&", op_and } } },
{ eval_table, { { "==", op_eq },
{ "!=", op_ne } } },
{ eval_unary, { { "<=", op_le },
{ ">=", op_ge },
{ "<", op_lt },
{ ">", op_gt } } }
};
/*
* Function for evaluating the innermost parts of expressions,
* viz. !expr (expr) defined(symbol) symbol number
* We reset the keepthis flag when we find a non-constant subexpression.
*/
static Linetype
eval_unary(const struct ops *ops, int *valp, const char **cpp)
{
const char *cp;
char *ep;
int sym;
cp = skipcomment(*cpp);
if (*cp == '!') {
debug("eval%d !", ops - eval_ops);
cp++;
if (eval_unary(ops, valp, &cp) == LT_IF)
return (LT_IF);
*valp = !*valp;
} else if (*cp == '(') {
cp++;
debug("eval%d (", ops - eval_ops);
if (eval_table(eval_ops, valp, &cp) == LT_IF)
return (LT_IF);
cp = skipcomment(cp);
if (*cp++ != ')')
return (LT_IF);
} else if (isdigit((unsigned char)*cp)) {
debug("eval%d number", ops - eval_ops);
*valp = strtol(cp, &ep, 0);
cp = skipsym(cp);
} else if (strncmp(cp, "defined", 7) == 0 && endsym(cp[7])) {
cp = skipcomment(cp+7);
debug("eval%d defined", ops - eval_ops);
if (*cp++ != '(')
return (LT_IF);
cp = skipcomment(cp);
sym = findsym(cp);
if (sym < 0)
return (LT_IF);
*valp = (value[sym] != NULL);
cp = skipsym(cp);
cp = skipcomment(cp);
if (*cp++ != ')')
return (LT_IF);
keepthis = false;
} else if (!endsym(*cp)) {
debug("eval%d symbol", ops - eval_ops);
sym = findsym(cp);
if (sym < 0)
return (LT_IF);
if (value[sym] == NULL)
*valp = 0;
else {
*valp = strtol(value[sym], &ep, 0);
if (*ep != '\0' || ep == value[sym])
return (LT_IF);
}
cp = skipsym(cp);
keepthis = false;
} else {
debug("eval%d bad expr", ops - eval_ops);
return (LT_IF);
}
*cpp = cp;
debug("eval%d = %d", ops - eval_ops, *valp);
return (*valp ? LT_TRUE : LT_FALSE);
}
/*
* Table-driven evaluation of binary operators.
*/
static Linetype
eval_table(const struct ops *ops, int *valp, const char **cpp)
{
const struct op *op;
const char *cp;
int val;
debug("eval%d", ops - eval_ops);
cp = *cpp;
if (ops->inner(ops+1, valp, &cp) == LT_IF)
return (LT_IF);
for (;;) {
cp = skipcomment(cp);
for (op = ops->op; op->str != NULL; op++)
if (strncmp(cp, op->str, strlen(op->str)) == 0)
break;
if (op->str == NULL)
break;
cp += strlen(op->str);
debug("eval%d %s", ops - eval_ops, op->str);
if (ops->inner(ops+1, &val, &cp) == LT_IF)
return (LT_IF);
*valp = op->fn(*valp, val);
}
*cpp = cp;
debug("eval%d = %d", ops - eval_ops, *valp);
return (*valp ? LT_TRUE : LT_FALSE);
}
/*
* Evaluate the expression on a #if or #elif line. If we can work out
* the result we return LT_TRUE or LT_FALSE accordingly, otherwise we
* return just a generic LT_IF.
*/
static Linetype
ifeval(const char **cpp)
{
int ret;
int val;
debug("eval %s", *cpp);
keepthis = killconsts ? false : true;
ret = eval_table(eval_ops, &val, cpp);
debug("eval = %d", val);
return (keepthis ? LT_IF : ret);
}
/*
* Skip over comments, strings, and character literals and stop at the
* next character position that is not whitespace. Between calls we keep
* the comment state in the global variable incomment, and we also adjust
* the global variable linestate when we see a newline.
* XXX: doesn't cope with the buffer splitting inside a state transition.
*/
static const char *
skipcomment(const char *cp)
{
if (text || ignoring[depth]) {
for (; isspace((unsigned char)*cp); cp++)
if (*cp == '\n')
linestate = LS_START;
return (cp);
}
while (*cp != '\0')
/* don't reset to LS_START after a line continuation */
if (strncmp(cp, "\\\n", 2) == 0)
cp += 2;
else switch (incomment) {
case NO_COMMENT:
if (strncmp(cp, "/\\\n", 3) == 0) {
incomment = STARTING_COMMENT;
cp += 3;
} else if (strncmp(cp, "/*", 2) == 0) {
incomment = C_COMMENT;
cp += 2;
} else if (strncmp(cp, "//", 2) == 0) {
incomment = CXX_COMMENT;
cp += 2;
} else if (strncmp(cp, "\'", 1) == 0) {
incomment = CHAR_LITERAL;
linestate = LS_DIRTY;
cp += 1;
} else if (strncmp(cp, "\"", 1) == 0) {
incomment = STRING_LITERAL;
linestate = LS_DIRTY;
cp += 1;
} else if (strncmp(cp, "\n", 1) == 0) {
linestate = LS_START;
cp += 1;
} else if (strchr(" \t", *cp) != NULL) {
cp += 1;
} else
return (cp);
continue;
case CXX_COMMENT:
if (strncmp(cp, "\n", 1) == 0) {
incomment = NO_COMMENT;
linestate = LS_START;
}
cp += 1;
continue;
case CHAR_LITERAL:
case STRING_LITERAL:
if ((incomment == CHAR_LITERAL && cp[0] == '\'') ||
(incomment == STRING_LITERAL && cp[0] == '\"')) {
incomment = NO_COMMENT;
cp += 1;
} else if (cp[0] == '\\') {
if (cp[1] == '\0')
cp += 1;
else
cp += 2;
} else if (strncmp(cp, "\n", 1) == 0) {
if (incomment == CHAR_LITERAL)
error("unterminated char literal");
else
error("unterminated string literal");
} else
cp += 1;
continue;
case C_COMMENT:
if (strncmp(cp, "*\\\n", 3) == 0) {
incomment = FINISHING_COMMENT;
cp += 3;
} else if (strncmp(cp, "*/", 2) == 0) {
incomment = NO_COMMENT;
cp += 2;
} else
cp += 1;
continue;
case STARTING_COMMENT:
if (*cp == '*') {
incomment = C_COMMENT;
cp += 1;
} else if (*cp == '/') {
incomment = CXX_COMMENT;
cp += 1;
} else {
incomment = NO_COMMENT;
linestate = LS_DIRTY;
}
continue;
case FINISHING_COMMENT:
if (*cp == '/') {
incomment = NO_COMMENT;
cp += 1;
} else
incomment = C_COMMENT;
continue;
default:
abort(); /* bug */
}
return (cp);
}
/*
* Skip over an identifier.
*/
static const char *
skipsym(const char *cp)
{
while (!endsym(*cp))
++cp;
return (cp);
}
/*
* Look for the symbol in the symbol table. If is is found, we return
* the symbol table index, else we return -1.
*/
static int
findsym(const char *str)
{
const char *cp;
int symind;
cp = skipsym(str);
if (cp == str)
return (-1);
if (symlist) {
printf("%.*s\n", (int)(cp-str), str);
/* we don't care about the value of the symbol */
return (0);
}
for (symind = 0; symind < nsyms; ++symind) {
if (strlcmp(symname[symind], str, cp-str) == 0) {
debug("findsym %s %s", symname[symind],
value[symind] ? value[symind] : "");
return (symind);
}
}
return (-1);
}
/*
* Add a symbol to the symbol table.
*/
static void
addsym(bool ignorethis, bool definethis, char *sym)
{
int symind;
char *val;
symind = findsym(sym);
if (symind < 0) {
if (nsyms >= MAXSYMS)
errx(2, "too many symbols");
symind = nsyms++;
}
symname[symind] = sym;
ignore[symind] = ignorethis;
val = sym + (skipsym(sym) - sym);
if (definethis) {
if (*val == '=') {
value[symind] = val+1;
*val = '\0';
} else if (*val == '\0')
value[symind] = "";
else
usage();
} else {
if (*val != '\0')
usage();
value[symind] = NULL;
}
}
/*
* Compare s with n characters of t.
* The same as strncmp() except that it checks that s[n] == '\0'.
*/
static int
strlcmp(const char *s, const char *t, size_t n)
{
while (n-- && *t != '\0')
if (*s != *t)
return ((unsigned char)*s - (unsigned char)*t);
else
++s, ++t;
return ((unsigned char)*s);
}
/*
* Diagnostics.
*/
static void
debug(const char *msg, ...)
{
va_list ap;
if (debugging) {
va_start(ap, msg);
vwarnx(msg, ap);
va_end(ap);
}
}
static void
error(const char *msg)
{
if (depth == 0)
warnx("%s: %d: %s", filename, linenum, msg);
else
warnx("%s: %d: %s (#if line %d depth %d)",
filename, linenum, msg, stifline[depth], depth);
errx(2, "output may be truncated");
}
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
# #
klibcdirs:; klibcdirs:;
PHONY += klibcdirs
# Generate builtin.o based on initramfs_data.o # Generate builtin.o based on initramfs_data.o
obj-y := initramfs_data.o obj-y := initramfs_data.o
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment