2010-10-13 10 views
5

He leído sobre el uso de "Custom.Before.Microsoft.Common.targets" y "Custom.After.Microsoft.Common.targets "para ejecutar un objetivo personalizado antes/después de cada compilación del proyecto y me gustaría utilizar esta técnica para cambiar la información de la versión mientras desarrollamos nuestro servidor de compilación TeamCity.MSBuild: Custom.After.Microsoft.Common.targets para proyectos nativos de C++ en VS2010

El problema es que, aunque funciona para proyectos C#, no parece funcionar para proyectos nativos de C++.

Después de buscar en el archivo Microsoft.Cpp.targets descubrí que para los proyectos nativos de C++ esto parece implementarse configurando $ (ForceImportBeforeCppTargets) y $ (ForceImportAfterCppTargets).

Parece que no puedo encontrar una sola información en la web sobre esta técnica para las aplicaciones nativas de C++, así que estoy preguntando si estoy mirando en la dirección correcta o no.

Cualquier ayuda es apreciada.

+0

¿Por qué no utiliza los eventos Build Build + Pre-Build Event y Post-Build? –

+0

No estamos utilizando los eventos de compilación pre/post porque siempre se ejecutan, queremos algo que solo se ejecute cuando se construye en el servidor de compilación y también se obtiene la información de la versión (y otra información) del servidor de compilación. Además, no queremos depender de si un desarrollador olvida o no poner algo en la configuración de este evento, tiene que ser automático y 'Custom.Before.Microsoft.Common.targets' lo proporciona, pero aparentemente no para el código nativo. – Halt

Respuesta

10

Para los proyectos de VC++ es un poco diferente. Define un archivo para importar al principio o al final del proyecto. Para utilizar este enfoque, debe definir valores para las propiedades ForceImportBeforeCppTargets o ForceImportAfterCppTargets. Por ejemplo, si desea que se incluya un archivo al comienzo del proyecto, puede pasar el valor en la línea de comando. Por ejemplo, acabo de crear un proyecto ficticio de VC++ llamado CppTets01. Luego creé los dos archivos de muestra a continuación.

Before.proj

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 


    <Target Name="CustomTargetInBefore" AfterTargets="Build"> 
    <Message Text="From CustomTargetInBefore" Importance="high"/> 
    </Target> 

</Project> 

After.proj

<?xml version="1.0" encoding="utf-8"?> 
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 

    <Target Name="CustomTargetInAfter" AfterTargets="Build"> 
    <Message Text="From CustomTargetInAfter" Importance="high"/> 
    </Target> 

</Project> 

Luego ejecuta el siguiente comando:

msbuild CppTest01.vcxproj 
    /p:ForceImportBeforeCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\Before.proj"; 
    ForceImportAfterCppTargets="C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\After.proj" 

El resultado fue C: \ Temp_NET \ desechable \ CppTest01 \ CppTest01> msbuild CppTest01.vcxproj/p: ForceImportBeforeCppTargets = "C: \ Temp_NET \ desechable \ CppTest01 \ C ppTest01 \ Before.proj"; ForceImportAfterCppTargets = "C: \ Temp_NET \ desechable \ CppTest01 \ CppTest01 \ After.proj"

Microsoft (R) Build Engine Version 4.0.30319.1 
[Microsoft .NET Framework, Version 4.0.30319.1] 
Copyright (C) Microsoft Corporation 2007. All rights reserved. 

Build started 10/18/2010 8:32:55 AM. 
Project "C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\CppTest01.vcxproj" on node 1 (default targets). 
InitializeBuildStatus: 
    Creating "Debug\CppTest01.unsuccessfulbuild" because "AlwaysCreate" was specified. 
ClCompile: 
    All outputs are up-to-date. 
    All outputs are up-to-date. 
ManifestResourceCompile: 
    All outputs are up-to-date. 
Link: 
    All outputs are up-to-date. 
Manifest: 
    All outputs are up-to-date. 
FinalizeBuildStatus: 
    Deleting file "Debug\CppTest01.unsuccessfulbuild". 
    Touching "Debug\CppTest01.lastbuildstate". 
CustomTargetInBefore: 
    From CustomTargetInBefore 
CustomTargetInAfter: 
    From CustomTargetInAfter 
Done Building Project "C:\Temp\_NET\ThrowAway\CppTest01\CppTest01\CppTest01.vcxproj" (default targets). 


Build succeeded. 
    0 Warning(s) 
    0 Error(s) 

Time Elapsed 00:00:00.21 

Como se puede ver en la salida los objetivos fueron inyectados con éxito en el proceso de construcción. Si desea volver a relacionar esto con Custom.Before.Microsoft.Common.targets y Custom.Before.Microsoft.Common.targets, debe saber que la técnica utilizada allí es un poco diferente. Específicamente, si crea esos archivos, se importan automáticamente en cada proyecto C#/VB.NET. En este caso, debe establecer esta propiedad. Usted realmente tiene dos opciones aquí:

  1. Puede establecer esta propiedad como una variable de entorno
  2. Se puede utilizar otra técnica, ImportBefore & ImportAfter que es específico para VC++

Para # 1 déjame explicarte un poco.En MSBuild cuando accede a una propiedad con la sintaxis $ (PROPNAME) entonces si una propiedad con el nombre PROPNAME no existe MSBuild se verá en las variables de entorno para ver si existe un valor tal, si lo hace, entonces se devuelve ese valor . Así que si usted tiene un servidor de compilación en la que desea incluir un archivo para cada VC++ construir, a continuación, sólo crear esas propiedades como variables de entorno. Ahora para la otra técnica.

ImportBefore/ImportAfter En VC++ se introduce un nuevo concepto. En Microsoft.Cpp.Win32.targets, puede ver la declaración en la parte superior del archivo .targets.

<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportBefore\*.targets" 
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportBefore')" /> 

entonces hay una hacia la parte inferior

<Import Project="$(VCTargetsPath)\Platforms\Win32\ImportAfter\*.targets" 
Condition="Exists('$(VCTargetsPath)\Platforms\Win32\ImportAfter')" /> 

Existe una declaración de importación similar para las otras plataformas de destino también. Eche un vistazo a los archivos en %ProgramFiles32%\MSBuild\Microsoft.Cpp\v4.0\Platforms\ para obtener los nombres específicos.

Con esta técnica, si desea importar un archivo, simplemente cree un archivo que finalice con .targets y colóquelo en la carpeta correspondiente. La ventaja de esto es que se importará en cada VC++ construir para esa plataforma, y ​​que puede crear muchos archivos diferentes. El inconveniente es que debe colocarlos en esas carpetas específicas. Esa es la principal diferencia entre ambas técnicas. Con esta primera técnica puede especificar la ubicación del archivo a través de la propiedad y no se incluye automáticamente para cada compilación, pero no es posible cambiar la ubicación

+0

Perdón por eso, estaba dando la información incorrecta. Miré esto un poco más profundo y he corregido el problema. He actualizado mi respuesta para reflejar mis hallazgos. –

+0

Gracias, excelente respuesta, que confirme lo que empecé a sospechar. Ahora sé que estoy en el camino correcto. – Halt

+0

Bien, disculpe por el descarrilamiento inicial. –

3

También puede agregar contenido del proyecto en uno de los archivos *.props de directorio de %LOCALAPPDATA%\Microsoft\MSBuild\v4.0\

Haz mismo efecto.

Cuestiones relacionadas