2009-10-20 18 views
5

Los __FILE__ y __LINE__ macros Se construye en la C pre-procesador, y con frecuencia se utilizan para la impresión de salida de depuración con nombres de archivo y los números de línea. Necesito algo similar, pero con solo el nombre del directorio al final de la ruta. Por ejemplo, si mi código está en: /home/davidc/some/path/to/some/code/foo/bar Necesito una macro que simplemente me dará "barra", si el código está en/home/davidc/some/path/to/some/code/foo/bee entonces lo necesito para darme "abeja".¿Cómo escribo un coste por __DIR__ macro, similar a __FILE__

¿Alguna idea? (por cierto, esto es para una aplicación C++).

Actualización: para ser claros, busco una macro que me dé una cadena que contenga el nombre del directorio en tiempo de compilación, no quiero hacer ningún procesamiento de cadenas en tiempo de ejecución.

Respuesta

6

Si está usando GNU make para construir su proyecto, entonces usted podría ser capaz de hacer algo como esto:

%.o: %.cpp 
    $(CC) $(CFLAGS) -D__DIR__="$(strip $(lastword $(subst /, , $(dir $(abspath $<)))))" -c $< -o [email protected] 

Eso tiene que ser sobre el más horrible de Dios cosa que he pensado hacer en un Makefile en bastante tiempo. No creo que encuentres una forma rápida o limpia de hacerlo dentro de los límites del compilador, así buscaría formas inteligentes de insertar la información en el proceso de compilación.

Buena suerte.

+0

D'oh, me ganaste por un minuto, estaba haciendo exactamente lo mismo. No funciona si el último directorio tiene espacios, pero de lo contrario es una solución perfecta. Y créeme, he visto * mucho * peores monstruosidades en Makefiles antes. –

+0

@ Adam: Solo tuve que hacer algunas _fixups_ para resolver los números de versión comenzando con los ceros esta noche. Pasar de 07.64 a 08.01 nos causó mucha pena innecesaria. –

+0

Estoy usando CMake, así que debería ser capaz de hacer esto. ¡Gracias! –

4

No hay una macro incorporada para eso, pero obviamente puede escribir su propia rutina de análisis que toma un archivo y arranca el nombre del directorio para un nombre de archivo completo. Vamos a llamar a esta función:

extern std::string parseLastDir (const char *path); 

entonces usted puede hacer una macro como esta:

#define __DIR__ parseLastDir (__FILE__) 

que tipo de comportarse como lo que quiere (le da un std :: string en lugar de un char * por lo que la limpieza es mejor definido) con la semántica pertinentes (sus resultados depende del archivo en el que la invoca, por lo que siempre se sale con el directorio correcto.)

+0

Lo que pasa es que quiero que el 'parseLastDir' tenga lugar en tiempo de compilación (No hay razón para que no pueda, ya que __FILE__ está predeterminado). Estaba pensando que quizás algo en el boost :: mpl o alguna otra metaprogramación de plantillas hacky dentro de una macro podría permitirme hacerlo ... Es para una aplicación más bien crítica para el rendimiento, y no quiero perder el tiempo haciendo series innecesarias procesamiento en tiempo de ejecución. –

+0

woops, se olvidó de marcar que debería ser \ __ FILE__, no __FILE__ –

+1

El problema es con el tiempo de compilación de acceso a los literales de cadena; eso no es posible ahora. Sin embargo, parece que tendremos el procesamiento de cadenas en tiempo de compilación en C++ 1x. –

2

lo que queremos es algo similar al UNIX

__BASE_FILE__ 

Eche un vistazo alrededor de http://theory.uwinnipeg.ca/localfiles/infofiles/gcc/cpp_13.html para él. Espero que esto ayude.

EDIT: Intento de dos

Cómo sobre el uso del comando #line preprocesador. Puede usarlo para cambiar la variable de nombre de archivo también como puede ver aquí: http://www.cppreference.com/wiki/preprocessor/line

+1

Cierre, pero no cigarro. Eso le da el nombre de archivo/ruta como pasó a g ++, por lo que corta algunas de las partes anteriores de la ruta, pero no me da el último directorio como quiero (dado que mi código está en un grupo de subdirectorios) , así que ahora acabo de obtener foo/bar en lugar de/home/davidc/some/path/to/some/code/foo/bar, cerrar, pero desafortunadamente sigue siendo el mismo problema. –

+0

Maldición, muy cerca. Voy a seguir buscando. –

2

Dependiendo de su compilador/cómo se construye su software, puede declarar que una macro es la ruta actual o cualquier ruta al compilar.

gcc -D__DIR__=/usr/src/test/ test.c 

Nunca he usado el compilador de MS pero sé que hay una opción similar para ICC también.

gcc manpage

+0

Gracias, pero eso no es lo que estoy buscando. Estoy compilando un gran proyecto con cientos de archivos en diferentes directorios, la idea es que cada archivo pueda #incluir esta macro, y devolverá el nombre del directorio correspondiente a su propia ubicación de archivo fuente, no quiero 'hard- código 'el camino a cualquier lugar en particular. –

+0

oh y sí, estoy usando g ++ en Linux –

0

Cómo cambiar su archivo MAKE/sistema de construcción de manera que para .../bar/file.cc la línea de compilación incluirá -D__DIR__ bar. Debería ser más fácil ...

Cuestiones relacionadas