Skip to content

Fantom 工具链文档(docTools) ​

原文: https://finproducts.atlassian.net/wiki/spaces/JIDD3/pages/34793979905/FIN+5.3.1+docTools 中文整理基于 FIN 5.3.1


manual ​

docTools ​

Fantom 命令行工具


chapters ​

Setuphow to get everything setup
Fanfan launcher
Fanshinteractive shell for exploring
Fanccompiler and transpiler tools
Fantunit testing framework
Fanpfcode disassembler
Buildbuild toolkit
Bootstraphow to recompile the runtime and compiler itself
IDEslinks to other Fantom IDEs

Bootstrap ​

概述 ​

Fantom 编译器本身是用 Fantom 编写的——这就产生了鸡与蛋的问题。没有编译器,你如何编译编译器?问题进一步复杂化,因为构建脚本本身也是用 Fantom 编写的。为了解决这个问题,引导过程需要两个 Fantom 安装版:

  1. rel:已知的良好 Fantom 安装(通常是最后一个构建)dev:用于构建的开发环境(可能从 GitHub 拉取)

按照惯例,我们将开发目录树结构化如下:

work/
  rel/
    bin/
    lib/
    ...
  fan/
    bin/
    lib/
    src/
    ...

"rel" 目录始终包含最后发布的版本。"fan" 目录包含我们的主要开发代码分支。

引导脚本 ​

从 git 执行自举构建的最简单方法是使用 "bootstrap.fan" 脚本:

  1. 从 https://fantom.org/ 下载最新发布的版本 将该版本解压到 {relHome} 确保 git 已安装在你的路径中(参见 Git) 验证 java_home 环境变量指向你的 JDK 安装 执行 {relHome}/bin/fan {relHome}/adm/bootstrap.fan 去拿一杯咖啡

注意:默认设置需要 JDK 1.8 来重新编译 Fantom。

默认情况下,devHome 被假定为 relHome 的一个同级目录,名为“fan”。如果您想使用其他目录,请指定“-devHome”选项。

这个脚本将执行若干步骤:

  1. 验证您的环境 克隆 git 仓库,如果仓库已存在则执行拉取 配置您的 etc 文件 从头重建您的 devHome 环境

本章的其余部分涵盖了完全理解引导构建所需的所有内部细节。

开发者主页 ​

默认情况下,构建假定 devHome 是 Fantom 安装的主目录。例如,如果你重新构建 Java 运行时,那么输出会进入 "devHome/lib/java/sys.jar"。在 rel 安装的情况下,我们不希望使用这个默认值,因为这会自我覆盖(这会导致一些棘手的问题)。因此,你需要在 rel 安装的 "etc/build/config.props" 中设置 devHome 属性,以使用 URI(而不是操作系统路径)引用 dev 目录:

// Must be configured boot build in substitute/release installation
devHome=file:/C:/work/fan/

如果你忘记做这件事,那么你将会遇到一个看起来像这样的构建错误:

C:\work\fan\src>sys\java\build
ERR: Must update 'devHome' for bootstrap build
BUILD FAILED [12ms]!

Substitutes ​

在一台只有源代码的干净机器上,我们没有任何已编译的 pod,例如 sys、build 或 compiler。为了运行构建脚本以编译这些 pod,我们需要使用我们的 rel 安装。

所有引导构建脚本的第一行都应包含以下 Unix shebang 行。即使您只是在 Windows 上构建,也应如此。

#! /usr/bin/env fansubstitute

在 Unix 上,fansubstitute 脚本在启动之前会明确将 FAN_HOME 设置为 FAN_SUBSTITUTE 变量的值。在 Windows 上,启动器脚本会在你即将运行的构建脚本中查找这一行。如果找到,它会在启动之前将 FAN_HOME 设置为 FAN_SUBSTITUTE 的值。因此,在任何情况下,你都需要导出 FAN_SUBSTITUTE 来引用你的 rel 安装。当然,你还必须将你的脚本作为可执行文件运行,以便 shebang 生效。

