Quiero cambiar la ubicación de mi código de prueba (tsnnls_test_DKU.c) y soy incapaz de hacer el cambio en el fichero makefile para reflejar este cambio de carpeta correctamente. Un poco de ayuda sería apreciada.

Tengo dos preguntas:
1) ¿Cómo vincular los archivos de objetos de diferentes subdirectorio
2) incluir diferentes rutas de búsqueda (3 rutas de búsqueda en mi ejemplo).

En mi orinal de instalación, donde makefile funciona bien, pongo mi código de prueba tsnnls_test_DKU.c en la siguiente ubicación (dentro de las bibliotecas de terceros):

Dir1 = /home/dkumar/libtsnnls-2.3.3/tsnnls

Todos los archivos objeto, que me une a, están en

OBJDir = /home/dkumar/libtsnnls-2.3.3/tsnnls

Además, algunos incluyen el archivo que figuran en tsnnls_test_DKU.c son en tres ubicaciones siguientes (tres rutas de búsqueda):

Dir1 = /home/dkumar/libtsnnls-2.3.3/tsnnls  
Dir2 = /home/dkumar/libtsnnls-2.3.3
Dir3 = /home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic

y mi makefile funciona bien.

Sin embargo, me gustaría cambiar la ubicación de código de prueba para:

Dir4 = /home/dkumar/CPP_ExampleCodes_DKU/Using_tsnnls_DKU/

