2011-09-21 16 views
5

¿Cuál es el método SCONS adecuado para actualizar el contenido de un archivo que forma parte de la compilación?Cómo hacer que SCONS actualice el contenido de un archivo utilizado en una compilación

Uso SCONS para construir un proyecto bastante grande. Pero por el bien de una simple pregunta, asuma que tiene este aspecto:

env.Program("foo", ["foo.c", "version.c"]) 

Bajo ciertas condiciones de construcción, es necesario actualizar el contenido de uno de los archivos de CPP en la construcción con la nueva información - información sobre la versión realidad. En el ejemplo anterior, necesitaría modificar el contenido de "version.c". Pensé que podría hacerlo bastante bien con el siguiente ejemplo:

env.Command(target="version.c", source=[], action=PythonFunctionToUpdateContents) 
env.Program("foo", ["foo.c", "version.c"]) 

Los PythonFunctionToUpdateContents usarían objetivo [0] como el nombre del archivo, abrirlo, buscar algún texto específico, cambiarlo, escribir los cambios volver al mismo archivo. Lamentablemente, la muestra anterior no funciona. SCONS elimina automáticamente un archivo de destino antes de compilarlo, por lo que mi archivo "version.c" se eliminó antes de que pudiera actualizarse.

Intenté configurar el destino y la fuente en el mismo archivo en la llamada env.Command(), pero eso solo crea un ciclo de dependencia.

Sé que podría resolver esto haciendo que SCONS genere el archivo ENTERO version.c, pero eso no es adecuado ya que version.c contiene muchos otros códigos que pueden cambiar como parte del desarrollo normal.

Respuesta

5

La forma habitual de hacerlo es tener un "version.c.in" o "version-in.c" o como quiera llamarlo. Modifique eso y déle salida a version.c. Agregaría el archivo "in" a su sistema de control de versiones, mientras que el archivo version.c no estaría allí. Así, el resultado de todo esto se vería como sigue:

env.Command(target="version.c", source="version-in.c", 
      action=PythonFunctionToUpdateContents) 
env.Program("foo", ["foo.c", "version.c"]) 

Esto se aplica a otros sistemas de construcción también - por lo general es una mala idea tener un archivo de entrada también puede ser un archivo de salida. Es mucho mejor usar un archivo intermedio para realizar el trabajo.

+0

El ejemplo era demasiado simple, quizás. Mi llamada "env.Program()" es realmente una llamada externa a un proceso de compilación de un tercero que no está basado en SCONS. Así que estoy tratando de modificar el archivo antes de iniciar su proceso. Estoy de acuerdo - modificar el archivo en su lugar no es una buena idea. Pero no tengo control sobre esa parte del proceso de compilación. –

+1

Sin embargo, se aplica el mismo principio: tiene un archivo que controla que es la plantilla de la entrada al proceso de compilación externo. Usted crea una copia modificada de su plantilla en el directorio correspondiente antes de iniciar el proceso externo. De lo contrario, siempre podría crear una copia completa de la compilación de terceros (podría no ser práctico) y modificar los archivos en esa copia. – richq

5

Esta respuesta es un poco tarde a la fiesta, pero aquí está de todos modos:

Debe utilizar env.Precious("version.c"). Esto evita que el archivo se elimine antes de ser construido.

Probablemente también desee utilizar env.NoClean("version.c") para que no se borre durante una limpieza.

Usted PODRÍA usar env.SideEffect tal vez, pero parece que tiene un par de cosas raras. Me dijeron en la lista de correo que generalmente no usaba esa.

+0

Actualización para cualquiera que lea esta respuesta: 'env.SideEffect' se debe usar para cuando varios constructores salgan al mismo archivo (como tal vez un registro, un archivo binario que contenga un contador, etc.); No creo que ayudaría en esta situación. El emparejamiento de 'Precious' y' NoClean' sería la solución "correcta". –

Cuestiones relacionadas