JDK ​

您需要 JDK 1.8 来从源码编译。

为了从源代码编译,您需要设置一些配置属性以引用您的 JDK 主目录:

jdkHome=/C:/dev/tools/java/

这些路径应格式化为文件系统 URI(而不是操作系统路径)。此属性应在你 rel 和 dev 环境的 "etc/build/config.props" 中配置。

Buildall ​

"buildall.fan" 脚本是用于编译 Fantom 发行版的顶层构建脚本。我们通常运行此命令来重建所有内容并在每个 pod 上运行测试:

buildall full test

"buildall" 脚本由 rel substitute 运行时执行,并反过来启动两个子脚本。"buildboot.fan" 脚本负责管理核心运行时模块的重建:

sys/build.fan
sys/java/build.fan
sys/dotnet/build.fan
sys/js/build.fan
compiler/build.fan
compilerJava/build.fan
build/build.fan

一旦引导模块被编译,开发环境就可以自我托管,并且可以用来编译其余部分。 这是通过“buildpods.fan”脚本完成的。

Dependencies ​

引导问题可能会导致一些令人困惑的依赖性问题,这里总结如下:

  • rel 编译器将生成 sys、compiler 和 build pod 文件。这意味着 rel 编译器必须能够生成 dev 运行时可以读取的 fcode。这也意味着 rel 编译器必须能够读取 dev 版本的 sys、compiler 和 build 中使用的任何新语法。rel 编译器实际上将使用 pod 的 dev 版本来解析依赖关系。例如,dev 编译器可以引用 dev 中定义的新 sys API,而 rel 中不能。在底层,这是可行的,因为编译器和 build pod 的构建脚本指定了非默认的 dependsDir。

由于这些限制,添加新的语言特性和 fcode 更改需要一些仔细的计划。

Debugging ​

你可以使用“dumpEnv”构建目标来导出构建脚本环境的关键方面。你可以在“buildall.fan”上运行该目标,尽管更简明的报告是对“buildboot.fan”和一个非引导 pod(例如“testSys/build.fan”)运行 dumpEnv。

关于您的环境需要注意的关键事项:

  1. 所有脚本都应该使用 dev 对于 devHome 目录,bootbuild 脚本应该使用 rel 对于 fanHome,非 bootbuild 脚本如 testSys 应该使用 dev 对于 fanHome,验证 sys/javafan/build.fan 的 javaHome

Summary ​

总之,你想确保几件关键的事情:

  1. 设置你的 rel 安装并且永远不要动它(将其视为只读)确保在 rel 和 dev 中都配置了 jdkHome 等等/build/config.props 确保 rel 等等/build/config.props 中的 devHome 指向你的 dev 安装 确保 FAN_SUBSTITUTE 环境变量只指向 rel 安装 仅将 dev bin 放入你的路径,并且始终从 dev 安装运行你的脚本 永远不要使用工作仓库进行引导(只使用 boot 仓库)

Build ​

概述 ​

Fantom 自带自己的标准构建引擎,以促进一致性并使共享代码变得容易。构建脚本是普通的 Fantom 脚本,继承自 BuildScript。构建脚本的特点:

  • BuildScript 基类处理常见功能,如命令行解析、环境设置和日志记录。子类定义目标,即构建脚本可以执行的操作,例如“compile”(编译)、“clean”(清理)或“test”(测试)。目标作为普通的 Fantom 方法实现,可以使用已安装的 API 执行任何所需的过程性代码。构建 pod 提供任务库,旨在提供可组合以定义目标的常见功能模块。构建 pod 提供预定义的 BuildScript 类库以处理常见脚本——你会经常使用的一个是 BuildPod,用于构建 Fantom pod。

