2012-06-18 2 views
13

Я заметил, что последние ядра (начиная с 2.16.24?) Не нравятся, если в внешнем модуле Kbuild изменен CFLAGS. Если CFLAGS изменяется будет произведена следующая ошибка системой Linux ядра Kbuild:Компиляция модуля ядра и KBUILD_NOPEDANTIC

scripts/Makefile.build:46: *** CFLAGS was changed in "/some/path". Fix it to use EXTRA_CFLAGS. Stop. 

От here:

Внешние модули имеют в некоторых случаях доработанную Gcc вариант путем изменения CFLAGS. Это никогда не было документировано, и был плохой практикой.

Дополнительный email от LKML.

Почему это плохая идея? Что рационально?

ответ

1

Linux makefiles создает CFLAGS способом, подходящим для ядра.
Переопределение CFLAGS означает, что вы добавляете некоторые флаги и можете удалить некоторые флаги. Некоторые из удаленных флагов могут быть важны для правильной компиляции.

+0

Если я понимаю, что CFLAGS являются флагами, все ядро ​​скомпилировано и поэтому не должно изменяться. Это означает, что система KBuild ядра скомпилирует мой внешний модуль с помощью CFLAGS + EXTRA_CFLAGS. Верный? – dimba

+0

думаю есть. – ugoren

9

Прежде всего, стоит упомянуть, что EXTRA_CFLAGS был устаревшим, но был заменен на ccflags-y. Вы можете прочитать о намерении ccflags-y в разделе Documentation/kbuild/makefiles.txt, раздел 3.7.

В принципе, эта переменная позволяет добавлять настройки к множеству флагов компиляции C, в пределах объема файла, в котором она назначена. Вы не должны изменять глобальные флаги, потому что может иметь глобальное влияние за пределами вашего собственного make-файла, что считается плохой практикой. Проверка, которую вы упомянули, проверяет, действительно ли глобальные флаги не изменялись включенными make-файлами.

Интересно посмотреть, как ccflags-y, ранее известный как EXTRA_CFLAGS, в конечном итоге используется в процессе сборки. Трассировка некоторые важные моменты (но не все, потому что остается в качестве упражнения для читателя ;-)) показывает следующее:

EXTRA_CFLAGS все еще можно использовать, в соответствии с scripts/Makefile.lib

1 # Backward compatibility 
2 asflags-y += $(EXTRA_AFLAGS) 
3 ccflags-y += $(EXTRA_CFLAGS) 

В том же файле показывает, как ccflags-y заканчивается в C флагах компиляции (а также показывает, что вы имеете другую переменную в вашем распоряжении, называется CFLAGS_<filename>.o):

104 orig_c_flags = $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) $(KBUILD_SUBDIR_CCFLAGS) \ 
105     $(ccflags-y) $(CFLAGS_$(basetarget).o) 
106 _c_flags  = $(filter-out $(CFLAGS_REMOVE_$(basetarget).o), $(orig_c_flags)) 
... 
133 __c_flags  = $(_c_flags) 
... 
147 c_flags  = -Wp,-MD,$(depfile) $(NOSTDINC_FLAGS) $(LINUXINCLUDE)  \ 
148     $(__c_flags) $(modkern_cflags)       \ 
149     -D"KBUILD_STR(s)=\#s" $(basename_flags) $(modname_flags) 

Тогда в scripts/Makefile.build, комп Правило ilation определяется:

234 cmd_cc_o_c = $(CC) $(c_flags) -c -o [email protected] $< 

Обратите внимание, что все они рекурсивно вычисляемые переменные, используя = и не :=, а это значит, что ваше собственное значение ccflags-y Вставляется в флагах C при определении его в собственном Makefile.

Окончательно о KBUILD_NOPEDANTIC, о котором вы упоминаете в заголовке, но не в актуальном вопросе.Это испытание для измененного значения CFLAGS можно отключить, давая KBUILD_NOPEDANTIC любое значение - см scripts/Makefile.build

47 ifeq ($(KBUILD_NOPEDANTIC),) 
48   ifneq ("$(save-cflags)","$(CFLAGS)") 
49     $(error CFLAGS was changed in "$(kbuild-file)". Fix it to use ccflags-y) 
50   endif 
51 endif 

Файлы, на которые ссылается в этом ответе были извлекаемые сегодня.

Теперь ... не будучи экспертом в этой области и глядя дальше в make-файлы после написания всей этой истории, есть и то, что я тоже не понимаю. Мне кажется, что CFLAGS не используется в системе сборки (неявно или явно), но KBUILD_CFLAGS есть. Поэтому я задаюсь вопросом, действительно ли эта проверка изменений в CFLAGS должна быть проверкой на изменения в KBUILD_CFLAGS.

Смежные вопросы