Skip to content

Instantly share code, notes, and snippets.

@nosami
Created May 20, 2018 10:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nosami/28987d4c36758eed6811443ca133064b to your computer and use it in GitHub Desktop.
Save nosami/28987d4c36758eed6811443ca133064b to your computer and use it in GitHub Desktop.
<!-- Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. -->
<!--
***********************************************************************************************
Microsoft.FSharp.Targets
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
created a backup copy. Incorrect changes to this file will make it
impossible to load or build your projects from the command-line or the IDE.
This file defines the steps in the standard build process specific for F# .NET projects.
For example, it contains the step that actually calls the F# compiler. The remainder
of the build process is defined in Microsoft.Common.targets, which is imported by
this file.
***********************************************************************************************
-->
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<MSBuildAllProjects>$(MSBuildAllProjects);$(MSBuildThisFileFullPath)</MSBuildAllProjects>
</PropertyGroup>
<UsingTask TaskName="Fsc" AssemblyFile="FSharp.Build.dll" />
<UsingTask TaskName="FSharpEmbedResourceText" AssemblyFile="FSharp.Build.dll" />
<UsingTask TaskName="FSharpEmbedResXSource" AssemblyFile="FSharp.Build.dll" />
<UsingTask TaskName="CreateFSharpManifestResourceName" AssemblyFile="FSharp.Build.dll" />
<UsingTask TaskName="WriteCodeFragment" AssemblyFile="FSharp.Build.dll" />
<PropertyGroup>
<ImportByWildcardBeforeMicrosoftFSharpTargets Condition="'$(ImportByWildcardBeforeMicrosoftFSharpTargets)' == ''">true</ImportByWildcardBeforeMicrosoftFSharpTargets>
<ImportByWildcardAfterMicrosoftFSharpTargets Condition="'$(ImportByWildcardAfterMicrosoftFSharpTargets)' == ''">true</ImportByWildcardAfterMicrosoftFSharpTargets>
</PropertyGroup>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore\*" Condition="'$(ImportByWildcardBeforeMicrosoftFSharpTargets)' == 'true' and exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportBefore')"/>
<PropertyGroup>
<DefaultLanguageSourceExtension>.fs</DefaultLanguageSourceExtension>
<Language>F#</Language>
<TargetRuntime>Managed</TargetRuntime>
<Tailcalls Condition="'$(Tailcalls)'==''">$(Optimize)</Tailcalls>
<FrameworkRegistryBase Condition="'$(TargetFrameworkIdentifier)'=='Silverlight'">Software\Microsoft\Microsoft SDKs\$(TargetFrameworkIdentifier)</FrameworkRegistryBase>
<!-- Visual studio requires a non-empty RootNamespace value for "Add New Item" to work. -->
<RootNamespace Condition="'$(RootNamespace)'==''">RootNamespace</RootNamespace>
<Actual32Bit Condition="'$(TargetFrameworkVersion)'=='v2.0' or '$(TargetFrameworkVersion)'=='v3.0' or '$(TargetFrameworkVersion)'=='v3.5' or '$(TargetFrameworkVersion)'=='v4.0'">false</Actual32Bit>
<Actual32Bit Condition="!('$(TargetFrameworkVersion)'=='v2.0' or '$(TargetFrameworkVersion)'=='v3.0' or '$(TargetFrameworkVersion)'=='v3.5' or '$(TargetFrameworkVersion)'=='v4.0')">$(Prefer32Bit)</Actual32Bit>
<!--
`/debug+` is produced based on `$(DebugSymols)`, which gets a default value of 'true' in
Microsoft.Common.CurrentVersion.targets, with a condition:
Condition=" '$(ConfigurationName)' == 'Debug' and '$(DebugSymbols)' == '' and '$(DebugType)'=='' "
But that file is imported later, so we cannot depend on the default value of `$(DebugSymbols)` or `$(ConfigurationName)`.
-->
<_ConfigurationNameTmp>$(ConfigurationName)</_ConfigurationNameTmp>
<_ConfigurationNameTmp Condition="'$(ConfigurationName)' == ''">$(Configuration)</_ConfigurationNameTmp>
<!-- _DebugFileExt is not an upstream msbuild feature yet -->
<_DebugFileExt>.pdb</_DebugFileExt>
<_DebugFileExt Condition="'$(FscDebugFileExt)' != ''">$(FscDebugFileExt)</_DebugFileExt>
<DebugType Condition="'$(OS)' != 'Windows_NT' And ('$(DebugSymbols)'=='True' or ('$(DebugSymbols)'=='' And '$(_ConfigurationNameTmp)'=='Debug'))">portable</DebugType>
<DebugType Condition="'$(FscDebugType)' != ''">$(FscDebugType)</DebugType>
</PropertyGroup>
<!--
The CreateManifestResourceNames target create the manifest resource names from the .RESX
files.
[IN]
@(EmbeddedResource) - The list of EmbeddedResource items that have been pre-processed to add metadata about resource type
Expected Metadata "Type" can either be "Resx" or "Non-Resx"
[OUT]
@(EmbeddedResource) - EmbeddedResource items with metadata
For F# applications the transformation is like:
Resources1.resx => Resources1 => Build into main assembly
SubFolder\Resources1.resx => SubFolder.Resources1 => Build into main assembly
Resources1.fr.resx => Resources1.fr => Build into satellite assembly
Resources1.notaculture.resx => Resources1.notaculture => Build into main assembly
For other project systems, this transformation may be different.
-->
<PropertyGroup>
<CreateManifestResourceNamesDependsOn></CreateManifestResourceNamesDependsOn>
</PropertyGroup>
<PropertyGroup>
<UsingXBuild>false</UsingXBuild>
<UsingXBuild Condition="'$(MSBuildAssemblyVersion)' == ''">true</UsingXBuild>
</PropertyGroup>
<Target
Name="CreateManifestResourceNames"
Condition="'@(EmbeddedResource)' != ''"
DependsOnTargets="$(CreateManifestResourceNamesDependsOn)"
>
<ItemGroup>
<_Temporary Remove="@(_Temporary)" />
</ItemGroup>
<!-- START XBUILD -->
<!-- This is the implementation of CreateManifestResourceNames which is compatible with the way -->
<!-- xbuild processes resource names -->
<CreateFSharpManifestResourceName
Condition="'@(ResxWithNoCulture)' != '' AND '$(UsingXBuild)' == 'true'"
UseStandardResourceNames="$(UseStandardResourceNames)"
ResourceFiles="@(ResxWithNoCulture)" RootNamespace="$(RootNamespace)">
<Output TaskParameter = "ManifestResourceNames" ItemName = "ManifestResourceWithNoCultureName" />
</CreateFSharpManifestResourceName>
<CreateFSharpManifestResourceName
Condition="'@(NonResxWithNoCulture)' != '' AND '$(UsingXBuild)' == 'true'"
UseStandardResourceNames="$(UseStandardResourceNames)"
ResourceFiles="@(NonResxWithNoCulture)" RootNamespace="$(RootNamespace)">
<Output TaskParameter = "ManifestResourceNames" ItemName = "ManifestNonResxWithNoCulture" />
</CreateFSharpManifestResourceName>
<CreateFSharpManifestResourceName
Condition="'@(ResxWithCulture)' != '' AND '$(UsingXBuild)' == 'true'"
UseStandardResourceNames="$(UseStandardResourceNames)"
ResourceFiles="@(ResxWithCulture)" RootNamespace="$(RootNamespace)">
<Output TaskParameter = "ManifestResourceNames" ItemName = "ManifestResourceWithCultureName" />
</CreateFSharpManifestResourceName>
<CreateFSharpManifestResourceName
Condition="'@(NonResxWithCulture)' != '' AND '$(UsingXBuild)' == 'true'"
UseStandardResourceNames="$(UseStandardResourceNames)"
ResourceFiles="@(NonResxWithCulture)" RootNamespace="$(RootNamespace)">
<Output TaskParameter = "ManifestResourceNames" ItemName = "ManifestNonResxWithCulture" />
</CreateFSharpManifestResourceName>
<!-- END XBUILD -->
<!-- START MSBUILD -->
<!-- This is the implementation of CreateManifestResourceNames which is compatible with the way -->
<!-- msbuild processes resource names -->
<!-- Create manifest names for culture and non-culture Resx files, and for non-culture Non-Resx resources -->
<CreateFSharpManifestResourceName
ResourceFiles="@(EmbeddedResource)"
RootNamespace="$(RootNamespace)"
UseStandardResourceNames="$(UseStandardResourceNames)"
Condition="'%(EmbeddedResource.ManifestResourceName)' == '' and ('%(EmbeddedResource.WithCulture)' == 'false' or '%(EmbeddedResource.Type)' == 'Resx') AND '$(UsingXBuild)' == 'false'">
<Output TaskParameter="ResourceFilesWithManifestResourceNames" ItemName="_Temporary" />
</CreateFSharpManifestResourceName>
<!-- Create manifest names for all culture non-resx resources -->
<CreateFSharpManifestResourceName
ResourceFiles="@(EmbeddedResource)"
RootNamespace="$(RootNamespace)"
UseStandardResourceNames="$(UseStandardResourceNames)"
PrependCultureAsDirectory="false"
Condition="'%(EmbeddedResource.ManifestResourceName)' == '' and '%(EmbeddedResource.WithCulture)' == 'true' and '%(EmbeddedResource.Type)' == 'Non-Resx' AND '$(UsingXBuild)' == 'false'">
<Output TaskParameter="ResourceFilesWithManifestResourceNames" ItemName="_Temporary" />
</CreateFSharpManifestResourceName>
<!-- END MSBUILD -->
<ItemGroup>
<EmbeddedResource Remove="@(EmbeddedResource)" Condition="'%(EmbeddedResource.ManifestResourceName)' == ''"/>
<EmbeddedResource Include="@(_Temporary)" />
<_Temporary Remove="@(_Temporary)" />
</ItemGroup>
</Target>
<ItemGroup>
<DocFileItem Include="$(DocumentationFile)" Condition="'$(DocumentationFile)'!=''"/>
</ItemGroup>
<ItemGroup Condition="'$(_DebugSymbolsProduced)' == 'true' and '$(PdbFile)' != ''">
<_DebugSymbolsIntermediatePathTemporary Include="$(PdbFile)"/>
<!-- Add any missing .pdb extension, as the compiler does -->
<_DebugSymbolsIntermediatePath Include="@(_DebugSymbolsIntermediatePathTemporary->'%(RootDir)%(Directory)%(Filename).pdb')"/>
</ItemGroup>
<PropertyGroup>
<CoreCompileDependsOn></CoreCompileDependsOn>
</PropertyGroup>
<Target Name="GenerateFSharpTextResources"
BeforeTargets="CoreResGen;PrepareForBuild">
<MakeDir Directories="$(IntermediateOutputPath)" />
<!-- Generate source for all resx files. -->
<FSharpEmbedResXSource EmbeddedResource="@(EmbeddedResource)" IntermediateOutputPath="$(IntermediateOutputPath)" TargetFramework="$(TargetFramework)">
<Output TaskParameter="GeneratedSource" ItemName="_FsGeneratedResXSource" />
</FSharpEmbedResXSource>
<ItemGroup>
<CompileBefore Include="@(_FsGeneratedResXSource)" />
<FileWrites Include="@(_FsGeneratedResXSource)" />
</ItemGroup>
<!-- Generate resx and source for all txt files. -->
<FSharpEmbedResourceText EmbeddedText="@(EmbeddedText)" IntermediateOutputPath="$(IntermediateOutputPath)">
<Output TaskParameter="GeneratedSource" ItemName="_FsGeneratedTxtSource" />
<Output TaskParameter="GeneratedResx" ItemName="_FsGeneratedResx" />
</FSharpEmbedResourceText>
<ItemGroup>
<CompileBefore Include="@(_FsGeneratedTxtSource)" />
<EmbeddedResource Include="@(_FsGeneratedResx)" />
<FileWrites Include="@(_FsGeneratedTxtSource)" />
<FileWrites Include="@(_FsGeneratedResx)" />
</ItemGroup>
</Target>
<Target
Name="CoreCompile"
Inputs="$(MSBuildAllProjects);
@(CompileBefore);
@(Compile);
@(CompileAfter);
@(_CoreCompileResourceInputs);
@(ManifestNonResxWithNoCultureOnDisk);
$(ApplicationIcon);
$(AssemblyOriginatorKeyFile);
@(ReferencePath);
@(CompiledLicenseFile);
@(EmbeddedDocumentation);
$(Win32Resource);
$(Win32Manifest);
@(CustomAdditionalCompileInputs);
$(VersionFile);
$(KeyOriginatorFile)"
Outputs="@(DocFileItem);
@(IntermediateAssembly);
@(_DebugSymbolsIntermediatePath);
$(NonExistentFile);
@(CustomAdditionalCompileOutputs)"
Returns=""
DependsOnTargets="$(CoreCompileDependsOn)"
>
<Error
Condition="'$(SilverlightVersion)' != '' and '$(SilverlightVersion)' != 'v5.0'"
Text="In this version of Visual Studio, F# for Silverlight can only target Silverlight v5.0. Use a prior version of Visual Studio to target previous versions of Silverlight with F#."
/>
<Warning
Condition="'$(Win32ResourceFile)' != '' "
Text="The property &lt;Win32ResourceFile> has been renamed to &lt;Win32Resource>. Update your project file to ensure that the correct value is passed via the --win32res option to the F# compiler."
/>
<!-- Workaround for differences between how msbuild and xbuild handle embedded resources.
If we just naively include the additional items needed for mono, that leads to issues
on msbuild/Windows due to double-including resources.
Here, we use the $(UsingXBuild) property to conditionally set another property containing the
correct list of resources based on the build system being used.
This could be a bit simpler, but xbuild doesn't seem to support msbuild 4.0 'item functions'
like Distinct().
Reference: https://github.com/Microsoft/visualfsharp/pull/2595
https://github.com/Microsoft/visualfsharp/pull/2605
-->
<ItemGroup>
<ActualEmbeddedResources
Condition=" '$(UsingXBuild)' == true"
Include="@(ManifestResourceWithNoCulture);@(ManifestNonResxWithNoCultureOnDisk);@(CompiledLicenseFile);@(AdditionalEmbeddedResource)" />
<ActualEmbeddedResources
Condition=" '$(UsingXBuild)' != true"
Include="@(_CoreCompileResourceInputs);@(CompiledLicenseFile);@(AdditionalEmbeddedResource)" />
</ItemGroup>
<!-- Condition is to filter out the _CoreCompileResourceInputs so that it doesn't pass in culture resources to the compiler -->
<!-- NOTE: ManifestResourceWithNoCulture and ManifestNonResxWithNoCultureOnDisk are generated by Mono targets files -->
<Fsc Condition=" '%(_CoreCompileResourceInputs.WithCulture)' != 'true' "
BaseAddress="$(BaseAddress)"
CodePage="$(CodePage)"
DebugSymbols="$(DebugSymbols)"
DebugType="$(DebugType)"
DefineConstants="$(DefineConstants)"
DelaySign="$(DelaySign)"
DisabledWarnings="$(NoWarn)"
DocumentationFile="$(DocumentationFile)"
DotnetFscCompilerPath="$(DotnetFscCompilerPath)"
EmbedAllSources="$(EmbedAllSources)"
Embed="$(Embed)"
GenerateInterfaceFile="$(GenerateInterfaceFile)"
HighEntropyVA="$(HighEntropyVA)"
KeyFile="$(KeyOriginatorFile)"
LCID="$(LCID)"
NoFramework="true"
Optimize="$(Optimize)"
OtherFlags="$(OtherFlags)"
OutputAssembly="@(IntermediateAssembly)"
PdbFile="$(PdbFile)"
Platform="$(PlatformTarget)"
Prefer32Bit="$(Actual32Bit)"
PreferredUILang="$(PreferredUILang)"
ProvideCommandLineArgs="$(ProvideCommandLineArgs)"
PublicSign="$(PublicSign)"
References="@(ReferencePath)"
ReferencePath="$(ReferencePath)"
Resources="@(ActualEmbeddedResources)"
SkipCompilerExecution="$(SkipCompilerExecution)"
SourceLink="$(SourceLink)"
Sources="@(CompileBefore);@(Compile);@(CompileAfter)"
Tailcalls="$(Tailcalls)"
TargetType="$(OutputType)"
TargetProfile="$(TargetProfile)"
ToolExe="$(FscToolExe)"
ToolPath="$(FscToolPath)"
TreatWarningsAsErrors="$(TreatWarningsAsErrors)"
UseStandardResourceNames="$(UseStandardResourceNames)"
Utf8Output="$(Utf8Output)"
VersionFile="$(VersionFile)"
VisualStudioStyleErrors="$(VisualStudioStyleErrors)"
WarningLevel="$(WarningLevel)"
WarningsAsErrors="$(WarningsAsErrors)"
Win32ManifestFile="$(Win32Manifest)"
Win32ResourceFile="$(Win32Resource)"
SubsystemVersion="$(SubsystemVersion)">
<Output TaskParameter="CommandLineArgs" ItemName="FscCommandLineArgs" />
</Fsc>
<ItemGroup>
<_CoreCompileResourceInputs Remove="@(_CoreCompileResourceInputs)" />
</ItemGroup>
</Target>
<Import Project="$(MSBuildBinPath)\Microsoft.Common.targets" />
<!--
============================================================
GenerateTargetFrameworkMonikerAttribute
Emit the target framework moniker attribute as a code
fragment into a temporary source file for the compiler.
============================================================
-->
<!--
============================================================
Override _GenerateCompileDependencyCache
Workaround for Issue #3824 and #3739
MsBuild does some optimisations around CompileInputs
The project system erroneously uses this to determine whether
to notify language services of CommandLine Information changes.
C# accidently changes it's file lists every build ... and so
gets the notifications.
F# doesn't ... so we don't get CL notifications following rebuilds
or build.
This workaround is basically to adds the current time (in ticks)
into the hash of CoreCompileInputs.cache at design time so that
we always appear to have different options and overcome the
brokencache behaviour.
Both msbuild and the project-system will fix their code at which time
this can go away.
============================================================
-->
<Target Name="_GenerateCompileDependencyCache" DependsOnTargets="ResolveAssemblyReferences" Condition="'$(DesignTimeBuild)' == 'true'">
<ItemGroup>
<CustomAdditionalCompileInputs Include="$(IntermediateOutputPath)$(MSBuildProjectFile).CoreCompileInputs.cache" />
<CoreCompileCache Remove="@(Compile)" />
<CoreCompileCache Include="@(ReferencePath)" />
<CoreCompileCache Include="$([System.DateTime]::Now.Ticks)" />
</ItemGroup>
<Hash ItemsToHash="@(CoreCompileCache)">
<Output TaskParameter="HashResult" PropertyName="CoreCompileDependencyHash" />
</Hash>
<WriteLinesToFile Lines="$(CoreCompileDependencyHash)" File="$(IntermediateOutputPath)$(MSBuildProjectFile).CoreCompileInputs.cache" Overwrite="True" WriteOnlyWhenDifferent="True" />
<ItemGroup>
<FileWrites Include="$(IntermediateOutputPath)$(MSBuildProjectFile).CoreCompileInputs.cache" />
</ItemGroup>
</Target>
<Target Name="GenerateTargetFrameworkMonikerAttribute" BeforeTargets="BeforeCompile" DependsOnTargets="PrepareForBuild;GetReferenceAssemblyPaths" Inputs="$(MSBuildThisFileFullPath)" Outputs="$(TargetFrameworkMonikerAssemblyAttributesPath)" Condition="'$(GenerateTargetFrameworkAttribute)' == 'true'">
<PropertyGroup>
<!-- This attribute is only available in mscorlib v4 and later -->
<AdditionalSourcesText Condition="'$(TargetFrameworkMoniker)' != '' and '$(TargetingClr2Framework)' != 'true'">
$(AdditionalSourcesText)
namespace Microsoft.BuildSettings
[&lt;System.Runtime.Versioning.TargetFrameworkAttribute(&quot;$(TargetFrameworkMoniker)&quot;, FrameworkDisplayName=&quot;$(TargetFrameworkMonikerDisplayName)&quot;)&gt;]
do ()
</AdditionalSourcesText>
</PropertyGroup>
<!-- This is a file shared between projects so we have to take care to handle simultaneous writes (by ContinueOnError)
and a race between clean from one project and build from another (by not adding to FilesWritten so it doesn't clean) -->
<WriteLinesToFile
File="$(TargetFrameworkMonikerAssemblyAttributesPath)"
Lines="$(AdditionalSourcesText)"
Condition="'$(AdditionalSourcesText)' != ''"
ContinueOnError="true"
Overwrite="true"/>
<ItemGroup>
<CompileBefore Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" Condition="'$(AdditionalSourcesText)' != '' AND ('$(OutputType)' == 'Exe' OR '$(OutputType)' == 'WinExe')"/>
<CompileAfter Include="$(TargetFrameworkMonikerAssemblyAttributesPath)" Condition="'$(AdditionalSourcesText)' != '' AND '$(OutputType)' != 'Exe' AND '$(OutputType)' != 'WinExe'"/>
</ItemGroup>
</Target>
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportAfter\*" Condition="'$(ImportByWildcardAfterMicrosoftFSharpTargets)' == 'true' and exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\$(MSBuildThisFile)\ImportAfter')"/>
</Project>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment