2010-03-02 11 views
42

¿Cuál es una buena estructura de directorios para proyectos mayores de C++ que usan Makefile?¿Cuál es una buena estructura de directorios para proyectos mayores de C++ que usan Makefile?

Así es como mi estructura de directorios se ve en la actualidad

lib/ (class implementations *.cpp) 
include/ (class definitions *.h) 
tests/ (main.cpp for quick tests) 

Ahora, no estoy seguro de cómo mi Makefile debe ser similar ... no parece funcionar cuando los archivos .cpp y Los archivos .h no están en el mismo directorio. ¿Podría alguien señalarme una estructura de directorio común con un archivo Makefile que lo acompañe para que no reinvente la rueda?

+0

¿Tiene un Makefile actualmente? Si es así, puede considerar publicarlo para obtener retroalimentación específica. –

+0

use el comando Make VPATH = ../lib: ./ include hará que el encabezado esté disponible en su directorio de pruebas –

Respuesta

51

Separar .cpp del archivo .h no siempre es una buena solución. En general, los separé a ambos cuando se usa como biblioteca (encabezado público en incluir y encabezado privado con el código fuente).

Si es una biblioteca, esta estructura está bien.

lib/ (class implementations *.cpp .h) 
include/ (class definitions *.h) <- Only those to be installed in your system 
tests/ (main.cpp for quick tests) 
doc/ (doxygen or any kind of documentation) 

Si se trata de una aplicación

src/ (source for the application) 
lib/ (source for the application library *.cpp *.hpp) 
include/ (interface for the library *.h) 
tests/ (main.cpp for quick tests) <- use cppunit for this part 
doc/ (doxygen or any kind of documentation) 

Use la opción -I $ (PROJECT_BASE)/include para especificar la ruta de inclusión para la compilación

Si se trata de un gran proyecto, puede ser bueno usar la herramienta como autoconf/automake o cmake para construir todo. Facilitará el desarrollo.

+4

No lo entiendo. ¿Cuál es la diferencia entre 'src' y' lib'? – feeela

+1

Cuando una aplicación es demasiado grande, desea separar su programa en un módulo diferente. Módulo que puede ser independiente y puede reutilizarlo en otra aplicación. Entonces podrías escribirlo así lib/LibraryForLogging, lib/LibraryForDatabase etc ... Es más fácil de administrar que si estuviera mezclado con todo el código fuente. – Phong

+0

Esto parece una buena manera de hacerlo, pero ¿qué pasa con las carpetas de salida (archivos creados)? Digamos que quiero construir una biblioteca (sin instalarla), ¿en qué carpeta debo ponerla? – gromit190

6

No existe una "buena estructura de directorios". Elija una estructura con la que se sienta cómodo y adhiérase a ella. A algunos les gusta colocar los archivos de origen (encabezados y archivos de implementación) en un directorio src/, por lo que el directorio raíz del proyecto no tiene más que un archivo MAKE, un LÉAME y poco más. Algunos, como la colocación de librerías de apoyo bajo un directorio lib/, unittests bajo test/ o src/test/, la documentación bajo doc/ etc.

todavía tengo que escuchar a nadie dividir archivos de cabecera y los archivos de implementación en dos directorios distintos sin embargo. Personalmente, no me gusta mucho dividir archivos en directorios. Normalmente coloco toda mi fuente en un solo directorio y toda la documentación en otro directorio. Si confío en buenas herramientas de búsqueda de todos modos, no hay necesidad de una estructura de directorios compleja.

make puede hacer frente al tipo de estructura en la que el archivo MAKE reside en un directorio diferente de la fuente. Lo único es que invocará las reglas desde el directorio del archivo MAKE: los compiladores generalmente no tienen problemas para compilar el origen que está en algún subdirectorio. No tiene que especificar rutas relativas en su #include s; simplemente especifique la ruta de inclusión con indicadores del compilador (indicador -I de gcc, etc.).

+5

y 'bin /' para los ejecutables ... :) – Lipis

12

Si tiene muchos archivos fuente, también puede ser una buena idea subdividir aún más su directorio fuente. Por ejemplo, un subdirectorio para la funcionalidad principal de la aplicación, una para la interfaz gráfica de usuario, etc.

src/core 
src/database 
src/effects 
src/gui 
... 

Si lo hace, también le obliga a evitar relaciones que no sean necesarios entre los "módulos", lo cual es un requisito previo para agradable y reutilizable código.

12

No hay una estructura de directorios específica o requerida.

Puede configurarlo de todos modos que desee. Tu problema es simple de resolver. Simplemente indique a Makefile que busque subdirectorios o que coloque objetos compilados en subdirectorios en lugar de usar solo el directorio actual.

Usted sólo tiene que utilizar en caminos Makefile:

%.o : %.cpp 

reemplazar con

bin/%.o : %.cpp 

Por lo tanto, se comprobará si el archivo binario en el directorio bin existe y así sucesivamente, se puede aplicar la misma a lugares donde se compilan los archivos

Hay formas de agregar/quitar/modificar rutas de archivos fuente y objeto.

Tenga una mirada en gnu make manual, concretamente en la sección 8.3 Funciones para nombres de archivo, y la anterior que 8.2 Funciones de cadena de sustitución y Análisis.

Puede hacer cosas como:

obtener una lista de los objetos de la lista de archivos de origen en el directorio actual:

OBJ  = $(patsubst %.cpp, %.o, $(wildcard *.cpp)) 

Salida:

Application.o Market.o ordermatch.o 

Si los objetos binarios están en el subdirectorio bin pero el código fuente está en el directorio actual, puede aplicar el prefijo bin a los archivos de objetos generados:

OBJ  = $(addprefix bin/,$(patsubst %.cpp, %.o, $(wildcard *.cpp))) 

Salida:

bin/Application.o bin/Market.o bin/ordermatch.o 

Y así sucesivamente.

Cuestiones relacionadas