构建工具包旨在提供一种一致的方式来组织构建脚本——它并不提供执行构建所需的所有内容的全面库。但通过预定义常用脚本(如 BuildPod),它将大多数脚本简化为纯声明式信息。当你确实需要自定义代码的功能时,可以像使用普通 Fantom 代码一样干净地实现它。

示例 ​

让我们创建一个名为 "buildtest.fan" 的构建脚本:

using build

class Build : BuildScript
{
  @Target { help = "Compile everything" }
  Void compile() { log.info("Compile away!") }

  @Target { help = "Clean it all up" }
  Void clean() { log.info("Clean away!") }
}

上面的脚本定义了两个目标:compile 和 clean。目标使用 @Target 特性进行注解。将 help 字段设置为简短摘要。要打印此脚本的用法,请使用 "-?"。

C:\dev\fan\src>buildtest -?
usage:
  build [options] <target>*
options:
  -? -help       Print usage summary
  -v             Verbose debug logging
  -dumpEnv       Debug dump of script env
targets:
  compile*       Compile everything
  clean          Clean it all up

请注意,“compile”目标被标记了一个星号,这表示它是默认目标,因为它是第一个声明的目标。如果我们在不使用参数的情况下调用该脚本,将会执行“compile”目标:

C:\dev\fan\src>buildtest
Compile away!
BUILD SUCCESS [3ms]!

或者我们可以将一个或多个目标作为参数传递:

C:\dev\fan\src>buildtest clean
Clean away!
BUILD SUCCESS [2ms]!

C:\dev\fan\src>buildtest clean compile
Clean away!
Compile away!
BUILD SUCCESS [2ms]!

注意:请参阅设置,以配置您的环境,使其仅使用脚本文件名即可运行脚本。

BuildScript ​

BuildScript 是所有构建脚本的基类。它提供了许多你会觉得很有用的槽位:

  • log:标准化日志记录
  • scriptFile:脚本本身的文件
  • scriptDir:包含脚本的目录
  • devHomeDir:您的开发 Fantom 环境的主目录

Lifecycle ​

构建脚本的生命周期由以下步骤组成:

  1. 基类构造函数将被执行,并会立即设置环境变量,例如日志(log)和脚本文件(scriptFile)。然后执行你的子类构造函数,这里你可以配置你自己的脚本字段。将调用 targets 回调以获取目标列表——大多数情况下,你会让默认实现通过搜索实现了 @Target 特性的函数来构建该列表。命令行会被解析以查找所有指定的目标,如果未指定目标,则使用 targets 方法的第一个目标。每个目标方法按照指定顺序被调用。如果抛出异常,脚本将失败并返回 -1,否则返回 0。

脚本运行期间的问题应通过 BuildScript.log 报告。如果遇到应该终止脚本的错误,则通过以下模式抛出 FatalBuildErr:

throw fatal("I just can't go on!")

BuildPod ​

BuildPod 是用于构建 Fantom pod 的构建脚本的基类。BuildPod 脚本定义了一些需要填写的字段。此外,它预定义了几个可以直接使用的目标:

  • compile:将 Fantom 代码重新编译成 pod 文件以及所有相关的本地文件(JavaScript、Java、.NET)
  • clean:删除所有中间文件和生成的目标文件
  • test:运行 pod 声明的所有测试
  • full:清理、编译、测试

按照惯例,Pod 源代码目录组织如下:

foo/
  build.fan
  fan/
    ClassAlpha.fan
    ClassBeta.fan
  java/
    ClassAlphaPeer.java
  js/
    ClassAlphaPeer.js
  dotnet/
    ClassAlphaPeer.cs
  test/
    TestClassAlpha.fan
    TestClassBeta.fan
  res/
    icon.png
    resource-file.txt

如果你没有测试或本地代码,那么这些目录不会被包含在内。我们上面目录结构的构建脚本如下所示:

