多年前有人问为什么c#不允许像Java这样的增量编译.El Skeet说它与Java输出.class文件而不是程序集有关.
现在已经发布了像Mono编译器即服务这样的2011年和常规事物,为c#创建增量编译器需要做些什么?
编辑:大家都在谈论这不是一个问题,这里是Jon Skeet从我链接到的主题的引用:
你是建议你永远不会发现自己在等待构建?甚至15秒?如果一个构建需要15秒,你想在一小时内建立20次(我当然使用TDD),这意味着我浪费了5分钟.休息5分钟是一回事 - 这是一种放松等待的好方法 - 但是被耽搁15次20次可能会非常令人沮丧.做任何有用的东西都不够长(除了喝一杯),但它足够刺激.
我怀疑有两个因素会导致我感到烦恼的程度,其他人显然没有:1)TDD真的依赖于更快的转变2)在Eclipse中使用Java时,这种延迟非常罕见
有很多关于创建编译器的书籍和文章,它们一次完成所有编译工作.那些IDE使用的增量编译器/解析器的设计呢?我熟悉第一类编译器,但我从未使用过第二类编译器.
我试图阅读一些关于Eclipse Java开发工具的文章,但是他们描述了如何使用完整的基础结构(即API)而不是描述内部设计(即它如何在内部工作).
我的目标是为我自己的编程语言实现增量编译器.你会推荐哪些书籍或文章?
最近我开始使用Eclipse的java编译器,因为它比标准的javac快得多.我被告知它更快,因为它执行增量编译.但我仍然有点不确定,因为我找不到任何关于eclispse和sun的编辑器"增量功能"的权威文档.是不是Sun的编译器总是编译每个源文件而Eclipse的编译器只编译已更改的文件和那些受此类更改影响的文件?
编辑:我没有使用Eclipse autobuild功能,而是我正在设置
-Dbuild.compiler=org.eclipse.jdt.core.JDTCompilerAdapter
Run Code Online (Sandbox Code Playgroud)
为我的蚂蚁构建.
在Scala中,从增量编译器(sbt,Eclipse中的sbt,IntelliJ)的功效和速度的角度来看,使用通配符导入是不是很糟糕?是否会对这些增量编译器决定在更改时重新编译的内容的方式产生负面影响?
例如,如果对于一个新类X,我只需要从包中导入类A和B(而不是C)pack,我是否会因此而受到惩罚:
import pack._
Run Code Online (Sandbox Code Playgroud)
而不是这个?
import pack.{ A, B }
Run Code Online (Sandbox Code Playgroud)
假设A并且B不依赖于C,将X使用通配符导入重新编译,而不是在C更改时使用更具体的导入,或者依赖关系跟踪系统是否足够智能以实现尽管通配符导入C未使用X?
正如Eclipse文档所建议的那样,我有一个org.eclipse.core.resources.IncrementalProjectBuilder编译每个源文件的文件,我也有一个org.eclipse.ui.editors.text.TextEditor可以编辑每个源文件的文件.每个源文件都编译到自己的编译单元中,但它可以引用其他(已编译的)源文件中的类型.
这个重要的两项任务是:
为了实现这一点,我想在内存中存储所有已编译类型的表示(以下称为"类型存储").
我的问题有两个:
上面的任务1由构建器执行,而任务2由编辑器执行.因此,他们都可以访问这种类型的商店,我应该创建一个他们都可以访问的静态存储,还是Eclipse提供了一种更简洁的方法来处理这个问题?请注意,在需要时实例化构建器和编辑器是eclipse,而不是我.
打开eclipse时,我不想重建整个项目,所以我可以重新填充我的类型存储.到目前为止,我最好的解决方案是将这些数据保存在某处,然后从那里重新填充我的商店(也许在项目打开时).这是其他增量编译器通常如何做到这一点的吗?我相信Java的方法是使用一个特殊的解析器,从类文件中有效地提取这些数据.
任何见解都会非常感激.这是我的第一个DSL.
eclipse-plugin incremental-linking incremental-build incremental-compiler
我知道Eclipse使用它自己的Java编译器(ECJ),它能够执行增量编译.从我发现的大多数读数来看,这个编译通常是由保存操作触发的,但这似乎与在输入单个单元/单词代码后几乎立即得到编译错误的错误反馈这一事实相匹配.我没有找到任何文档或文献说明这是什么粒度被触发(即每个单词,字母,行)?是否还有其他背景代码分析?虽然除了语法中的错误检测之外,我看不出它如何能够检测只能通过编译过程显示的语义错误.
在 LLVM 中,我们有LLVMContext,这是存储单元,我们有llvm::Module,这是构建新符号(函数和类型)的地方。
我的问题是;用于编译单元的正确 llvm 抽象是什么?是Module?或者这实际上意味着更大的范围,即:共享库目标
在我看来,编译单元必须满足全有或全无的结果;要么它编译所有内容都没有错误,要么存在错误,需要在 CU 中的任何符号可用之前对其进行修复和重新构建。在我看来,这是编译单元应该代表什么的定义
如果模块是 CU 的正确抽象,我如何将其他(正确编译的)Module对象中的符号呈现给即将构建的新模块,以便它能够找到那些?我需要添加声明还是有其他一些快捷方式?
指向相关行的点将clang有很大帮助
在我们的项目中,我们对通过编译生成的.class文件进行了增强后处理.此增强步骤实际上会修改生成的.class文件,然后覆盖它.
enhance <<= enhance triggeredBy (compile in Compile)
Run Code Online (Sandbox Code Playgroud)
问题是sbt有一种称为增量重新编译的机制.它监视生成的.class文件.每次增强器覆盖生成的.class文件时,sbt都会识别这些修改并在下一个编译命令中重新编译相关的源.
对我们来说,重新编译是一项非常耗时的工作.我们希望阻止sbt重新编译修改后的.class文件.这可能意味着使sbt仅监视源更改,而不是输出更改.
我做了一些搜索.但我发现了一些关于这一点的事情.现在我知道一个名为Analysis的特性可能负责从源到输出.class文件的映射.所以我向你们求助.
Ps:我们可以通过将增强的输出放到另一个文件夹来解决这个问题,但不是首选.
我正在学习一点汇编,对于我的下一个项目,我想学习如何制作增量汇编器。我所说的“增量汇编器”是指在运行时接受新代码的汇编器。
一般来说,汇编的工作流程是编写文件并将它们提供给汇编器+链接器,并在另一端获取可执行文件。将此与基于图像的系统(例如 Smalltalk 或 SBCL (lisp))进行对比,在这些系统中,您有一个正在运行的图像,并且可以增量地向其中添加函数/表达式。
有谁知道在这样的系统中这是如何实现的?假设我们正在使用 Linux 操作系统,他们是否只是简单地编辑 ELF 文件并在每次执行新函数/表达式时重新加载整个映像?或者有没有办法加载 ELF 文件的内容,然后在其上动态执行程序集(即不向磁盘写入任何其他文件)?
有人可以给我举一个最小的例子吗?或有关此类基于图像的系统及其制作方法的书籍/博客?
我是一个局外人,试图看看Rust是否适合我的项目.
我读过Rust缺少渐进式编译(尽管有beta版功能).
incremental-linking incremental-build rust incremental-compiler