2010-05-07 19 views
6

En resumen: Quiero generar dos árboles de fuentes diferentes a los actuales, basados ​​solo en una macro de preprocesador definida y otra indefinida, sin otros cambios en la fuente.Separa las ramas específicas #ifdef

Si usted está interesado, aquí está mi historia ...

Al principio, mi código estaba limpio. Luego hicimos un nuevo producto, y sí, fue mejor. Pero el código solo vio los mismos dispositivos periféricos, por lo que pudimos mantener el mismo código.

Bueno, casi.

Había una pequeña condición que necesita ser cambiado, por lo que añade:

#if defined(PRODUCT_A) 
condition = checkCat(); 
#elif defined(PRODUCT_B) 
condition = checkCat() && checkHat(); 
#endif 

... a uno y sólo un archivo de origen. En general todos los archivos de código incluyen en este archivo de cabecera, que tenía:

#if !(defined(PRODUCT_A)||defined(PRODUCT_B)) 
#error "Don't make me replace you with a small shell script. RTFM." 
#endif 

... para que la gente no podía compilarlo a menos que definen explícitamente un tipo de producto.

Todo estaba bien. Oh ... excepto que se hicieron modificaciones, se cambiaron los componentes, y dado que el nuevo hardware funcionó mejor, pudimos reescribir significativamente los sistemas de control. Ahora, cuando miro sobre la faz del código, hay más de 60 áreas separadas o bien delineados por:

#ifdef PRODUCT_A 
... 
#else 
... 
#endif 

... o el mismo, pero para PRODUCT_B. O incluso:

#if defined(PRODUCT_A) 
... 
#elif defined(PRODUCT_B) 
... 
#endif 

Y, por supuesto, a veces la cordura tomaron unas vacaciones más largas y:

#ifdef PRODUCT_A 
... 
#endif 
#ifdef PRODUCT_B 
... 
#endif 

Estas condiciones se envuelven en cualquier lugar de uno a doscientas líneas (se podría pensar que el último podría hacerse cambiando los archivos de encabezado, pero los nombres de las funciones deben ser los mismos).

Esto es una locura. Sería mejor mantener dos ramas separadas basadas en productos en el repositorio de origen y portar los cambios comunes. Me doy cuenta de esto ahora.

¿Hay algo que pueda generar los dos árboles de fuentes diferentes que necesito, basándose únicamente en PRODUCT_A ser definido y PRODUCT_B está sin definir (y viceversa), sin tocar cualquier otra cosa (es decir. Sin la inclusión de cabecera, sin macro expansión, etc.)?

+2

Esto es lo ramificación es para. – rlbond

+0

Bueno, al principio parecía una tontería crear una nueva rama de un árbol que contenga 72 archivos fuente y encabezado solo para una condición diferente. Pensamos que los cambios comunes a ambos productos serían mucho más comunes, y con ramas separadas tendríamos que cambiar los puertos todo el tiempo. La realidad, obviamente, resultó ser diferente. – detly

+0

El código fuente es como su habitación, tiene que limpiarlo periódicamente. De lo contrario, terminas con un gran desastre apestoso. Se hicieron sucursales para lidiar con este tipo de complejidad. La mejor parte es que combinar correcciones de errores en las sucursales es trivial en un buen SCM. –

Respuesta

6

Creo que Coan hará lo que está buscando. Desde el enlace:

Dada una configuración y un poco de código fuente, Coan puede contestar una serie de preguntas acerca de cómo aparecería el código fuente para el/C preprocesador de C++ si esa configuración de símbolos se había aplicado de antemano.

Y también: código

Fuente re-escrito por Coan no es preprocesado código como producido por el preprocesador C.Todavía contiene comentarios, macro-invocaciones y # -directivas. Sigue siendo un código fuente, pero simplificado de acuerdo con la configuración elegida.

por lo que podría ejecutarlo dos veces, primero especificando el producto A y el producto B.

+0

Ojalá pudiera marcar esto dos veces. – detly

+0

Me alegro de poder ayudar. – Dusty

+0

Terminé haciendo un [PPA para Coan] (https://launchpad.net/~detly/+archive/ubuntu/coan) ya que lo uso mucho. – detly

Cuestiones relacionadas