// build.fan
using build
class Build : BuildPod
{
  new make()
  {
    podName    = "foo"
    summary    = "Description of foo pod.  Foo is good."
    depends    = ["sys 1.0+", "bar 1.1+"]
    srcDirs    = [`fan/`, `test/`]
    javaDirs   = [`java/`]
    jsDirs     = [`js/`]
    dotnetDirs = [`dotnet/`]
    resDirs    = [`res/`]
  }
}

请注意,所有目录都是相对于脚本目录指定的 Uri。如果你没有本地代码,可以省略 javaDirs、dotnetDirs 和 jsDirs 设置。如果你没有资源文件,可以省略 resDirs。请参见 HelloWorld 获取更简单的示例。

通常,pod 的版本由构建脚本的 version 字段设置。默认情况下,这设置为在“etc/build/config.props”中配置的 config 属性 buildVersion。

初始化工具 ​

Fantom 版本 1.0.72 及之后的版本包括一个“init”工具,用于简化创建新项目:

$ fan build init hello
Created new env 'hello/'
Created new pod 'src/hello/'
INIT SUCCESS!

它会生成以下目录:

hello
├── etc
├── fan.props
├── lib
└── src
    ├── build.fan
    └── hello
        ├── build.fan
        ├── fan
        └── test

关于这个结构,有几点需要注意:

  1. 如果“hello”目录不存在,初始化工具会认为这是一个新项目,并生成一个“fan.props”文件。该文件告诉构建和运行时工具,这个目录是一个 PathEnv。现在,当你构建 pods 时,它们将写入本地的“lib/”目录,而不会污染你全局的 Fantom “lib” 文件夹。按照惯例,Fantom 项目组织为 <project-name>/src/<pod-name>。因此,“hello” pod 的源代码将被包含在它自己的子目录下。根目录下的 src/build.fan 是你的顶级构建脚本。该脚本继承自 BuildGroup。每当你向项目中添加一个新 pod 时,务必在这里添加,这样你就可以一步构建所有内容。

如果您的项目需要额外的 pod,只需在项目目录下重新运行初始化工具:

~/hello$ fan build init next
Created new pod 'src/next/'
Remember to add 'next/build.fan' to 'src/build.fan'!
INIT SUCCESS!

你的项目目录现在看起来像这样:

hello
├── etc
├── fan.props
├── lib
└── src
    ├── build.fan
    ├── hello
    │   ├── build.fan
    │   ├── fan
    │   └── test
    └── next
        ├── build.fan
        ├── fan
        └── test

请注意,init 工具在生成新的 Pod 源代码树时支持使用相对路径:

$ fan build init backend/webserver
Created new pod 'src/backend/webserver/'
Remember to add 'backend/webserver/build.fan' to 'src/build.fan'!
INIT SUCCESS!

Fan ​

概述 ​

风扇启动器用于运行 Fantom 代码。它可以通过两种方式使用:

  1. 在预编译的 pod 中执行方法以运行以 ".fan" 扩展名结尾的脚本文件

风扇可执行文件还有几个获取版本信息的选项。"-version" 选项将打印正在使用的运行时的当前版本以及配置的仓库。你可以使用 "-pods" 选项列出所有已安装的 pods。

运行脚本 ​

如果传递给风扇可执行文件的第一个参数是以“.fan”结尾的文件名,则启动器将尝试按照以下步骤执行脚本:

  1. 编译脚本文件,找到定义了名为“main”的方法的类。如果该方法不是静态的,则通过 Type.make 创建的实例调用它。如果该方法有一个 Str[] 参数,则使用 Env.args 调用,否则无参数调用。如果 main 返回一个 Int,则将其作为退出代码返回

脚本文件可以声明多个类型声明,但只有一个类型可以定义名为“main”的方法。脚本可以声明 using 语句或使用完全限定的类型名称来访问任何 pod 中的类型。然而,目前脚本无法从另一个脚本文件导入类型。

参见 HelloWorld 了解如何运行脚本文件的示例。