Aquí es cómo mi makefile parece (Actualizado después de las entradas de otro usuario:

# A sample Makefile

VPATH = -L/home/dkumar/libtsnnls-2.3.3/tsnnls
INC_PATH  = -I/home/dkumar/libtsnnls-2.3.3/ -I/home/dkumar/libtsnnls-2.3.3/tsnnls/  -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic/

# Here is a simple Make Macro.
LINK_TARGET     = tsnnls_test_DKU
OBJS_LOC    = tsnnls_test_DKU.o

# Here is a Make Macro that uses the backslash to extend to multiple lines.
OBJS =  libtsnnls_la-taucs_malloc.o libtsnnls_la-taucs_ccs_order.o \
    libtsnnls_la-taucs_ccs_ops.o libtsnnls_la-taucs_vec_base.o \
    libtsnnls_la-taucs_complex.o libtsnnls_la-colamd.o \
    libtsnnls_la-amdbar.o libtsnnls_la-amdexa.o \
    libtsnnls_la-amdtru.o libtsnnls_la-genmmd.o \
    libtsnnls_la-taucs_timer.o libtsnnls_la-taucs_sn_llt.o \
    libtsnnls_la-taucs_ccs_base.o libtsnnls_la-tlsqr.o \
    libtsnnls_la-tsnnls.o libtsnnls_la-lsqr.o   \
    $(OBJS_LOC)

REBUILDABLES = $(LINK_TARGET) 

all : $(LINK_TARGET)
    echo All done

clean : 
    rm -f $(REBUILDABLES)   
    echo Clean done

#Inclusion of all libraries
RANLIB = ranlib
STATICLIB= /usr/local/lib/taucs_full/lib/linux/libtaucs.a 

tsnnls_test_LDADD = $(LDADD)
LIBS = -largtable2 -llapack -lblas -lquadmath -lm

$(LINK_TARGET) : $(OBJS)   $(tsnnls_test_LDADD) $(LIBS)  $(STATICLIB)
gcc -g ${INC_PATH} -o [email protected] $^

El error que me sale al intentar ejecutar «$make»

make: *** No rule to make target `libtsnnls_la-taucs_malloc.o', needed by `tsnnls_test_DKU'.  Stop.

Obviamente, no he sido capaz de utilizar VPATH correctamente.

ACTUALIZACIÓN:
Gracias a Mike Kinghan por responder a mi pregunta.

  • El archivo Makefile no parecen referirse a cualquier incluir rutas (ya que sólo hace que el enlace de la etapa explícito). Si desea vincular los objetos que residen en diferentes subdirectorios, es posible que desee buscar en VPATH documentación.
  • ¿Tienes algún ejemplo de trabajo de VPATH? Busqué en google; se encuentran muchos de enlace, pero nada que me funciona. Yo no podía averiguado cómo pasar VPATH para el compilador. También, estoy tratando de incluir INC_PATH donde los archivos de cabecera y otros códigos de existir. Por favor, ver mi intento actualizados del makefile. Lo que no funciona bien.
  • Si he entendido bien tu problema, los nombres de archivo enumerados en ‘${OBJS}’ puede estar en cualquiera de los varios directorios y por lo tanto ahora hay manera de decir ‘gcc’ donde estos archivos están (no un archivo Makefile problema, pero un gcc línea de comandos problema). Si este es el problema real, tengo miedo ‘${VPATH}’ no ayuda mucho, ya que sólo es utilizado por ‘hacer’ para localizar los requisitos previos. Una forma de resolver es el uso de diferentes variables de la lista de ‘OBJS’ de diferentes directorios y anteponer la ruta de acceso completa en el destino de los requisitos previos
  • Todos los archivos en ‘${OBJS}’ es de una sola carpeta. También, los archivos de encabezado, que mi código de prueba de las necesidades, están ubicados en tres diferentes carpetas de todos los mencionados en INC_PATH.
  • ¿cuál es el problema real, a continuación, (¿cuál es el mensaje de error)?
  • El mensaje de error, básicamente, establece que se olvida de decirle a hacer que los archivos de origen de su objeto de archivos dependend en. También, INC_PATH no es el nombre predeterminado para extender el compilador incluir la ruta de acceso. Trate de C_INCLUDE_PATH o CPATH si usted está usando gcc.
  • Yo podía entender cómo incluir el objeto de los archivos contenidos en el directorio diferente o directorios. Aun así, no podía utilizar C_INCLUDE_PATH y CPATH para incluir archivos.
  • Donde están los archivos de origen (*.c/*.cpp) que corresponden a los archivos de objeto? E. g. donde está el archivo de origen que corresponde a libtsnnls_la-taucs_malloc.o?
  • He sido capaz de incluir objetos de los archivos ubicados en el directorio diferente. Por favor, ver mi respuesta parcial en la sección de respuestas. Todavía no se puede incluir la búsqueda de archivos correctamente. Por favor, consulte la actualización con respecto a esto.

InformationsquelleAutor Garima Singh | 2015-01-26

2 Comentarios

  1. 20

    Q1: ¿Cómo vincular los archivos de objeto desde un subdirectorio?

    Digamos que su programa prog es un programa en C que estará vinculado de objeto file0.o, file1.o que
    son compiladas en el subdirectorio obj. Aquí es el tipo de cosa que usted normalmente necesita en su
    el makefile para realizar la vinculación.

    $(OBJS) = $(patsubst %.o,obj/%.o,file0.o file1.o)
    
    prog: $(OBJS)
        gcc -o [email protected] $(CFLAGS) $(OBJS) $(LDFLAGS) $(LDLIBS)

    Esto hace que $(OBJS) = obj/file0.o, obj/file1.o y simplemente pasar el objeto
    los archivos, como que el comando link. Documentación de patsubst

    N. B. Esto no es suficiente para crear la obj subdirectorio si no existe cuando quieras
    compilar un archivo de objeto en ella. Tendrás que crear tu mismo o el estudio de cómo hacer que make hacerlo.

    Q2: ¿Cómo incluir diferentes rutas de búsqueda?

    Esta es una pregunta ambigua – la ambigüedad es confuso – y debemos desglosarlo en Q2.una, la Q2.b, T2.c:

    Q2.a: ¿Cómo especificar diferentes rutas de búsqueda donde el preprocesador buscará archivos de encabezado que se #include-ed en el código fuente?

    Por defecto, el preprocesador buscará archivos de encabezado de una lista estándar de rutas de búsqueda. Se les puede ver por
    ejecuta el preprocesador en modo detallado, por ejemplo,cpp -v (CTRL-C para terminar). La salida contendrá algo como:

    #include "..." search starts here:
    #include <...> search starts here:
     /usr/lib/gcc/x86_64-linux-gnu/4.8/include
     /usr/local/include
     /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
     /usr/include/x86_64-linux-gnu
     /usr/include
    End of search list.

    Supongamos que usted tiene algunos archivos de encabezado de su cuenta en subdirectorios
    inc y inc/foo/bar y desea que el preprocesador para buscar estos directorios
    así. Entonces usted necesita para pasar el preprocesador opciones:

    -I inc -I inc/foo/bar

    a su comando compile. Preprocesador opciones son convencionalmente asignado a
    el hacer variable CPPFLAGS, por ejemplo,

    CPPFLAGS = -I inc -I inc/foo/bar

    (junto con cualquier otro preprocesador de las opciones necesarias), y se transmite a través de este
    variable en el comando compile receta, por ejemplo,

    gcc -c -o [email protected] $(CPPFLAGS) $(CFLAGS) $<

    N. B. es un error común pensar que CPPFLAGS es el convencional de hacer variable para el compilador de C++ de banderas.
    La convencional de hacer variable para el compilador de C++ de banderas es CXXFLAGS.

    Se puede ver el efecto de la -I opción mediante la ejecución de:

    mkdir -p inc/foo/bar # Just to create the path
    cpp -v -I inc -I inc/foo/bar

    (CTRL-C para terminar). Ahora la salida contendrá como:

    #include "..." search starts here:
    #include <...> search starts here:
     inc
     inc/foo/bar
     /usr/lib/gcc/x86_64-linux-gnu/4.8/include
     /usr/local/include
     /usr/lib/gcc/x86_64-linux-gnu/4.8/include-fixed
     /usr/include/x86_64-linux-gnu
     /usr/include
    End of search list.

    Q2.b: Cómo especificar diferentes rutas de búsqueda donde el enlazador se busca bibliotecas?

    Vamos a suponer que usted tiene una biblioteca, libfoobar.a que usted necesita para enlazar con prog y
    el que reside en un directorio lib que es de 2 niveles arriba el fichero makefile. Entonces usted
    necesita pasar a las opciones del enlazador:

    -L ../../lib

    y

    -lfoobar

    al enlace de su comando. El primero de ellos le dirá al enlazador que ../../lib es uno de los lugares para ver
    para las bibliotecas. Convencionalmente, se pasa a esta opción en el vinculador comando receta a través de LDFLAGS. El segundo le dice
    el enlazador de buscar alguna librería llamada libfoobar.a (una biblioteca estática) o libfoobar.so
    (una biblioteca dinámica). Convencionalmente, se pasa a esta opción en el vinculador comando receta a través de LDLIBS

    Así como hay una lista predeterminada de búsqueda de caminos para el preprocesador, no es un defecto
    lista de rutas de búsqueda para el vinculador. Usted puede ver mediante la ejecución de:

    gcc -v -Wl,--verbose 2>&1 | grep 'LIBRARY_PATH'

    El resultado será algo como:

    LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.8/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/:
    /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:
    /usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../:/lib/:/usr/lib/

    Cuando usted necesita el enlace de una de las librerías estándar, por ejemplo, libm (de la librería math), que reside en uno de los
    la biblioteca por defecto de rutas de búsqueda, usted no necesita pasar cualquier -L opción. -lm solo va a hacer.

    Q2.c: Cómo especificar diferentes rutas de búsqueda donde make buscará los requisitos previos
    de los objetivos?

    N. B. Esta es una pregunta acerca de make, no una pregunta sobre el preprocesador, compilador, o
    enlazador.

    Hemos asumido que todos los de su objeto de archivos se compilan en el subdirectorio obj.
    Para conseguir compilado allí, sería agradable y simple para usar el patrón de la regla:

    obj/%.o:%.c
        gcc -c -o [email protected] $(CPPFLAGS) $(CFLAGS) $<

    que decir make que, por ejemplo, obj/file0.o está hecho de file0.c por la receta:

    gcc -c -o obj/file0.o $(CPPFLAGS) $(CFLAGS) file0.c

    y lo mismo para cualquier archivo obj/*.o y archivo de correspondencia de *.c

    Esto está bien siempre y file0.c reside en el mismo directorio que el archivo makefile, pero
    supongamos que usted tiene su *.c archivos en otro lugar? Dicen que los archivos de origen se organizan
    en subdirectorios, foo/file0.c y bar/file1.c. Luego make será incapaz de
    satisfacer a que el patrón de la regla y le dicen que «no hay ninguna regla para hacer objetivo obj/file0.o»,
    etc.

    Para resolver este problema, utilice VPATH, un make variable que tiene un significado especial.
    Si asigna una lista de nombres de directorio, marcada por ‘:’, a VPATH, entonces
    make buscará un requisito previo en cada uno de los directorios listados siempre
    no puede encontrar en el directorio actual. Así:

    VPATH = foo:bar

    hará make para buscar en el directorio actual y, a continuación, foo y bar cuando
    intenta encontrar .c archivos para que coincida con el patrón de la regla. Tendrá éxito en la satisfacción de
    la regla de compilar los archivos de origen necesarios.

    N. B. ha utilizado VPATH erróneamente en su código publicados:

    VPATH = -L/home/dkumar/libtsnnls-2.3.3/tsnnls

    Tiene asignados un enlazador ruta de búsqueda, con la opción del vinculador -L, que no tiene
    negocios allí.

    Línea de base:

    • La preprecessor rutas de búsqueda, para localizar los archivos de encabezado, se especifican con
      el preprocesador del -I<dirname> opción. Pasar estas opciones para la compilación de recetas en CPPFLAGS

    • El vinculador de las rutas de búsqueda, para localizar las bibliotecas, se especifican con la
      del enlazador -L<dirname> opción. Pasar estas opciones en el enlace de la receta en LDFLAGS

    • La búsqueda de caminos para la preprequisities de make reglas se especifican en
      el make variable VPATH, como un ‘:-marcada lista de nombres de directorio.

    • Gracias por tan detallada respuesta. Esto es exactamente lo que yo estaba buscando. Realmente no puedo agradecerles lo suficiente.
    • Iba a dar +10 si pudiera. Esta respuesta resume cada pregunta que yo tenía acerca de los Makefiles. Voy a mantener como referencia para siempre. Gracias!
  2. 0

    My answer to part of question
    He podido averiguar cómo vincular object files from different subdirectory/subdirectories; pero, aún could not figure out how to use different search path:

    Mi actual makefile es:

        # A sample Makefile
    OBJS_PATH = /home/dkumar/libtsnnls-2.3.3/tsnnls/
    C_INCLUDE_PATH  = -I/home/dkumar/libtsnnls-2.3.3/ -I/home/dkumar/libtsnnls-2.3.3/tsnnls/  -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic/
    CPATH  = -I/home/dkumar/libtsnnls-2.3.3/ -I/home/dkumar/libtsnnls-2.3.3/tsnnls/  -I/home/dkumar/libtsnnls-2.3.3/tsnnls/taucs_basic/
    # Here is a simple Make Macro.
    LINK_TARGET     = tsnnls_test_DKU
    OBJS_LOC    = tsnnls_test_DKU.o
    # Here is a Make Macro that uses the backslash to extend to multiple lines.
    OBJS =  libtsnnls_la-taucs_malloc.o libtsnnls_la-taucs_ccs_order.o \
    libtsnnls_la-taucs_ccs_ops.o libtsnnls_la-taucs_vec_base.o \
    libtsnnls_la-taucs_complex.o libtsnnls_la-colamd.o \
    libtsnnls_la-amdbar.o libtsnnls_la-amdexa.o \
    libtsnnls_la-amdtru.o libtsnnls_la-genmmd.o \
    libtsnnls_la-taucs_timer.o libtsnnls_la-taucs_sn_llt.o \
    libtsnnls_la-taucs_ccs_base.o libtsnnls_la-tlsqr.o \
    libtsnnls_la-tsnnls.o libtsnnls_la-lsqr.o   
    ## adding "$(OBJS_PATH)" to each word in "$(OBJS)"
    # which in our case is basically to add the same folder in front of all "*.o" object files.
    OBJS2 = $(addprefix $(OBJS_PATH)/, $(OBJS)) 
    # OBJS_LOC is in current working directory,
    OBJS_ALL = $(OBJS2) \
    $(OBJS_LOC)
    ## DKU IS COPING THIS FROM ORIGINAL MAKEFILE THAT ARE GENERATED USING /home/dkumar/libtsnnls-2.3.3/tsnnls/MAKEFILE.AM
    RANLIB = ranlib
    STATICLIB= /usr/local/lib/taucs_full/lib/linux/libtaucs.a 
    tsnnls_test_LDADD = $(LDADD)
    LIBS = -largtable2 -llapack -lblas -lquadmath -lm
    REBUILDABLES = $(OBJS_LOC) $(LINK_TARGET) 
    all : $(LINK_TARGET)
    echo All done
    clean : 
    rm -f $(REBUILDABLES)   
    echo Clean done
    # Here is a Rule that uses some built-in Make Macros in its command:
    $(LINK_TARGET) : $(OBJS_ALL)   $(tsnnls_test_LDADD) $(LIBS)  $(STATICLIB)
    gcc -g -o [email protected] $^

Dejar respuesta

Please enter your comment!
Please enter your name here