Compilación del módulo Kernel y KBUILD_NOPEDANTIC

Me he dado cuenta de que los kernels recientes (a partir de 2.16.24?) No les gusta si CFLAGS se cambia en el archivo Kbuild del módulo externo. Si se modifica CFLAGS se le emitirá el siguiente error por parte del sistema kernel de Linux Kbuild:

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

De aquí :

Los módulos externos tienen en algunos casos una opción modificada de gcc       modificando CFLAGS. Esto nunca ha sido documentado y       fue una mala práctica.

Correo electrónico adicional de LKML.

¿Por qué es mala idea? ¿Qué es racional?

13

2 Respuestas

Antes que nada, vale la pena mencionar que EXTRA_CFLAGS ha quedado en desuso hace un tiempo y se reemplaza por ccflags-y . Puede leer sobre la intención de ccflags-y en Documentation/kbuild/makefiles.txt , sección 3.7.

Básicamente, esta variable le permite agregar configuraciones al conjunto de indicadores de compilación C, dentro del alcance del archivo donde está asignado únicamente. Se supone que no debes cambiar las banderas globales porque podrían tener un impacto global más allá de tu propio archivo MAKE, lo cual se considera una mala práctica. El cheque que menciona verifica que, de hecho, los indicadores globales no se cambiaron con los archivos make incluidos.

Es interesante comprobar cómo ccflags-y , antes conocido como EXTRA_CFLAGS , termina siendo utilizado en el proceso de compilación. El seguimiento de algunos puntos relevantes (pero no todos, porque eso se deja como un ejercicio para el lector ;-)) muestra lo siguiente:

EXTRA_CFLAGS can still be used, according to scripts/Makefile.lib

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

The same file shows how ccflags-y ends up in the C compilation flags (and also shows you that you have another variable at your disposal, called CFLAGS_.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)

Luego, en scripts/Makefile.build , se define la regla de compilación:

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

Tenga en cuenta que estas son todas las variables expandidas recursivamente, usando = y no : = , lo que significa que su propio valor de ccflags-y se inserta en C indica cuándo lo define en su propio archivo MAKE.

Finally about KBUILD_NOPEDANTIC, which you mention in the title but not in the actual question. This test for changed value of CFLAGS can be disabled by giving KBUILD_NOPEDANTIC any value -- see 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

Los archivos a los que se hace referencia en esta respuesta fueron recuperados hoy.

Ahora ... al no ser un experto en esta área y mirar más allá en los makefiles después de escribir toda esta historia, hay algo que tampoco entiendo. Me parece que CFLAGS no se usa en el sistema de compilación (ni implícita ni explícitamente), pero sí lo es KBUILD_CFLAGS . Así que me pregunto si esta verificación de cambios en CFLAGS en realidad debería ser una verificación de cambios en KBUILD_CFLAGS en su lugar.

9
agregado

Los makefiles de Linux compilan CFLAGS de una manera apropiada para el núcleo.
Reemplazando CFLAGS significa que agrega algunos indicadores y puede eliminar algunos indicadores. Algunos de los indicadores eliminados pueden ser importantes para la compilación correcta.

1
agregado
Si entiendo que CFLAGS son indicadores, se compila todo el núcleo y, por lo tanto, no debería modificarse. Esto significa que kernel KBuild system compilará mi módulo externo con CFLAGS + EXTRA_CFLAGS. ¿Correcto?
agregado el autor dimba, fuente
Creo que sí.
agregado el autor ugoren, fuente