Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A most simple and basic CSC helper #592

Merged
merged 1 commit into from
Nov 18, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions src/app/FakeLib/CscHelper.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
/// Contains tasks to compile C# source files with CSC.EXE (C# Compiler).
module Fake.CscHelper
open System

/// Supported output types
type CscTarget =
| Exe
| Winexe
| Library
| Module

/// Supported platforms
type CscPlatform =
| X86
| Itanium
| X64
| AnyCpu32BitPreferred
| AnyCpu

/// Compiler parameters
type CscParams =
{ /// Specifies the output file name and path.
Output : string
/// Specifies the compiled artifact target type.
Target : CscTarget
/// Specifies the compiled artifact target platform.
Platform : CscPlatform
/// Specifies assemblies to reference for the compilation.
References : string list
/// Specifies whether to emit debug information (default is false).
Debug : bool
/// Specifies other params for the compilation. Freeform strings.
OtherParams : string list }

/// The default parameters to the compiler.
static member Default =
{ Output = ""
Target = Exe
Platform = AnyCpu
References = []
Debug = false
OtherParams = [] }

let cscExe (srcFiles : string list) (opts : string list) : int =
let processResult =
ExecProcessAndReturnMessages (fun p ->
p.FileName <- if isMono then "mcs" else "csc"
p.Arguments <- [
opts |> separated " "
srcFiles |> separated " "
] |> separated " "
) (TimeSpan.FromMinutes 10.)

trace <| sprintf "CSC with args:%A" (Array.ofSeq opts)

processResult.ExitCode

/// Compiles the given C# source files with the specified parameters.
///
/// ## Parameters
///
/// - `setParams` - Function used to overwrite the default CSC parameters.
/// - `inputFiles` - The C# input files.
///
/// ## Returns
///
/// The exit status code of the compile process.
///
/// ## Sample
///
/// ["file1.cs"; "file2.cs"]
/// |> csc (fun parameters ->
/// { parameters with Output = ...
/// Target = ...
/// ... })
let csc (setParams : CscParams -> CscParams) (inputFiles : string list) : int =
let inputFiles = inputFiles |> Seq.toList
let taskDesc = inputFiles |> separated ", "
let cscParams = setParams CscParams.Default

let output = if cscParams.Output <> "" then [sprintf "/out:%s" cscParams.Output] else []
let target =
match cscParams.Target with
| Exe -> [ "/target:exe" ]
| Winexe -> [ "/target:winexe" ]
| Library -> [ "/target:library" ]
| Module -> [ "/target:module" ]
let platform =
match cscParams.Platform with
| X86 -> [ "/platform:x86" ]
| Itanium -> [ "/platform:itanium" ]
| X64 -> [ "/platform:x64" ]
| AnyCpu32BitPreferred -> [ "/platform:anycpu32bitpreferred" ]
| AnyCpu -> [ "/platform:anycpu" ]
let references =
cscParams.References
|> List.map (fun r -> sprintf "/reference:%s" r)
let debug = if cscParams.Debug then [ "/debug" ] else []
let argList =
output @ target @ platform @ references @ debug @ cscParams.OtherParams
traceStartTask "Csc " taskDesc
let res = cscExe inputFiles argList
traceEndTask "Csc " taskDesc
res

/// Compiles one or more C# source files with the specified parameters.
/// ## Parameters
///
/// - `setParams` - Function used to overwrite the default CSC parameters.
/// - `inputFiles` - The C# input files.
///
/// ## Sample
///
/// ["file1.cs"; "file2.cs"]
/// |> Csc (fun parameters ->
/// { parameters with Output = ...
/// Target = ...
/// ... })
let Csc (setParams : CscParams -> CscParams) (inputFiles : string list) : unit =
let res = csc setParams inputFiles
if res <> 0 then raise <| BuildException("Csc: compile failed with exit code", [ string res ])
3 changes: 2 additions & 1 deletion src/app/FakeLib/FakeLib.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@
<Compile Include="ReportGeneratorHelper.fs" />
<Compile Include="RoundhouseHelper.fs" />
<Compile Include="FscHelper.fs" />
<Compile Include="CscHelper.fs" />
<Compile Include="HipChatNotificationHelper.fs" />
<Compile Include="XamarinHelper.fs" />
<Compile Include="XDTHelper.fs" />
Expand Down Expand Up @@ -637,4 +638,4 @@
</ItemGroup>
</Otherwise>
</Choose>
</Project>
</Project>
64 changes: 64 additions & 0 deletions src/test/Test.FAKECore/CscSpecs.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using System;
using System.IO;
using System.Linq;
using Fake;
using Machine.Specifications;
using Microsoft.FSharp.Core;
using Microsoft.FSharp.Collections;

namespace Test.FAKECore
{
public class compile_csfiles_to_dll
{
static string tempDir, outFile, csFile1, csFile2;
static FSharpFunc<CscHelper.CscParams, CscHelper.CscParams> cscParams;

Establish context = () =>
{
tempDir = Path.GetTempPath();
csFile1 = Path.Combine(tempDir, "test1.cs");
csFile2 = Path.Combine(tempDir, "test2.cs");

File.WriteAllText(csFile1, @"
using System;

namespace Test {
public class Class1 {
public string Hello(string what) {
return String.Format(""Hello {0}"", what);
}
}
}");

File.WriteAllText(csFile2, @"
using System;

namespace Test {
public class Class2 : Class1 {
public void HelloWorld() {
Console.WriteLine(this.Hello(""World""));
}
}
}");

outFile = Path.Combine(tempDir, "test.dll");
try { File.Delete(outFile); } catch (FileNotFoundException) {}

cscParams = FSharpFuncUtil.ToFSharpFunc<CscHelper.CscParams, CscHelper.CscParams>(
p => new CscHelper.CscParams(
output: outFile,
target: CscHelper.CscTarget.Library,
platform: p.Platform,
references: p.References,
debug: p.Debug,
otherParams: p.OtherParams
)
);
};

Because of = () => CscHelper.Csc(cscParams, ListModule.OfSeq(new [] { csFile1, csFile2 }));

It should_compile_to_dll = () => File.Exists(outFile).ShouldBeTrue();
}
}

3 changes: 2 additions & 1 deletion src/test/Test.FAKECore/Test.FAKECore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@
<Compile Include="ConfigFiles\ConfigSpecs.cs" />
<Compile Include="AssemblyInfoSpecs.cs" />
<Compile Include="XdtSpecs.cs" />
<Compile Include="CscSpecs.cs" />
<Compile Include="XmlSpecs.cs" />
<Compile Include="TestData.cs" />
<Compile Include="FileHandling\CleanDirectorySpecs.cs" />
Expand Down Expand Up @@ -715,4 +716,4 @@
</ItemGroup>
</Otherwise>
</Choose>
</Project>
</Project>