diff --git a/aegisub/build/Aegisub/Aegisub.vcxproj b/aegisub/build/Aegisub/Aegisub.vcxproj
index 95fbe4280..2759a3f79 100644
--- a/aegisub/build/Aegisub/Aegisub.vcxproj
+++ b/aegisub/build/Aegisub/Aegisub.vcxproj
@@ -47,7 +47,7 @@
-
+
diff --git a/aegisub/build/BuildTasks/BuildTasks.fs b/aegisub/build/BuildTasks/BuildTasks.fs
index 550900866..e3a5e74a4 100644
--- a/aegisub/build/BuildTasks/BuildTasks.fs
+++ b/aegisub/build/BuildTasks/BuildTasks.fs
@@ -22,8 +22,8 @@ open Microsoft.Build.Evaluation
open Microsoft.Build.Framework
open Microsoft.Build.Utilities
-exception ShellException of string
-
+/// Search the executable path for the directory containing the given file and
+/// return it or empty string if not found
let searchPath file =
Environment.GetEnvironmentVariable("path").Split ';'
|> Seq.map (fun p -> IO.Path.Combine(p, file))
@@ -31,6 +31,8 @@ let searchPath file =
|> Seq.append [""]
|> Seq.nth 1
+/// Read all of the defined properties from the calling project file and stuff
+/// them in a Map
let propertyMap (be : IBuildEngine) =
use reader = Xml.XmlReader.Create(be.ProjectFileOfTaskNode)
let project = new Project(reader)
@@ -41,44 +43,106 @@ let propertyMap (be : IBuildEngine) =
|> Seq.map (fun x -> (x.Name, x.EvaluatedValue))
|> Map.ofSeq
+/// Convert a windows path possibly relative to the Aegisub project file to an
+/// absolute msys path
+let mungePath projectDir path =
+ let matchre pat str =
+ let m = System.Text.RegularExpressions.Regex.Match(str, pat)
+ if m.Success
+ then List.tail [ for g in m.Groups -> g.Value ]
+ else []
+ match IO.Path.Combine(projectDir, path) |> matchre "([A-Za-z]):\\\\(.*)" with
+ | drive :: path :: [] -> sprintf "/%s/%s" drive (path.Replace('\\', '/'))
+ | _ -> failwith <| sprintf "Bad path: '%s' '%s'" projectDir path
+
type ShellWrapper(props : Map) =
+ let setPath msysRoot =
+ Environment.SetEnvironmentVariable("path", msysRoot + "\\bin;" + props.["NativeExecutablePath"])
+ Environment.SetEnvironmentVariable("CC", "cl")
+ Environment.SetEnvironmentVariable("INCLUDE", props.["IncludePath"])
+ Environment.SetEnvironmentVariable("LIB", props.["LibraryPath"])
+
let sh =
match props.TryFind "MsysBasePath" with
| None | Some "" -> searchPath "sh.exe"
- | Some path -> sprintf "%s\\bin\\sh.exe" path
+ | Some path -> setPath path; sprintf "%s\\bin\\sh.exe" path
let cwd = function
| null | "" -> props.["AegisubSourceBase"]
- | x -> x
+ | x -> if not <| IO.Directory.Exists x then ignore <| IO.Directory.CreateDirectory(x)
+ x
- member this.call scriptName workingDir =
+ member this.call args workingDir =
if not <| IO.File.Exists sh then
- raise <| ShellException "sh.exe not found. Make sure the MSYS root is set to a correct location."
+ failwith "sh.exe not found. Make sure the MSYS root is set to a correct location."
let info = new ProcessStartInfo(FileName = sh
- , Arguments = scriptName
+ , Arguments = args
, WorkingDirectory = cwd workingDir
, RedirectStandardOutput = true
, UseShellExecute = false)
use p = new Process(StartInfo = info)
ignore(p.Start())
+ let output = p.StandardOutput.ReadToEnd()
p.WaitForExit()
if p.ExitCode <> 0 then
- raise <| ShellException(p.StandardOutput.ReadToEnd())
+ failwith output
+
+ member this.callScript scriptName args workingDir =
+ this.call (sprintf "%s %s" (mungePath props.["ProjectDir"] scriptName) args) workingDir
type ExecShellScript() =
inherit Task()
member val WorkingDirectory = "" with get, set
member val Command = "" with get, set
+ member val Script = "" with get, set
+ member val Arguments = "" with get, set
override this.Execute() =
try
let sw = ShellWrapper (propertyMap this.BuildEngine)
- this.Log.LogMessage("Calling '{0}'", this.Command);
- sw.call this.Command this.WorkingDirectory
+ if this.Script.Length > 0
+ then this.Log.LogMessage("Calling '{0}' {1}", this.Script, this.Arguments);
+ sw.callScript this.Script this.Arguments this.WorkingDirectory
+ else this.Log.LogMessage("Calling '{0}' {1}", this.Command, this.Arguments);
+ sw.call (sprintf "-c '%s %s'" this.Command this.Arguments) this.WorkingDirectory
true
- with ShellException(e) ->
+ with Failure(e) ->
this.Log.LogError(e)
false
+
+type MsysPath() =
+ inherit Task()
+
+ member val ProjectDir = "" with get, set
+ member val Path = "" with get, set
+
+ [