前言

最近为了解决Spark2.1的Bug,对Spark的源码做了不少修改,需要对修改的代码做编译测试,如果编译整个Spark项目快的话,也得半小时左右,所以基本上是改了哪个子项目就单独对那个项目编译打包。

Spark官方已经给出了如何使用mvn单独编译子项目的方法:http://spark.apache.org/docs/latest/building-spark.html#building-submodules-individually

使用mvn单独编译子项目是节约了不少时间。但是频繁的改动项目,每次用mvn编译还是挺耗时间的。

之前看官方文档提到,对于开发者,为了提高效率,推荐使用sbt编译。于是,又查了下文档资料:http://spark.apache.org/developer-tools.html

咦,看到:Running Build Targets For Individual Projects,内容如下:

$ # sbt
$ build/sbt package
$ # Maven
$ build/mvn package -DskipTests -pl assembly

这不是坑么,虽然没怎么用sbt编译过Spark,但是sbt俺还是用过的。build/sbt package明明是编译整个项目的好吧,这哪是编译子项目啊。

翻遍官方所有跟编译有关的资料,无果。

最后,研究了下Spark的sbt定义,也就是下project/SparkBuild.scala文件,找到了使用sbt编译子项目的方法。

使用sbt编译子项目

下面是对spark-core重新编译打包的方法,我们需要使用REPL模式,大致的流程如下:

➜  spark git:(branch-2.1.0) ✗ ./build/sbt -Pyarn -Phadoop-2.6 -Phive
...
[info] Set current project to spark-parent (in build file:/Users/stan/Projects/spark/)
> project core
[info] Set current project to spark-core (in build file:/Users/stan/Projects/spark/)
> package
[info] Updating {file:/Users/stan/Projects/spark/}tags...
[info] Resolving jline#jline;2.12.1 ...
...
[info] Packaging /Users/stan/Projects/spark/core/target/scala-2.11/spark-core_2.11-2.1.0.jar ...
[info] Done packaging.
[success] Total time: 213 s, completed 2017-2-15 16:58:15

最后将spark-core_2.11-2.1.0.jar替换到jars或者assembly/target/scala-2.11/jars目录下就可以了。

选择的子项目的关键是project命令,如何知道有哪些定义好的子项目呢?这个还得参考project/SparkBuild.scala中BuildCommons的定义:

object BuildCommons {

  private val buildLocation = file(".").getAbsoluteFile.getParentFile

  val sqlProjects@Seq(catalyst, sql, hive, hiveThriftServer, sqlKafka010) = Seq(
"catalyst", "sql", "hive", "hive-thriftserver", "sql-kafka-0-10"
).map(ProjectRef(buildLocation, _)) val streamingProjects@Seq(
streaming, streamingFlumeSink, streamingFlume, streamingKafka, streamingKafka010
) = Seq(
"streaming", "streaming-flume-sink", "streaming-flume", "streaming-kafka-0-8", "streaming-kafka-0-10"
).map(ProjectRef(buildLocation, _)) val allProjects@Seq(
core, graphx, mllib, mllibLocal, repl, networkCommon, networkShuffle, launcher, unsafe, tags, sketch, _*
) = Seq(
"core", "graphx", "mllib", "mllib-local", "repl", "network-common", "network-shuffle", "launcher", "unsafe",
"tags", "sketch"
).map(ProjectRef(buildLocation, _)) ++ sqlProjects ++ streamingProjects val optionallyEnabledProjects@Seq(mesos, yarn, java8Tests, sparkGangliaLgpl,
streamingKinesisAsl, dockerIntegrationTests) =
Seq("mesos", "yarn", "java8-tests", "ganglia-lgpl", "streaming-kinesis-asl",
"docker-integration-tests").map(ProjectRef(buildLocation, _)) val assemblyProjects@Seq(networkYarn, streamingFlumeAssembly, streamingKafkaAssembly, streamingKafka010Assembly, streamingKinesisAslAssembly) =
Seq("network-yarn", "streaming-flume-assembly", "streaming-kafka-0-8-assembly", "streaming-kafka-0-10-assembly", "streaming-kinesis-asl-assembly")
.map(ProjectRef(buildLocation, _)) val copyJarsProjects@Seq(assembly, examples) = Seq("assembly", "examples")
.map(ProjectRef(buildLocation, _)) val tools = ProjectRef(buildLocation, "tools")
// Root project.
val spark = ProjectRef(buildLocation, "spark")
val sparkHome = buildLocation val testTempDir = s"$sparkHome/target/tmp" val javacJVMVersion = settingKey[String]("source and target JVM version for javac")
val scalacJVMVersion = settingKey[String]("source and target JVM version for scalac")
}

我们看下这个例子:

  val sqlProjects@Seq(catalyst, sql, hive, hiveThriftServer, sqlKafka010) = Seq(
"catalyst", "sql", "hive", "hive-thriftserver", "sql-kafka-0-10"
).map(ProjectRef(buildLocation, _))

这是对sql项目定义的子项目,有:catalyst, sql, hive, hive-thriftserver, sql-kafka-0-10

我们如果需要编译catalyst这个项目,只需要进入sbt:project catalyst选择catalyst项目就可以了,后面使用的compile、package等命令都是针对这个项目的。

多谢知乎@凤凰木的评论,还有一种非REPL的编译方式,比如要编译hive项目,我们可以直接在Spark源码目录下执行build/sbt hive/package

使用sbt执行单个测试

示例:build/sbt "~catalyst/test-only *FoldablePropagationSuite"

对catalyst项目执行测试,只测试FoldablePropagationSuite结尾的类。

