Проблемы с использованием подстановочного знака в Makefile при сборке.ko из объектов в каталоге

Я организовал модули ядра как разные подкомпоненты, так что я могу легко вставить / удалить существующий подмодуль, чтобы попробовать или интегрировать вещи.

Структура каталога показана ниже:

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

Я получил предупреждение, показанное ниже, когда я попытался заменить подход [1-1] на [1-2] в моем Makefile выше.

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

Из вывода консоли я не вижу src/foo1.c был скомпилирован так, как будто я использую подход [1-1] в Makefile.

# [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 (отметьте [2] в Makefile) и выясните, что значения одинаковы для обоих подходов [1-1] и [1-2].

Кто-нибудь на SO придумал подобные проблемы, может помочь затенить свет?

(Я предпочитаю [1-2], потому что это может спасти мои усилия от обновления Makefile при добавлении нового подкомпонента)

Ниже я также приложил исходный код main.c, foo1.c & foo1.h, Вы также можете проверить репозиторий github для этой проблемы, чтобы упростить доступ к этому коду.


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 является подкомпонентом, где просто распечатывает некоторые вещи во время его инициализации и очистки:

./include/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 / 01/15

Согласно ответу Цыварева ниже, можно исправить 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 ответ

Решение

При сборке модуля ядра ваш Makefile обрабатывается дважды:

  1. Когда вы печатаете make из каталога вашего модуля.
  2. Внутри процесса Kbuild, потому что вы проходите M=$(PWD) вариант к нему.

Первый раз Makefile обрабатывается с текущим каталогом, равным каталогу модуля. Таким образом, подстановочный знак работает, как и ожидалось, что подтверждается печатью из all чек.

Но во второй раз Makefile обрабатывается с текущим каталогом, равным каталогу сборки ядра (/lib/modules/4.4.23-PT-ProbeOn-AuditOn+/build в твоем случае). В этом режиме

$(wildcard src/*.c)

пытается найти файл в каталоге сборки ядра, что явно не удается.


Во время второй обработки можно обратиться к каталогу сборки модуля с помощью $(src),

Так можно использовать wildcard() для сбора источников модуля. Но обратите внимание, что система сборки ядра ожидает, что путь к исходному файлу (точнее, к объектному файлу) будет относительно каталога сборки модуля. Итак, нужно раздеть $(src) компонент каждого файла, полученного с wildcard(),

Другие вопросы по тегам