另请参阅 Unix 设置和 Windows 设置,以使风扇脚本可执行,而无需显式调用启动器。

运行中的Pods ​

您可以使用以下任意一种格式来执行已安装 pod 中的方法:

fan <pod> [args]
fan <pod>::<type> [args]
fan <pod>::<type>.<method> [args]

执行该方法的步骤如下:

  1. 如果仅指定了 Pod 名称,则假定为 <pod ::Main.main;如果仅指定了类型名称,则假定为 <pod ::<type .main。解析方法的限定名称,如果方法不是静态的,则通过 Type.make 创建的实例调用;如果方法有 Str[] 参数,则使用 Env.args 调用,否则不带参数调用。如果 main 返回 Int,则将其作为退出代码返回。

请参阅 HelloWorld 了解如何在 pod 中构建和运行方法的示例。

Main ​

主方法可以返回 Void 或 Int。如果主方法返回 Int,则该值作为进程的退出代码返回,否则返回零(如果抛出异常,则返回非零)。

主方法要么不带参数,要么带有 Str[]。你可以通过 Env.args 方法访问在命令行上传递的任何参数。以下都是有效的主方法:

Void main()
Void main(Str[] args)
Void main(Str[] args, Bool defaultsOk := true)
Int main()
Int main(Str[] args)
Int main(Str[] args, Bool defA := true, Int? defB := null)

上面所有的主方法签名都可以是静态的或基于实例的。如果主方法是静态的,那么它可以通过反射直接调用。然而,如果主方法是基于实例的,则通过 Type.make 创建一个新实例来用于主方法。此技术可用于通过基类执行常见初始化——实际上,构建脚本本身就使用了它。


Fanc ​

概述 ​

fanc 命令行用于将 Fantom 代码转译为包括 Java 和 JavaScript/TypeScript 在内的不同编程语言。

Java ​

使用 fanc java 将一组 Fantom pods 转换为 Java 源代码。此命令使用其中一个 pod 的名称,解决它们的依赖链,并生成打包自包含 jar 文件所需的代码。另请参见 Java。

Example:

fanc java -jar example.jar pod1 pod2

JavaScript ​

使用 fanc js 将一组 Fantom pods 转换为 JavaScript 和 TypeScript 源代码。此命令接受一个 pod 名称,解决它们的依赖链,并生成作为 NPM 模块的 JS 和 TS 代码。另请参见 JavaScript。

Example:

fanc js pod1 pod2

Fanp ​

概述 ​

fanp 命令行工具用于反汇编已编译的 fcode。如果你有强烈的愿望去破解编译器或运行时生成的代码,那么你会发现 fanp 是不可或缺的。像许多其他命令行工具一样,你可以传递一个 pod 名称、一个类型 qname 或一个槽 qname:

fanp fansh
fanp fansh::Main
fanp fansh::Main.main

默认情况下,仅打印高级签名和特征。通过“-?”打印用法以查看各种选项。

反汇编代码 ​

"-c" 选项将转储操作码:

// fansh::Main.main
static Void main() { Shell.make.run }

// disassemble it
C:\>fanp -c fansh::Main.main

main () -> sys::Void [const public static]
  [Code]
    0: CallNew             fansh::Shell.make() -> sys::Void
    3: CallVirtual         fansh::Shell.run() -> sys::Void
    6: Return
  [LineNumber] size=2
     168

拆解脚本 ​

你可以在脚本文件编译后但执行前,使用脚本文件名后面的“-fcodeDump”参数打印脚本的反汇编代码:

fan script.fan -fcodeDump
script.fan -fcodeDump        // if script.fan is directly executable

Fansh ​

概述 ​

fansh 是一个非常简单的交互式 shell,用于探索 Fantom。该 shell 允许你输入一行语句或表达式。如果表达式的结果非空,则会通过 Obj.toStr 方法打印结果。输入 "quit" 退出:

