El objetivo de compilación personalizado de Delphi XE siempre está deshabilitado

177

Creé un .targetsarchivo MSBuild personalizado que incluí en un proyecto Delphi XE a través del IDE y lo habilité desde el menú contextual del Administrador de proyectos. Aunque el archivo se valida, siempre se desactiva después de volver a guardar el archivo del proyecto.

Aquí hay una versión simplificada del archivo de objetivos, llamada Custom.targets.

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <Target Name="Hello">
    <Message Text="Hello from custom target"/>
  </Target>
</Project>

Como archivo independiente, esto funciona como se esperaba: escribiendo ...

MSBuild Custom.target /t:Hello

... en la línea de comando da el mensaje esperado.

Agregar Custom.targetsa un proyecto de Delphi a través del IDE muestra el archivo en el Administrador de proyectos como se esperaba, y el .dprojarchivo ahora contiene la línea ...

<TargetsFile Include="Custom.targets"/>

Hice clic derecho en el archivo en el Administrador de proyectos del IDE y seleccioné Enable. Pero cuando se construye el proyecto, aparece la Buildventana de mensaje:

[Advertencia de MSBuild] Custom.targets (1): Ignorando la importación deshabilitada: PathToProjectSource\\Custom.targets

Hacer clic con el botón derecho nuevamente en Project Manager aún muestra la Enableopción en lugar de la esperadaDisable .

En la línea de comando MSBuild ProjectName.dproj /t:Hello también falla.

He intentado hackear el .dprojarchivo para agregar la línea ...

<Import Project="Custom.targets"/>

Escribir MSBuild ProjectName.dproj /t:Helloahora funciona. Pero la próxima vez que guarde el archivo de proyecto del IDE, el<Import> declaración se elimina.

Alguien tiene alguna idea de lo que va mal, por favor?

delphidabbler
fuente
10
En su ejemplo de uso de msbuild desde la línea de comandos, muestra Custom.target mientras que en cualquier otro lugar usa Custom.targets . Cual es
Kenneth Cochran
44
Buen lugar: no lo había notado a pesar de mirar mucho el código. No puedo llegar a una máquina con Delphi en ella durante unos días (¡en el hospital!), Pero intentaré el código usando "objetivo" u "objetivos" consistentemente cuando pueda.
delphidabbler
66
No es un usuario de Delphi, pero de acuerdo con esto Todos los archivos .targets deben contener scripts válidos de MSBuild sin errores. Si el archivo tiene algún error, se le notifica y, si el proyecto hace referencia al archivo .targets no válido, se desactiva y no se puede volver a habilitar hasta que se corrijan los errores. Puede valer la pena verificar que todo esté correcto, ya que eso explica los síntomas que está teniendo.
Daniel Morritt
Desafortunadamente, en XE7 no puedo reproducir su problema, todo parece funcionar como se esperaba: compilando desde la línea de comandos con /t:Helloel IDE con un clic derecho en el Administrador de proyectos - Objetivos - Hola. He agregado Custom.targetsal proyecto haciendo clic derecho en el Administrador de proyectos - Agregar - (buscó el archivo). La ruta es el mismo directorio que el archivo .dproj.
Ondrej Kelle

Respuestas:

1

Delphi genera todo el contenido de dproj y esta importación personalizada siempre se eliminará.

Puede escribir sus propios archivos xbu de msbuild, pero el dproj pertenece a Delphi.

A menos que tenga un código fuente o esté dispuesto a parchear la idea, no puede hacerlo.

Si realmente desea una forma xml flexible para construir proyectos de Delphi y crear objetivos en abundancia, intente querer o querer vnext (mi tenedor en bitbucket)

Warren P
fuente
1

Incluiría el archivo de destino manualmente y lo construiría externamente usando MSBuild en lugar de desde el IDE, porque al compilar desde el IDE es un poco complicado saber qué configuración y destino ha aplicado (¿se hizo clic en el proyecto? O el de objetivo habilitado: no obtiene ninguna pista visual de que un objetivo personalizado está habilitado).

Por lo general, lo hago antes Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets"para que no se muestren en el IDE (existen, pero están ocultos para los desarrolladores).

Por ejemplo, mis proyectos Delphi XE4 terminan con:

    <Import Project="..\BuildServer.Targets"/>
    <Import Project="$(BDS)\Bin\CodeGear.Delphi.Targets" Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')"/>
    <Import Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj" Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')"/>
</Project>

Mi archivo .targets define un "PropertyGroup" y un "Target" personalizados con una condición, por lo que solo se aplicarán cuando se llamen desde MSBuild:

  <PropertyGroup  Condition="'$(Config)'=='CustomConfig'">
    <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
    ...
  </PropertyGroup>
  <Target Name="DisplayProjectInfo">
    <Message Text="Project File Name = $(MSBuildProjectFile)"/>
    <Message Text="Version = $(VerInfo_Keys)"/>
    <Message Text="OutputDir = $(DCC_ExeOutput)"/>
  </Target>
  <Target Name="CustomTarget" Condition="'$(Config)'=='CustomConfig'">
  <MSBuild Projects="$(MSBuildProjectFile)" Targets="Clean" />
    <MSBuild Projects="$(MSBuildProjectFile)" Targets="Build" />
    <CallTarget Targets="DisplayProjectInfo"/>
  </Target>

Luego compílalo con:

msbuild /t:CustomTarget /p:config=CustomConfig poject.dproj

El uso de este enfoque le permite personalizar los objetivos de compilación para asegurarse de que cada aplicación obtenga la configuración correcta sin verse afectada por los cambios realizados por nadie.

Fran
fuente