Autor Tema: Makefile foreach  (Leído 2023 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado planeta9999

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Makefile foreach
« en: 12 de Mayo de 2017, 20:24:30 »
.

Estos días he estado mirando el tema del Makefile, que me ha parecido bastante interesante.

Tengo un proyecto para Raspberry, que en principio iba a hacer con QT Creator, pero ya no lo tengo claro, porque algo que yo pensaba que estaría mascado, y me refiero a reproducir un video, parece que es mucho más complejo. Al final creo que usaré OpenMax IL para reproducir los videos, y aunque tengo un fuente y he conseguido un libro en PDF, es algo extremadamente enrevesado.

Total, que probablemente me lo curraré directamente en la RPY3, editando con Geeny (espero conseguir configurarle el Debug con GDB), y para compilar quiero hacerlo directamente con el Makefile o configurar Geeny para que haga lo mismo con make Makefile.

Encontré por Youtuble un cursillo acelerado de 6 capítulos, y aunque se quedan en lo básico, tengo pillados los conceptos. Bueno, al grano, en mi programa se leen el estado de 32 entradas usando un par de MCP23S17 por SPI, y se reproducen unos videos en función del estado de esas entradas y un fichero de configuración guardado en un Pendrive USB. Encontré un fuente prefabricado para el MCP23S17, que se lo trabaja muy bien, viene con su Makefile para compilarlo.

He abierto el Makefile y más o menos lo tengo claro, salvo en las lineas que usa el foreach. Este es el Makefile, entiendo que el foreach es como un bucle for,  pero como en principio no hay nada definido en INCPATHS y LIBPATHS, no cazo como funciona, además esos TMP tampoco entiendo de donde salen.


Código: [Seleccionar]
PROJECT=mcp23s17
SOURCES=src/mcp23s17.c
LIBRARY=static
INCPATHS=
LIBPATHS=
LDFLAGS=
CFLAGS=-c -Wall
CC=gcc

# ------------ MAGIC BEGINS HERE -------------

# Automatic generation of some important lists
OBJECTS=$(SOURCES:.c=.o)
INCFLAGS=$(foreach TMP,$(INCPATHS),-I$(TMP))
LIBFLAGS=$(foreach TMP,$(LIBPATHS),-L$(TMP))

# Set up the output file names for the different output types
ifeq "$(LIBRARY)" "shared"
    BINARY=lib$(PROJECT).so
    LDFLAGS += -shared
else ifeq "$(LIBRARY)" "static"
    BINARY=lib$(PROJECT).a
else
    BINARY=$(PROJECT)
endif

all: $(SOURCES) $(BINARY)

$(BINARY): $(OBJECTS)
    # Link the object files, or archive into a static library
    ifeq "$(LIBRARY)" "static"
ar rcs $(BINARY) $(OBJECTS)
    else
$(CC) $(LIBFLAGS) $(OBJECTS) $(LDFLAGS) -o $@
    endif

.c.o:
$(CC) $(INCFLAGS) $(CFLAGS) -fPIC $< -o $@

distclean: clean
rm -f $(BINARY)

example: example.c
gcc -o example example.c -Isrc/ -L. -lmcp23s17

interrupt_example: interrupt_example.c
gcc -o interrupt_example interrupt_example.c -Isrc/ -L. -lmcp23s17

clean:
rm -f $(OBJECTS)

install: $(BINARY)
install src/mcp23s17.h /usr/local/include
install $(BINARY) /usr/local/lib
« Última modificación: 12 de Mayo de 2017, 20:29:33 por planeta9999 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Makefile foreach
« Respuesta #1 en: 12 de Mayo de 2017, 21:07:31 »
Por lo que entiendo:

Lo que hace es agarrar una lista ( INCPATHS ) elemento a elemento y ponerlo en TMP momentaneamente. Luego simplemente lo reemplaza en el texto ( 3er argumento )

Suponete
INCPATHS = /etc/ /opt/

Cada vuelta dejaria el -I/etc/ , -I/opt/

quedandote una lista en INCFLAGS

INCFLAGS quedaria -I/etc/ -I/opt/

Imagino que los INCPATHS se los dara el compilador cuando los genera. Sino tenes que definirlos vos.

Desconectado planeta9999

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:Makefile foreach
« Respuesta #2 en: 12 de Mayo de 2017, 21:46:41 »
.

Gracias Killer.
Si, algo así imaginaba, pero como en este Makefile, no han puesto nada en INCPATHS ni en LIBPATHS, no se si esos valores se ponen separados por comas, por un espacio en blanco o como.

Ahora veo claro lo del TMP, pensé que era una variable propia de make (pero no está documentada como tal), y como tampoco la veía definida al principio del fuente, no entendía de donde salía. Ahora veo que queda definida en el primer parámetro del foreach.

Buscaré algún ejemplo por Google, a ver como se escriben las listas de valores, si separadas por comas, por espacios...

Desconectado jorgeaf_59

  • PIC10
  • *
  • Mensajes: 26
Re:Makefile foreach
« Respuesta #3 en: 12 de Mayo de 2017, 23:18:15 »
Hola,

Creo que el makefile se hizo a partir de un "esqueleto" o esquema genérico (ver https://gist.github.com/mkhl/159461); en el caso particular de las bibliotecas o librerías para MCP23S17 por SPI esa parte no cumple ninguna función.
Disculpen si estoy equivocado, solamente trato de aprender algo siguiendolos a ustedes, y cuando puedo, sugerir algo.
Saludos,

Jorge

Desconectado planeta9999

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:Makefile foreach
« Respuesta #4 en: 12 de Mayo de 2017, 23:58:23 »
Creo que el makefile se hizo a partir de un "esqueleto" o esquema genérico (ver https://gist.github.com/mkhl/159461); en el caso particular de las bibliotecas o librerías para MCP23S17 por SPI esa parte no cumple ninguna función.


Yo más bien creo que están ahí para que el usuario añada los path de acceso a sus includes y librerías, necesarias para otras partes del código del propio usuario.

Por ejemplo en mi caso, tengo añadir código fuente para usar OpenMAX IL para reproducir videos, que precisan de otras librerías y ficheros .h para los includes, me vendrá bien meterlo ahí.

Lo que tengo que ver es donde se le dice el nivel de optimización, creo que es un parámetro a poner en CFLAGS, y que compile o no para Debug.


Edito; encontré esto sobre el nivel de optimización de GCC. Por omisión está sin optimizar, y va bien para Debug, pero recomendable compilar con optimización para producción. Probaré los diversos valores a ver que tal.

Código: [Seleccionar]
-O
Next up is the -O variable. This variable controls the overall level of optimization. Changing this value will make the code compilation take more time and will use much more memory, especially as the level of optimization is increased.

There are seven -O settings: -O0, -O1, -O2, -O3, -Os, -Og, and -Ofast. Only use one of them in /etc/portage/make.conf.

With the exception of -O0, the -O settings each activate several additional flags, so be sure to read the GCC manual's chapter on optimization options to learn which flags are activated at each -O level, as well as some explanations as to what they do.

Let us examine each optimization level:

-O0: This level (that is the letter "O" followed by a zero) turns off optimization entirely and is the default if no -O level is specified in CFLAGS or CXXFLAGS. This reduces compilation time and can improve debugging info, but some applications will not work properly without optimization enabled. This option is not recommended except for debugging purposes.
-O1: the most basic optimization level. The compiler will try to produce faster, smaller code without taking much compilation time. It is basic, but it should get the job done all the time.
-O2: A step up from -O1. The recommended level of optimization unless the system has special needs. -O2 will activate a few more flags in addition to the ones activated by -O1. With -O2, the compiler will attempt to increase code performance without compromising on size, and without taking too much compilation time.
-O3: the highest level of optimization possible. It enables optimizations that are expensive in terms of compile time and memory usage. Compiling with -O3 is not a guaranteed way to improve performance, and in fact, in many cases, can slow down a system due to larger binaries and increased memory usage. -O3 is also known to break several packages. Using -O3 is not recommended.
-Os: optimizes code for size. It activates all -O2 options that do not increase the size of the generated code. It can be useful for machines that have extremely limited disk storage space and/or CPUs with small cache sizes.
-Og: In GCC 4.8, a new general optimization level, -Og, has been introduced. It addresses the need for fast compilation and a superior debugging experience while providing a reasonable level of runtime performance. Overall experience for development should be better than the default optimization level -O0. Note that -Og does not imply -g, it simply disables optimizations that may interfere with debugging.
-Ofast: New in GCC 4.7, consists of -O3 plus -ffast-math, -fno-protect-parens, and -fstack-arrays. This option breaks strict standards compliance, and is not recommended for use.
As previously mentioned, -O2 is the recommended optimization level. If package compilation fails and while not using -O2, try rebuilding with that option. As a fallback option, try setting the CFLAGS and CXXFLAGS to a lower optimization level, such as -O1 or even -O0 -g2 -ggdb (for error reporting and checking for possible problems).
« Última modificación: 13 de Mayo de 2017, 00:15:55 por planeta9999 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Makefile foreach
« Respuesta #5 en: 13 de Mayo de 2017, 10:46:35 »
Si, va en CFLAGS, mandale -O2.

No veo diferencias entre DEBUG/PRODUCCION en el makefile. La unica diferencia que hay es que en caso de querer hacer una libreria cambias la variable LIBRARY a static o shared, sino compila directamente.
« Última modificación: 13 de Mayo de 2017, 10:48:59 por KILLERJC »

Desconectado planeta9999

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:Makefile foreach
« Respuesta #6 en: 13 de Mayo de 2017, 18:21:23 »

No veo diferencias entre DEBUG/PRODUCCION en el makefile. La unica diferencia que hay es que en caso de querer hacer una libreria cambias la variable LIBRARY a static o shared, sino compila directamente.


Si que veo bastantes opciones en la llamada al compilador, conocía el -g, pero veo que hay muchas más, que supongo se pueden meter en el CFLAGS.

https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html

Precisamente, he estado probando recientemente el Debug en QTCreator, y veía cosas raras al intentar visualizar el estado de las variables, ahora pienso que puede ser por no haber compilado con la opción adecuada.
« Última modificación: 13 de Mayo de 2017, 18:23:48 por planeta9999 »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re:Makefile foreach
« Respuesta #7 en: 14 de Mayo de 2017, 05:19:34 »
Los inicios con el Makefile son difíciles porque hay que estudiar la línea de comandos. Lo bueno es que eso te servirá para siempre. No cambia con los años.
Verás como al final te resultará más complicado buscar todas las opciones repartidas por montones de menús del Eclipse.

Un saludo.

Desconectado planeta9999

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 3520
    • Pinballsp
Re:Makefile foreach
« Respuesta #8 en: 14 de Mayo de 2017, 07:10:18 »
.

Si, ya veo el potencial que tiene el Makefile, de todas formas mirando por los IDES se localiza todo igual, en Eclipse, KDS y Atmel Studio lo tengo toda controlado. Y quiero mirar como se configura en Geeny para usarlo como IDE alternativo en Raspberry, para hacer programas sin entorno gráfico.