C:\dev\fan\bin>fansh
Fantom Shell v1.0.74 ('?' for help)
fansh> 3 + 4
7
fansh> "3" + 4
34
fansh> [3, 2, 9, 1].sort.join("|")
1|2|3|9
fansh> quit

Scope ​

如果你输入一个声明局部变量或赋值局部变量的语句,shell 会使该变量可用于后续的计算。你可以输入 “scope” 命令来列出当前的局部变量。例如:

C:\dev\fan\bin>fansh
Fantom Shell v1.0.74 ('?' for help)
fansh> x := 5
5
fansh> y := 7
7
fansh> z := [x, y]
[5, 7]
fansh> scope

Current Scope:
  sys::Int?[] z = [5, 7]
  sys::Int y = 7
  sys::Int x = 5

使用Pods ​

您可以使用完全限定的类型名称来导入一个 pod:

fansh> inet::IpAddr("www.google.com").numeric
64.233.161.147

或者您可以通过使用 using 语句导入一个 pod:

fansh> using inet
Add using: using inet
fansh> IpAddr("www.google.com").numeric
64.233.161.104
fansh> scope

Current Usings:
  using inet

Current Scope:

Limitations ​

目前,与许多其他语言的交互式命令行相比,Fantom 的交互式命令行功能相当有限。你无法输入多行语句或表达式,也无法输入完整的类型定义。如果你希望通过超过简单单行语句的方式来探索这种语言,请将你的 Fantom 代码作为脚本运行。


Fant ​

概述 ​

Fantom 在运行时中内置了单元测试框架——它与常见的测试框架如 JUnit 非常相似。测试的关键概念有:

  • 编写继承 Test 的测试类 编写以 "test" 开头的测试方法 通过 "verifyXXX" 方法断言测试条件 使用 fant 命令行工具运行测试

组织测试 ​

按照惯例,测试类直接在其关联的模块中组织,使用以下目录结构:

myPod/
  build.fan
  fan/
    ClassA.fan
    ClassB.fan
  test/
    TestClassA.fan
    TestClassB.fan

编写测试 ​

在 pod 中,任何继承自 Test 的具体类都被视为测试类。测试类中任何以“test”开头的方法都被视为测试方法。测试方法必须是无参数的公共实例方法。测试方法使用 verify 方法来断言条件。三种最常用的 verify 方法:

  • verify: 断言一个布尔条件为真
  • verifyEq: 断言两个对象相等
  • verifyErr: 断言抛出一个异常

这里是一个测试类的示例:

class SampleTest : Test
{
  Void testStuff()
  {
    verify('A'.isUpper)
    verifyEq('A'.lower, 'a')
    verifyErr(ParseErr#) { x := Int.fromStr("@#!") }
  }
}

运行测试 ​

Fant 启动器用于运行测试。您可以传递一个 pod 名称、类型 qname 或槽 qname 来运行任何已安装 pod 中的任意测试。您还可以传递“-all”来运行所有 pod 中的所有测试:

fant -all
fant testSys
fant testSys::StrTest
fant testSys::StrTest.testEach

你也可以向 fant 传递一个脚本文件名:

fant /tests/foo.fan

该脚本将被编译成一个 pod,然后所有 Test 的子类将被运行。

测试结果将打印到标准输出。任何测试失败将作为异常引发。

测试生命周期 ​

在运行测试时,每个测试方法按如下方式执行:

  1. 通过 make 实例化测试类的新实例,调用 setup。测试方法在没有参数的情况下被调用。任何引发的异常都会被捕获,并且测试会被标记为失败。保证会调用 teardown。

测试方法引发的任何异常都被视为失败。调用失败的 verify 将只会引发一个异常。


IDEs ​

概述 ​

尽管 Fantom 是一种非常年轻的语言,但已经有许多项目致力于为你喜欢的 IDE 提供 Fantom 支持。请注意,这些项目中的许多仍处于早期开发阶段。

Eclipse F4(xored 软件) ​

F4 是一个基于 Eclipse 的 Fantom IDE,主要用 Fantom 本身编写。它可以通过 Eclipse 更新站点作为一组插件安装,或作为独立应用程序安装:

