Как интегрировать autoconf в ядро ​​Makfile? - PullRequest
0 голосов
/ 10 июня 2019

У меня есть проект модуля ядра, и я использую autoconf для генерации файла Makefile внутри модуля ядра. И такое использование autoconf нарушает ядро ​​при построении исходного кода дерева, потому что Makefile ядра не поддерживает autoconf, поэтому не может сгенерировать файл конфигурации для модуля. Есть ли способ сделать ядро ​​Makefile и autoconf совместимыми? Спасибо!

1 Ответ

1 голос
/ 10 июня 2019

Уловка, которую я часто использовал в прошлом, состоит в том, чтобы иметь два файла Makefile - сгенерированный автомобилем один и один ядро, и переключать их во время «make».

Вот пример:

Makefile.am

## Process this file with automake to produce Makefile.in

## this is so that Automake includes the C compiling definitions, and
## includes the source files in the distribution.

## [@]kerneldir[@] is the kernel build directory.
## [@]kernelext[@] is the kernel module extension `ko`.
## [@]moduledir[@] is the module installation directory.
## [@]depmod[@] is the depmod program.

EXTRA_PROGRAMS = automake_dummy
automake_dummy_SOURCES = mymodule.c Makefile.kernel
generated_sources =

## there is no *just* object file support in automake.  This is close enough
module_DATA = mymodule.o
export_objs = mymodule.o

# where the kernel build is located
KERNEL_LOCATION=@kerneldir@

MYMODULE_TOP_SRCDIR = @abs_top_srcdir@
MYMODULE_TOP_BUILDDIR = @abs_top_builddir@
MYMODULE_BUILDDIR = @abs_builddir@

# some magic for using linux kernel settings
# when compiling module(s)
MYMODULE_EXTRA_CFLAGS = -DEXPORT_SYMTAB $(DEFS) -I$(MYMODULE_BUILDDIR) \
    -I$(MYMODULE_TOP_BUILDDIR) -I$(MYMODULE_TOP_SRCDIR)/include
export MYMODULE_EXTRA_CFLAGS KERNEL_LOCATION module_DATA export_objs

.PHONY: FORCE

$(automake_dummy_SOURCES): FORCE
    @test "$(srcdir)" == "." || test -e "$@" || ln -vs "$(srcdir)/$@" .

# Add FORCE in case the kernel has changed.
$(module_DATA): $(generated_sources) $(automake_dummy_SOURCES) FORCE
    mv Makefile Makefile.automake
    cp Makefile.kernel Makefile
    $(MAKE) -C $(KERNEL_LOCATION) SUBDIRS=$(MYMODULE_BUILDDIR) M=$(MYMODULE_BUILDDIR) modules
    mv Makefile.automake Makefile

install-moduleDATA: $(module_DATA)
    $(mkinstalldirs) $(DESTDIR)$(moduledir)
    @list='$(module_DATA:.o=.@kernelext@)'; for p in $$list; do \
      if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
      f="`echo $$p | sed -e 's|^.*/||'`"; \
      echo " $(INSTALL_DATA) $$d$$p $(DESTDIR)$(moduledir)/$$f"; \
      $(INSTALL_DATA) $$d$$p $(DESTDIR)$(moduledir)/$$f; \
    done

uninstall-moduleDATA:
    @list='$(module_DATA:.o=.@kernelext@)'; for p in $$list; do \
      f="`echo $$p | sed -e 's|^.*/||'`"; \
      echo " rm -f $(DESTDIR)$(moduledir)/$$f"; \
      rm -f $(DESTDIR)$(moduledir)/$$f; \
    done

if SANDBOXED
else
install-data-local: install-moduleDATA
    -@depmod@ -a
endif

MOSTLYCLEANFILES = $(module_DATA) $(module_DATA:.o=.@kernelext@) \
    Modules.symvers Module.symvers Module.markers modules.order
CLEANFILES = $(module_DATA:.o=.mod.c) $(generated_sources)

clean-local:
    -rm -f .*.cmd .*.flags
    -rm -rf .tmp_versions
    -if test "$(srcdir)" != "."; then \
        for f in $(automake_dummy_SOURCES); do \
            if test "$$f" -ef "$(srcdir)/$$f"; then \
                rm -f "$$f"; \
            fi; \
        done; \
    fi

FORCE:

Используются некоторые автоматические замены:

  • kerneldir - это каталог сборки ядра, например / lib / modules/ $ {версия} / build
  • kernelext - это расширение модуля, которое должно быть ko.
  • moduledir - это каталог установки модуля, например / lib / modules / ${version} / extra
  • depmod - это программа depmod, например, установленная AC_PATH_PROG(depmod, depmod, /sbin/depmod, $PATH:/sbin)

(Вы можете заменить все экземпляры @kernelext@ в Makefile.am на ko, если хотите.)

Переменные automake_dummy_SOURCES, module_DATA, export_objs и MYMODULE_EXTRA_CFLAGS можно настроить при необходимости.

Обратите внимание, как правило для цели $(module_DATA) копирует файлы Makefile до и после запуска файла Makefile ядра.Исходный (сгенерированный automake) Makefile переименовывается в Makefile.automake, а другой Makefile (Makefile.kernel) копируется на его место.Когда суб-make завершается без ошибок, Makefile.automake перемещается обратно в Makefile.Это не работает, когда подкомпозиция не завершается успешно, но это решается другим Makefile.

Makefile.kernel

EXTRA_CFLAGS += $(MYMODULE_EXTRA_CFLAGS)

obj-m := $(module_DATA)
ifeq ($(VERSION).$(PATCHLEVEL), 2.4)
export-objs := $(export_objs)
endif

all mostlyclean clean maintainer-clean distclean:
    $(warning **************************************************)
    $(warning *** Makefile trick not undone, trying to recover *)
    $(warning **************************************************)
    mv Makefile.automake Makefile
    $(MAKE) $@

# The following is needed for 2.5 kernels and also let's the makefile work
# when things get screwed.
ifneq (,$(wildcard $(KERNEL_LOCATION)/Rules.make))
include $(KERNEL_LOCATION)/Rules.make
endif

Thisпереименовывается в Makefile автоматически сгенерированными правилами Makefile во время подкоманды ядра и впоследствии переименовывается обратно в Makefile.kernel.

Правило all mostlyclean clean maintainer-clean distclean: предназначено для восстановления, когда предыдущая make закончилась ошибкой,оставляя Makefile.kernel вместо Makefile.Он перемещает исходный сгенерированный автомобилем Makefile (теперь в Makefile.automake) обратно в Makefile и автоматически запускает make.

...