-->

ccflag option in Makefile

2020-08-02 11:37发布

问题:

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
  1. When the CONFIG_FEATURE_X is enabled (Y) in .config using make menuconfig, it works fine.

  2. 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?

回答1:

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


回答2:

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}