instalar - makefile 112 makeopts no existe el fichero o el directorio
Hacer make para crear archivos de objetos en un directorio especĂfico (2)
GNU Make 3.82
gcc 4.7.2
c89
Tengo el siguiente archivo make:
INC_PATH=-I/home/dev_tools/apr/include/apr-1
LIB_PATH=-L/home/dev_tools/apr/lib
LIBS=-lapr-1 -laprutil-1
RUNTIME_PATH=-Wl,-rpath,/home/dev_tools/apr/lib
CC=gcc
CFLAGS=-Wall -Wextra -g -m32 -O2 -D_DEBUG -D_THREAD_SAFE -D_REENTRANT -D_LARGEFILE64_SOURCE $(INC_PATH)
SOURCES=$(wildcard src/*.c)
OBJECTS=$(patsubst %.c, %.o, $(SOURCES))
EXECUTABLE=bin/to
all: build $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS)
$(OBJECTS): $(SOURCES)
$(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS)
build:
@mkdir -p bin
clean:
rm -rf $(EXECUTABLE) $(OBJECTS) bin
find . -name "*~" -exec rm {} /;
find . -name "*.o" -exec rm {} /;
Mi estructura de directorios es como este project/src project/bin
. My Makefile está en la carpeta del project (root)
y todos mis * .h y * .c están en el directorio src. Actualmente tengo solo un archivo fuente llamado timeout.c
Me sale este error:
gcc: error: src/timeout.o: No such file or directory
Lo he usado para obtener todos los archivos fuente:
SOURCES=$(wildcard src/*.c)
Y los archivos de objeto:
OBJECTS=$(patsubst %.c, %.o, $(SOURCES))
Sin embargo, la marca parece crear el archivo objeto en la carpeta raíz del proyecto donde está el Makefile. ¿No debería ponerlo en el directorio src?
Tienes dos problemas en esta regla (bueno, tres):
$(OBJECTS): $(SOURCES)
$(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS)
Aún no lo ha notado, pero la regla hace que cada objeto dependa de todas las fuentes e intenta crearlo de esa manera. No es un problema, siempre y cuando tengas una sola fuente. Fácil de arreglar con una regla de patrón estático y una variable automática :
$(OBJECTS): src/%.o : src/%.c
$(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS)
Además, el comando ("$ (CC) ...") no especifica un nombre de archivo de salida, por lo que gcc lo deducirá del nombre del archivo fuente; si le das src/timeout.c
, producirá timeout.o
(en el directorio de trabajo, project/
). Por lo tanto, debe especificar la ruta deseada al archivo de salida. Fácil de hacer con otra variable automática:
$(OBJECTS): src/%.o : src/%.c
$(CC) $(CFLAGS) -c $< $(LIB_PATH) $(LIBS) -o $@
Use la opción gcc
-o para escribir el archivo de salida en una ubicación particular. Por ejemplo, podrías decir:
$(CC) $(CFLAGS) -c $(SOURCES) $(LIB_PATH) $(LIBS) -o $(OBJECTS)
Desafortunadamente, hay un problema con esta línea: si hay más de un archivo fuente en $(SOURCES)
, no funcionará, ya que $(OBJECTS)
también contendrá múltiples nombres de archivo, y la opción -o solo se enlaza al primer argumento
Una forma de compilar cada archivo en una lista de archivos de código fuente es usar reglas implícitas. En gmake
, escribirías:
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) -o $@ $(RUNTIME_PATH) $(OBJECTS) $(LIB_PATH) $(LIBS)
%.o : %.c
$(CC) $(CFLAGS) -c $< -o $@
donde $ < se reemplaza con el nombre del archivo de entrada y $ @ se reemplaza con el nombre del archivo de salida.