  • 首页

IntelliJ ​

IntelliJ 的 Fantom 语法高亮

  • GitHub

Netbeans FantomIDE(tcolar) ​

FantomIDE 是一个基于 Netbeans 的 Fantom 语言 IDE。它可以作为插件安装到现有的 Netbeans 安装中,也可以作为独立的 IDE 安装。它开箱即用支持 Fantom 以及 Java、Javascript、CSS、HTML、XML、Subversion、Mercurial。

  • 首页 下载

这个项目已经过时,不再维护。

TextMate 捆绑包 (msl) ​

TextMate 的 Fantom 插件包:

  • 首页

Sublime Text 3(mgiannini) ​

用于 Sublime Text 3 文本编辑器的 Fantom 插件。

  • sublime-fantom

Atom 编辑器 (mgiannini) ​

适用于 Atom 编辑器的 Fantom 插件。

  • language-fantom

Visual Studio 代码 (a-mackay) ​

用于 Visual Studio Code 编辑器的 Fantom 语法高亮。

  • a-mackay/fantom-语法高亮

文本编辑器 ​

Fantom 发行版在 "adm/tools" 下包含许多常用文本编辑器的配置文件,包括:

  • Emacs jEedit TextPad Vim

Flux ​

Fantom FWT 仓库包括一个非常基础的编辑器,叫做 Flux,它为 Fantom、Java、C 等提供语法颜色编码。

卡芒贝尔(tcolar) ​

Camembert 是一个免费的、开源的、轻量级的 IDE,完全用 Fantom 编写。

  • 首页

安装与配置 ​

Unix 设置 ​

Fantom 分发包是以 zip 文件的形式打包的。解压后,你应该将“bin”添加到你的路径中:

PATH=$PATH:/apps/fantom/bin

Fantom 启动器是作为一组 Bash shell 脚本实现的,这些脚本都路由到位于 "bin/fanlaunch" 的通用代码。当前的实现相当简单,并且要求你的环境中有可用的 "java" 命令。

如果解压后的 zip 文件没有在脚本文件上设置可执行权限,那么 "adm/unixsetup" 脚本将自动对所有 shell 脚本和 Fan 构建脚本调用 "chmod +x":

bash adm/unixsetup

可执行脚本 ​

Fantom 允许源文件的第一行以 "!" 开头,以作为 Unix shell 脚本运行:

#! /usr/bin/env fan
class Script { static Void main() { echo("hi") } }

chmod +x myscript.fan
./myscript.fan

Windows 安装 ​

Fantom 分发版打包为一个 zip 文件。解压后,你应该将 "bin" 目录添加到你的路径中:

PATH=%PATH%;C:\dev\fan\bin

Fantom 启动程序是作为一组 Windows 批处理脚本实现的,这些脚本都路由到“bin\fanlaunch.bat”中的公共代码。如果你的路径配置正确,你应该能够运行

fan -version

可执行脚本 ​

你总是可以使用 fan 启动器通过在命令行上传递它来运行脚本。但理想情况下,你会希望设置你的环境,以便可以将 fan 脚本直接作为可执行文件调用:

fan build.fan    // call using fan launcher explicitly
build            // call as executable script

以下一系列控制台命令将使“.fan”文件可执行,假设我们安装在“c:\dev\fan”下:

assoc .fan=Fan
ftype Fan=cmd.exe /c call "C:\dev\fan\bin\fan.bat" "%1" %*
set pathext=%pathext%;.fan

Java 运行时 ​

适用于 Windows 和 Unix 的启动器按以下顺序确定使用哪个 Java:

