Understanding Makefile += operator - makefile

I have a line in my kernel make file:
obj-y += sample.o adc.o trigger.o send.o
I don't understand the above line. Is it same as the following?
obj-y +=sample.o
obj-y +=adc.o
obj-y +=trigger.o
obj-y +=send.o

According to the GNU make manual, += is used to append strings to variables. So yes.

Related

Simple way to pass variables to CFLAGS in a make file

I have a Makefile which looks like below. I use ifeq to add variables to compiler flags.
ABC=1
XYZ=1
ifeq ($(ABC),1)
CFLAGS+= -DABC
endif
ifeq ($(XYZ),1)
CFLAGS+= -DXYZ
endif
...
Is there a cleaner way to add all variables to CFLAGS instead of using ifeq for all?
Is there a cleaner way to add all variables to CFLAGS instead of using ifeq for all?
You can use computed variable names to avoid those verbose ifeq blocks:
ABC=1
XYZ=1
cflags.abc.1 := -DABC
cflags.xyz.1 := -DXYZ
CFLAGS += cflags.abc.${ABC} cflags.xyz.${XYZ}
It uses the fact that unset variables expand to empty strings in GNU make.

ccflag option in Makefile

I want to compile my c code (in kernel) which needs to include some header files from another directory.
Instead of specifying the complete path to header files in c file, I would like to specify the include path in Makefile.
My c file gets complied when the config option CONFIG_FEATURE_X is enabled.
I have written the following in Makefile:
obj-$(CONFIG_FEATURE_X) += my_file.o
ccflags-$(CONFIG_FEATURE_X) += -I$(obj)/../../path
When the CONFIG_FEATURE_X is enabled (Y) in .config using make menuconfig, it works fine.
But when the CONFIG_FEATURE_X is enabled as module (m) in .config, this does not include the header files from the path specified and gives the file not found error.
How can I do this?
When the CONFIG_FEATURE_X is enabled (Y) in .config using make menuconfig, it works fine.
That's because
ccflags-$(CONFIG_FEATURE_X) += -I$(obj)/../../path
would evaluate to
ccflags-y += -I$(obj)/../../path
According to Documentation/kbuild/makefiles.txt:
--- 3.7 Compilation flags
ccflags-y, asflags-y and ldflags-y
These three flags apply only to the kbuild makefile in which they
are assigned. They are used for all the normal cc, as and ld
invocations happening during a recursive build.
Note: Flags with the same behaviour were previously named:
EXTRA_CFLAGS, EXTRA_AFLAGS and EXTRA_LDFLAGS.
They are still supported but their usage is deprecated.
ccflags-y specifies options for compiling with $(CC).
So you have defined a valid compilation flag for the built-in case.
But when the CONFIG_FEATURE_X is enabled as module (m) in .config, this does not include the header files from the path specified and gives the file not found error.
That's because
ccflags-$(CONFIG_FEATURE_X) += -I$(obj)/../../path
would evaluate to
ccflags-m += -I$(obj)/../../path
According to the current version of Documentation/kbuild/makefiles.txt, there is no such compilation flag as "ccflags-m".
So the path specification is never used for the loadable module.
How can I do this?
Instead of the ccflags-$() flag, you could try to use CFLAGS_$#, a per-file options for $(CC).
CFLAGS_$#, AFLAGS_$#
CFLAGS_$# and AFLAGS_$# only apply to commands in current
kbuild makefile.
$(CFLAGS_$#) specifies per-file options for $(CC). The $#
part has a literal value which specifies the file that it is for.
Example:
# drivers/scsi/Makefile
CFLAGS_aha152x.o = -DAHA152X_STAT -DAUTOCONF
CFLAGS_gdth.o = # -DDEBUG_GDTH=2 -D__SERIAL__ -D__COM2__ \
-DGDTH_STATISTICS
These two lines specify compilation flags for aha152x.o and gdth.o.
$(AFLAGS_$#) is a similar feature for source files in assembly
languages.
Example:
# arch/arm/kernel/Makefile
AFLAGS_head.o := -DTEXT_OFFSET=$(TEXT_OFFSET)
AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312
AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt
So in your Makefile:
CFLAGS_my_file.o = -I$(obj)/../../path
As noted by the #sawdust answer, it seems (according to documentation) that only ccflags-y variable is supported, not a ccflags-m one.
However, for make things work you may use a "trick":
ccflags-y += ${ccflags-m}
Complete code:
obj-$(CONFIG_FEATURE_X) += my_file.o
ccflags-$(CONFIG_FEATURE_X) += -I$(obj)/../../path
# After all, add content of 'ccflags-m' variable to 'ccflags-y' one.
ccflags-y += ${ccflags-m}

CFLAGS variation for modules in makefile

I'm working on a large firmware and I've to add GNU gprof to only some modules(file directories) of it. The makefiles have inherited structure. So I do it this way:
ft/*.o : ft/*.c
CFLAGS += -pg
ft/*.o : ft/*.c
LDFLAGS += -pg
But this gives me a warning that it will overwrite the CFLAGS and then it adds the gprof to all the modules. My guess is that CFLAG is somewhere common. How can I make sure that CFLAG only works on the part of module(directory) I want on?
You can do it using target-specific variables.
The correct syntax is:
ft/*.o : CFLAGS += -pg
ft/*.o : LDFLAGS += -pg
These are the lines you need to add.
Alternatively, you can add these flags to executables, shared and static libraries. Target specific variables propagate to its prerequisites, i.e. the .o files comprising your binaries.

No rule to make target based on parameter use

I am using a makefile to control the compilation of my project. At the start of my Makefile, I have:
ifdef PIXEL
CFLAGS += -DBY_PIXEL
else
ifdef LINE
CFLAGS += -DBY_LINE
else
ifdef BLOCK
CFLAGS += -DBY_BLOCK
else
CFLAGS += -DBY_PIXEL (HERE)
endif
endif
endif
I have the error "No rule to make target XXX" where XXX is PIXEL, LINE or BLOCK. However when I don't write any parameter, it finds the target in the last else (where I put (HERE).
I dont fully understand why but I don't often write Makefile. Do you guys have an idea about it?
To specify a variable for make, set it to a value after the make command. For example, make PIXEL=foo build

:= or += when compiling Linux kernel modules?

Tutorials for compiling the kernel module for Linux, use different syntax for the Makefile.
Example 1
obj-m += rpi-pwm.o
Example 2
obj-m := nothing.o
What are the differences, and is there a preferred way?
:= would set the variable obj-m to nothing.o. This implies that if obj-m was previously set then it would be replaced by nothing.o.
+= would add rpi-pwm.o to the variable obj-m. If obj-m was previously set to nothing.o, then it'd become nothing.o rpi-pwm.o.
Saying
obj-m += rpi-pwm.o
is equivalent to saying
obj-m := $(obj-m) rpi-pwm.o

Resources