~是对开发非常有用的东西,他表示进行持续测试,如果我们执行测试后发现case没有过,那么可以在不退出测试的情况下,直接去修改代码,保存代码后,sbt会再次执行测试。

如果需要对一个子项目执行测试,只需要执行:build/sbt sql/test(对sql项目做测试)。

结语

这下可以爽爽的编译Spark了。

还有一些有用的编译技巧,去参考http://spark.apache.org/developer-tools.html就可以了。

使用SBT编译Spark子项目的更多相关文章

  1. sbt编译spark程序提示value toDF is not a member of Seq()

    sbt编译spark程序提示value toDF is not a member of Seq() 前提 使用Scala编写的Spark程序,在sbt编译打包的时候提示value toDF is no ...

  2. [转] 用SBT编译Spark的WordCount程序

    问题导读: 1.什么是sbt? 2.sbt项目环境如何建立? 3.如何使用sbt编译打包scala? [sbt介绍 sbt是一个代码编译工具,是scala界的mvn,可以编译scala,java等,需 ...

  3. window环境下使用sbt编译spark源码

    前些天用maven编译打包spark,搞得焦头烂额的,各种错误,层出不穷,想想也是醉了,于是乎,换种方式,使用sbt编译,看看人品如何! 首先,从官网spark官网下载spark源码包,解压出来.我这 ...

  4. 用SBT编译Spark的WordCount程序

    问题导读: 1.什么是sbt? 2.sbt项目环境如何建立? 3.如何使用sbt编译打包scala? sbt介绍 sbt是一个代码编译工具,是scala界的mvn,可以编译scala,java等,需要 ...

  5. 编译spark源码 Maven 、SBT 2种方式编译

    由于实际环境较为复杂,从Spark官方下载二进制安装包可能不具有相关功能或不支持指定的软件版本,这就需要我们根据实际情况编译Spark源代码,生成所需要的部署包. Spark可以通过Maven和SBT ...

  6. 使用 IntelliJ IDEA 导入 Spark源码及编译 Spark 源代码

    1. 准备工作 首先你的系统中需要安装了 JDK 1.6+,并且安装了 Scala.之后下载最新版的 IntelliJ IDEA 后,首先安装(第一次打开会推荐你安装)Scala 插件,相关方法就不多 ...

  7. Spark-1.0.1 的make-distribution.sh编译、SBT编译、Maven编译 三种编译方法

    fesh个人实践,欢迎经验交流!本文Blog地址:http://www.cnblogs.com/fesh/p/3775343.html 本文编译方法所支持的hadoop环境是Hadoop-2.2.0, ...

  8. Spark笔记--使用Maven编译Spark源码(windows)

    1. 官网下载源码 source code,地址: http://spark.apache.org/downloads.html 2. 使用maven编译: 注意在编译之前,需要设置java堆大小以及 ...

  9. 如何搭建SBT编译Scala开发的Android工程

    作者:戚明峰 最近接触了shadowsocks的Android客户端项目源码(https://github.com/shadowsocks/shadowsocks-android),刚好这个项目是使用 ...

随机推荐

  1. Photoshop 画基本图形

    作者:zccst 1,画三角形 按下“U”选择“多边形工具”(是个六边形的图标),在上方的菜单栏中的“边”后面输入“3”,然后在画布中拖动就是三角形了,画好后按下CTRL+ENTER键转化成选区,然后 ...

  2. JUCE_FIFO实现分析

    JUCE_FIFO代码简单剖析,此处的剖析就是给自己留一个方便查询的内容:不做太多内容的要求,只做简单的记录:本文以初学者的角度来些,大牛请飘过O(∩_∩)O FIFO的功能在博客的其他帖子里面已经有 ...

  3. 配置Linux Kernel时make menuconfig执行流程分析

       在编译内核前,一般是根据已有的配置文件(一般在内核根目录下的arch/arm/configs/文件夹下,把该目录下的xxx_defconfig文件拷贝到内核根目录下,并重命名为.config)来 ...

  4. Android实现渐显按钮的左右滑动效果

    本示例演示在Android中实现带渐显按钮的左右滑动效果. 关于滑动效果,在我的上一篇博文中提到过,有兴趣的朋友可以访问: http://www.cnblogs.com/hanyonglu/archi ...

  5. UVa 10473 - Simple Base Conversion

    题目大意:十进制与十六进制之间的相互转换. #include <cstdio> int main() { #ifdef LOCAL freopen("in", &quo ...

  6. WDA 程序文本翻译OTR

    1.针对直接使用表字段,数据元素的情况: 1.1修改数据元素对应的语言值:DD04T. 1.2模拟SE63插入翻译条目:LXE_LOG 1.3运行时文件翻译条目:DDFTX *&------- ...

  7. ArcGisServer根据最大最小坐标换算瓦片行列号(转载)

    ArcGisServer根据最大最小坐标换算瓦片行列号 1.前言 在上一节中我们知道了屏幕上一像素等于实际中多少单位长度(米或经纬度)的换算方法,而知道这个原理后,接下来我们要怎么用它呢?它和我们前端 ...

  8. CMake Tutorial

    1.最简实例 使用cmake的最简实例是由一个源程序文件生成一个可执行文件.例如由下述C++源程序文件生成可执行文件tutorial. main.cpp #include<iostream> ...

  9. Spring中各个jar包的作用

    spring.jar 是包含有完整发布模块的单个jar 包.但是不包括mock.jar, aspects.jar, spring-portlet.jar, and spring-hibernate2. ...

  10. java中String相等问题

    java中判断两个字符串是否相等的问题   判断两个字符串是否相等的问题.在编程中,通常比较两个字符串是否相同的表达式是"==",但在java中不能这么写.在java中,用的是eq ...