FAKE Fsc任务是将构建产品写入错误的目录

时间:2014-11-14 17:28:37

标签: f# f#-fake

我正在学习F#,并为类似hello-world的应用程序设置FAKE构建工具。 (虽然偶尔会想到“地狱世界”这个短语...... :-)我正在使用Mac和emacs(通常试图通过偏好来避免使用GUI IDE)。

在对文档进行一些调整之后,这是我如何通过FAKE调用F#编译器:

let buildDir  = @"./build-app/"                        // Where application build products go

Target "CompileApp" (fun _ ->                          // Compile application source code
  !! @"src/app/**/*.fs"                                // Look for F# source files
  |> Seq.toList                                        // Convert FileIncludes to string list
  |> Fsc (fun p ->                                     //  which is what the Fsc task wants
    {p with                                            //
       FscTarget = Exe                                 //
       Platform  = AnyCpu                              //
       Output    = (buildDir + "hello-fsharp.exe") })  // *** Writing to . instead of buildDir?
)                                                      //

使用!!以通常的方式制作所有来源的FileIncludes,然后使用Seq.toList将其更改为string list个文件名,然后递交到Fsc任务。很简单,它甚至似乎有效:

...
Starting Target: CompileApp (==> SetVersions)
FSC with args:[|"-o"; "./build-app/hello-fsharp.exe"; "--target:exe"; "--platform:anycpu";
  "/Users/sgr/Documents/laboratory/hello-fsharp/src/app/hello-fsharp.fs"|]
Finished Target: CompileApp
...

但是,尽管上面的控制台输出说明了,实际的构建产品仍然转到顶级目录,而不是构建目录。上面的消息看起来-o参数正在以适当的文件名传递给编译器,但可执行文件放在.而不是./build-app/

所以,2个问题:

  1. 这是在FAKE构建工具中调用F#编译器的合理方法吗?
  2. 我误解了导致构建产品出错的地方是什么?

1 个答案:

答案 0 :(得分:3)

FAKE issue #521中报告了此问题或非常类似的问题,似乎已在FAKE pull request #601中修复,其中包含。{/ p>

问题解释

除了我以外,每个人都知道,FSharp.Compiler.Service中实现的F#编译器有跳过第一个参数的做法。请参阅第127行附近的FSharp.Compiler.Service/tests/service/FscTests.fs,其中我们会看到以下内容丰富的评论:

 // fsc parser skips the first argument by default;
 // perhaps this shouldn't happen in library code.

是否应该发生, 发生的是什么。由于-oFscHelper生成的参数中排在第一位,因此它被尽职尽责地忽略了(显然还有它的论点)。因此,程序集进入默认位置,而不是指定的位置。

解决方案

除了 --out:destinationFile字段外,临时解决方法是在OtherParams setter FscParams字段中指定Output;后者是在前者完成工作时被忽视的牺牲品。

长期解决方案是修复FscHelper生成的参数,以便在前面有一个额外的一次性参数;那么这两个问题就会在一阵油腻的黑烟中湮灭。 (当你想到它时,它的美丽就像它的美丽。)这正是由@forki23刚刚合并到主人的事情:

 // Always prepend "fsc.exe" since fsc compiler skips the first argument
 let optsArr = Array.append [|"fsc.exe"|] optsArr

因此该解决方案应该是最新版本的FAKE(3.11.0)。

我的两个问题的答案是:

  1. 是的,这似乎是调用F#编译器的合理方法。
  2. 我没有误解任何事情;它只是一个错误,修复正在进行中。
  3. 更重要的是: 实际的误解是我应该检查FAKE问题并提取请求以查看是否有其他人报告了此类事情,并且这就是我下次要做的事。