在跨目录的对象构建.ko时,在Makefile中使用通配符的问题

时间:2018-01-12 09:37:47

标签: linux makefile wildcard kernel-module kbuild

我将内核模块组织为不同的子组件,因此我可以轻松插入/删除现有的子模块来尝试或集成内容。

目录布局如下所示:

foo --+-- Makefile
      |
      +-- main.c
      |
      +-- include --+-- foo1.h
      |             |
      |             +-- ... (other headers)
      |
      |
      +-- src ------+-- foo1.c
                    |
                    +-- ... (other sources)

这是我的Makefile,

MODULE_NAME = foo
obj-m += $(MODULE_NAME).o

# [approach 1-1]
# SRCS := main.c src/foo1.c

# [approach 1-2]
SRCS := main.c $(wildcard src/*.c)

$(MODULE_NAME)-objs += main.o $(SRCS:.c=.o)

all:
        # [2] echo to check if foo-objs values changes
        echo $($(MODULE_NAME)-objs)
        KCFLAGS="-I$(PWD)/include" \
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

当我尝试在上面的Makefile中用[1-2]替换方法[1-1]时,我收到如下警告。

WARNING: "InitFoo1" [.../foo/foo.ko] undefined!
WARNING: "CleanuptFoo1" [.../foo/foo.ko] undefined!

在控制台输出中,我看不到src/foo1.c已编译,就像我在Makefile中使用方法[1-1]一样。

# [2] echo to check if foo-objs values changes
echo main.o main.o src/foo1.o
main.o main.o src/foo1.o
KCFLAGS="-I/home/cyng93/experiment/issues/so_kbuild_wildcard/include" \
make -C /lib/modules/4.4.23-PT-ProbeOn-AuditOn+/build M=/home/cyng93/experiment/issues/so_kbuild_wildcard modules
make[1]: Entering directory '/linux'
  CC [M]  /home/cyng93/experiment/issues/so_kbuild_wildcard/main.o
  LD [M]  /home/cyng93/experiment/issues/so_kbuild_wildcard/foo.o
  Building modules, stage 2.
  MODPOST 1 modules
WARNING: "InitFoo1" [/home/cyng93/experiment/issues/so_kbuild_wildcard/foo.ko] undefined!
WARNING: "CleanupFoo1" [/home/cyng93/experiment/issues/so_kbuild_wildcard/foo.ko] undefined!
  CC      /home/cyng93/experiment/issues/so_kbuild_wildcard/foo.mod.o
  LD [M]  /home/cyng93/experiment/issues/so_kbuild_wildcard/foo.ko
make[1]: Leaving directory '/linux'

我尝试回显foo-objs(在Makefile中检查[2]),发现方法[1-1]和&的值相同。 [1-2]。

SO上的任何人都提出类似的问题可以帮助掩盖一些问题吗?

(我更喜欢[1-2],因为它可以节省我在添加新子组件时更新Makefile的工作量)

下面我还附上了main.cfoo1.c&的源代码。 foo1.h。 您还可以查看github repo for this issue以便更轻松地访问这些代码。

的main.c

#include <linux/module.h>
#include "foo1.h"


static int myinit(void)
{
    printk("Module inserted!\n");
    InitFoo1();

    return 0;
}

static void myexit(void)
{
    CleanupFoo1();
    printk("Module removed!\n");
}

module_init(myinit);
module_exit(myexit);

MODULE_LICENSE("GPL v2");

在这里,foo1是一个子组件,只需在初始化和清理过程中打印出一些内容:

./包括/ foo1.h

#ifndef FOO1_H
#define FOO1_H

int InitFoo1(void);
void CleanupFoo1(void);

#endif

./ SRC / foo1.c

#include <linux/module.h>
#include "foo1.h"


int InitFoo1(void)
{
    printk("Init Foo1\n");
    return 0;
}


void CleanupTest(void)
{
    printk("Cleanup Foo1\n");
}

update_2018 / 1月15日

根据下面的Tsyvarev回答,可以通过修改Makefile来修改Makefile,如下所示:

MODULE_NAME = foo
obj-m += $(MODULE_NAME).o

# [approach 1-1]
# SRCS := main.c src/foo1.c

# [approach 1-2 (not working)]
# SRCS := main.c $(wildcard src/*.c)

# [approach 1-2 (working)]
MISC := $($(src)/wildcard src/*.c)
SRCS := main.c $(MISC:$(src)%/=%)

$(MODULE_NAME)-objs += main.o $(SRCS:.c=.o)

all:
        # [2] echo to check if foo-objs values changes
        echo $($(MODULE_NAME)-objs)
        KCFLAGS="-I$(PWD)/include" \
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
        make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

1 个答案:

答案 0 :(得分:0)

构建内核模块时,Makefile处理两次

  1. 从模块目录中键入make时。
  2. 在Kbuild流程中,因为您将M=$(PWD)选项传递给它。
  3. 首次使用当前目录处理Makefile,该目录等于模块的目录。因此,通配符按预期工作,通过从all收据打印确认。

    但第二次处理Makefile时,当前目录等于内核的构建目录(在您的情况下为/lib/modules/4.4.23-PT-ProbeOn-AuditOn+/build)。在那种模式下

    $(wildcard src/*.c)
    

    尝试在内核的构建目录中查找文件,这显然会失败。

    在第二次处理时,可以使用$(src)来引用模块的构建目录。

    这样可以使用wildcard()来收集模块的来源。但请注意,内核构建系统期望源文件(更确切地说, object 文件)的路径相对于模块的构建目录为。因此,需要删除使用$(src)获得的每个文件的wildcard()分量。