  1. 如果设置了 FAN_JAVA 环境变量,那么我们假设它指向要运行的 "java.exe"。如果设置了 JAVA_HOME 环境变量,那么我们使用 "${JAVA_HOME}/bin/java"。否则,我们回退到系统的 "java" 可执行文件。

您可以通过编辑 "etc/sys/config.props" 并设置 "java.options" 属性来配置 JVM 选项。这对于修改 JVM 的内存设置非常有用。

// etc/sys/config.props
java.options=-Xmx128M

Fantom 当前需要 Java 版本 1.8 或更高版本才能运行。编译源代码需要 Java 1.8。

你也可以通过将 "sys.jar" 添加到你的类路径并确保已设置 "fan_home" 环境变量或已设置 "fan.home" Java 系统属性,直接运行 Fantom,而无需启动器:

// via env var
C:\>set fan_home=c:\dev\fan
C:\>java -cp %fan_home%\lib\java\sys.jar fanx.tools.Fan -version

// via system property
C:\>java -cp c:\dev\fan\lib\java\sys.jar -Dfan.home=%fan_home% fanx.tools.Fan -version

每个工具对应不同的类,例如,要运行 fant,就运行 Java 类 fanx.tools.Fant。

Substitutes ​

启动器脚本的另一个功能是能够将特定的脚本文件映射到使用备用的Fantom运行时。该技术用于管理引导构建过程。

Fantom 程序作为 Windows 服务 ​

Fantom 安装程序在安装目录的 "bin" 文件夹中包含一个名为 fansc.exe 的二进制文件。"fansc"(风扇服务控制)二进制文件可用于将 Fantom 程序安装为 Windows 服务或卸载该服务。您可以在不带任何参数的情况下运行该程序以查看用法。使用 fansc 有一些要求。

  1. 为您的 Fantom 程序创建一个 Windows 批处理文件启动器。您可以使用 "bin" 目录中的任何启动器作为模板。您必须从具有提升/管理员权限的命令提示符运行 "fansc" 程序。

以下示例说明如何将默认的 WispService 安装为 Windows 服务:

// Create the bin/wisp.bat file with these contents:
@echo off
call %~dp0\fanlaunch.bat Fan wisp::WispService %*

// Now install it, configuring it to run on port 8080
C:\dev\fantom\fan\bin\> fansc.exe install MyWispService C:\dev\fantom\fan\bin\wisp.bat -port 8080

Java 扩展 ​

您可以将 Java JAR 添加到以下目录,以便让 Fantom 类加载器自动加载它们:

  • {home}/lib/java/ext/ {home}/lib/java/ext/

平台目录用于按平台不同而变化的 JAR。例如,SWT JAR 会分发在特定平台的目录中。你可以通过运行 “fan -version” 来验证你的平台。

将 Java JAR 添加到您的 Fantom 环境中的首选机制是将它们转换为 pod。

另请参见 JavaFFI。

JLine ​

在 Unix 和 OS X 环境中,在 Java 虚拟机中运行命令行应用程序(如 fansh)可能会不太方便,因为箭头键等控制键无法被处理。你可以将 JLine 添加到系统类路径中来解决这个问题。内置的 bash 启动脚本会自动将 "lib/java/jline.jar" 添加到类路径中。支持 JLine3 的 LineReader 和 JLine2 的 ConsoleReader。使用 JLine3 时支持的功能更多。如果未找到 JLine,则会使用 java.io.Console 作为备用。要将命令行支持集成到你的应用程序中,请使用 Console API。

较新的 Java 版本不支持将 jar 添加到 {java-home}/lib/ext。相反,如果您希望 jline 能在 Fantom 的所有安装中全局可用,请像这样将 classpath 设置为环境变量:

export CLASSPATH=/work/stuff/jline/jline-3.9.0.jar

Env ​

Fantom 的默认行为是将其所有文件管理在安装目录下。但你可以使用替代环境启动 Fantom,以自定义部署结构的方式。详情请参见 Env。