Compartir a través de


Compilaciones incrementales

Las compilaciones incrementales de MSBuild son compilaciones que se optimizan para que no se ejecuten los destinos que tienen archivos de salida que están actualizados con respecto a sus archivos de entrada correspondientes.

Un elemento de destino puede tener un atributo Inputs, que indica qué elementos espera el destino como entrada y un atributo Outputs, que indica qué elementos genera como salida. MSBuild intenta encontrar una asignación uno a uno entre los valores de estos atributos. Si existe dicha asignación, MSBuild compara la marca de tiempo de cada elemento de entrada con la marca de tiempo de su elemento de salida correspondiente. Los archivos de salida que no tienen una asignación uno a uno se comparan con todos los archivos de entrada. Un elemento se considera up-to-date si su archivo de salida es la misma edad o más reciente que su archivo de entrada o archivos.

Nota

Cuando MSBuild evalúa los archivos de entrada, solo se tiene en cuenta el contenido de la lista en la ejecución actual. Los cambios en la lista de la última compilación no hacen automáticamente que un objetivo esté desactualizado.

Si todos los elementos de salida están en el estado up-to-date, MSBuild omite el objetivo. Esta compilación incremental del destino puede mejorar significativamente la velocidad de compilación. Si solo algunos archivos están up-to-date, MSBuild ejecuta el destino, pero omite los elementos up-to-date y, por lo tanto, trae todos los elementos up-to-date. Este proceso se conoce como compilación incremental parcial.

Las asignaciones de uno a uno solo se pueden generar haciendo que el atributo Outputs sea una transformación del atributo Inputs. Para obtener más información, consulte Transformaciones de MSBuild.

Tenga en cuenta el siguiente objetivo:

<Target Name="Backup" Inputs="@(Compile)"
    Outputs="@(Compile->'$(BackupFolder)%(Identity).bak')">
    <Copy SourceFiles="@(Compile)" DestinationFiles=
        "@(Compile->'$(BackupFolder)%(Identity).bak')" />
</Target>

El conjunto de archivos representados por el tipo de elemento Compile se copia en un directorio de copia de seguridad. Los archivos de copia de seguridad tienen la extensión de nombre de archivo .bak. Si los archivos representados por el tipo de elemento de Compile o los archivos de copia de seguridad correspondientes, no se eliminan ni modifican después de ejecutar el destino de Backup, el destino de Backup se omite en compilaciones posteriores.

Inferencia de salida

MSBuild compara los atributos Inputs y Outputs de un destino para determinar si el destino debe ejecutarse. Idealmente, el conjunto de archivos que existe después de completar una compilación incremental debe permanecer igual si se ejecutan o no los destinos asociados. Dado que las propiedades y los elementos que las tareas crean o modifican pueden afectar a la compilación, MSBuild debe deducir sus valores incluso si se omite el destino que les afecta. Este proceso se conoce como inferencia de salida.

Hay tres casos:

  • El destino tiene un atributo Condition que se evalúa como false. En este caso, el destino no se ejecuta y no tiene ningún efecto en la compilación.

  • El destino tiene salidas sin actualizar y se ejecuta para actualizarlas.

  • El destino no tiene salidas sin actualizar y se omite. MSBuild evalúa el destino y realiza cambios en los elementos y las propiedades como si el destino se hubiera ejecutado.

Para admitir la compilación incremental, las tareas deben asegurarse de que el valor del atributo TaskParameter de cualquier elemento Output sea igual a un parámetro de entrada de tarea. Por ejemplo:

<CreateProperty Value="123">
    <Output PropertyName="Easy" TaskParameter="Value" />
</CreateProperty>

Este código crea la propiedad Easy, que tiene el valor 123 independientemente de si el destino se ejecuta o se omite.

A partir de MSBuild 3.5, la inferencia de salida se realiza automáticamente en los grupos de elementos y propiedades de un destino. Las tareas CreateItem no son necesarias en un objetivo y deben evitarse. Además, las tareas CreateProperty deben utilizarse en un destino solamente para determinar si se ha ejecutado un destino.

Antes de MSBuild 3.5, puede usar la tarea CreateItem.

Determinar si se ha ejecutado un destino

Debido a la inferencia de salida, debe examinar las propiedades y los elementos de un destino para determinar si se ha ejecutado. Para ello, agregue la tarea CreateProperty al destino y proporciónele un elemento Output cuyo valor de atributo TaskParameter sea ValueSetByTask. Por ejemplo:

<CreateProperty Value="true">
    <Output TaskParameter="ValueSetByTask" PropertyName="CompileRan" />
</CreateProperty>

Este código crea la propiedad CompileRan y le proporciona el valor true, pero solo si se ejecuta el destino. Si se omite el destino, no se crea CompileRan.