스칼라 :: SBT 명령어

0. SBT 사용법

simple build tool

build tool 이란 프로젝트를 진행할 때 컴파일, 실행, 테스트, 소스 구조 관리, 파일 삭제과 같은 일들을 간단한 명령어로 실행할 수 있도록 도와주는 도구이다.
예를 들어 컴파일러를 사용해서 프로젝트 내에 있는 100개의 소스코드를 컴파일한다고 하자. 만약 소스코드가 한 디렉토리 안에 있지 않다면 일일히 모든 디렉토리를 찾아 scalac를 사용해서 컴파일을 해줘야 할 것이다. 프로젝트의 규모가 커질수록 구조없이 관리하는 일은 불가능해진다.
sbt를 사용하면 프로젝트를 더 간편하게 관리할 수 있다.

일단 시작하기

가장 간단한 구조로 시작해보겠다.

1. 파일 구조 만들기.

hello라는 이름의 프로젝트를 만들려고 한다. 이 프로젝트 내에는 hello.scala 소스코드가 있어 컴파일 후 실행하면 'hello world’를 출력한다.
이를 sbt를 통해서 관리하고 싶을 때 우리는 간단한 구조를 지켜야 한다.

  • hello
    • build.sbt
    • src
      • main
        • java
        • scala
          • hello.scala
          • another.scala
      • test
        • java
        • scala
          • hellotest.scala
          • anothertest.scala
    • target

src/main/scala 폴더는 .scala로 끝나는 모든 소스코드들을 관리한다.
src/test/scala 폴더는 .scala로 끝나는 모든 테스트 코드들을 관리한다.
target 폴더는 컴파일된 바이트코드들이 보관된다.

아래 파일들을 해당 디렉토리에 맞게 넣어주자.

/* hello/src/main/scala/hello.scala */
object Hello extends App {
 // hello를 출력한다. 
 println("Hello")
}
/* hello/src/main/scala/user.scala */
class User(val name : String) {
}
// 유저 객체를 생성 테스트를 위해서 만든다. 
/* hello/test/main/scala/SetSuit.scala */
// 임의의 테스트 파일 
import collection.mutable.Stack
import org.scalatest._

class ExampleSpec extends FlatSpec with Matchers {

  "A Stack" should "pop values in last-in-first-out order" in {
    val stack = new Stack[Int]
    stack.push(1)
    stack.push(2)
    stack.pop() should be (2)
    stack.pop() should be (1)
  }

  it should "throw NoSuchElementException if an empty stack is popped" in {
    val emptyStack = new Stack[Int]
    a [NoSuchElementException] should be thrownBy {
      emptyStack.pop()
    } 
  }
}

build.sbt

build.sbt는 프로젝트의 이름과 버전, 사용하고자 하는 스칼라 버전과 필요한 라이브러리들을 명시하는 파일이다. 이 build.sbt 파일을 통해서 sbt는 프로젝트를 관리할 수 있게 된다.

/* hello/build.sbt */
name := "hello"

version := "0.0.1"

scalaVersion := "2.12.8"

libraryDependencies += "org.scalactic" %% "scalactic" % "3.0.5"

libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test"

build.sbt 파일은 := 을 명시적으로 사용해서 값을 할당한다. 특히 scala version을 명시함으로써 배포할 때 동일한 버전을 유도할 수 있다. libraryDependencies 는 += 으로 연결되어 있는데, 이는 라이브러리를 추가하기 위해서다.

2. sbt 실행하기

여기까지 왔다면 sbt를 실행해보자.

/* hello/ */
sbt

sbt를 실행한 후에 exit으로 나온 뒤 완성된 구조는 다음과 같을 것이다.

  • hello
    • build.sbt
    • project
    • src
      • main
        • java
        • scala
          • hello.scala
          • another.scala
      • test
        • java
        • scala
          • hellotest.scala
          • anothertest.scala
    • target

우리가 위의 build.sbt 파일에서 libraryDependencies로 지정해준 파일들은 다운로드가 끝난 뒤에 hello/target/streams/compile/managedClasspath 디렉토리에 관리된다. 만약 libraryDependencies를 사용하지 않고 java 외부 라이브러리를 jar 파일로 java에 넣는다면 sbt가 끝난후에는 hello/target/streams/compile/unmanagedClasspath 디렉토리에 관리될 것이다. (이 부분은 확실하지 않다)

3. 컴파일 및 실행하기

/* hello/ */
sbt
sbt:hello> compile 
sbt:hello> run 

4. console 활용해보기

우리가 생성한 소스코드를 가지고 잘 동작하는지 확인해보기 위해서 우리는 console이라는 기능을 활용해 볼 수 있다. 아무런 import없이 프로젝트 내에서 정의된 클래스들을 사용할 수 있다.

sbt 
sbt:hello> compile 
sbt:hello> console 

5. 그 외 명령어

/* hello/ */
sbt
sbt:hello> help 

help 명령어를 통해서 sbt를 통해서 실행가능한 기능들을 살펴볼 수 있다.
유용하게 쓰는 명령어들은 다음과 같다.

  • tasks : 해당 프로젝트에서 사용하는 주요 명령어들을 파악할 수 있다.
  • console : 줄 단위로 실행가능한 콘솔을 통해서 프로젝트 내에서 컴파일된 클래스들을 사용해 볼 수 있다.
  • clean : target에 컴파일된 모든 파일들을 삭제
  • settings : build.sbt에서 지정가능한 목록들과 설명을 보여준다.
  • reload : buils.sbt나 소스코드 등 프로젝트 내 변경사항이 있을 때 다시 로드해준다.
  • ~ compile : 관리하는 소스코드가 추가되거나 변경될 때 자동으로 컴파일하도록 한다.
  • compile : 소스코드를 컴파일한다.
  • run : test/src/ 소스코드를 실행한다.
  • test : 소스코드를 컴파일하고 실행한다. (compile + run)

댓글

이 블로그의 인기 게시물

[Linux, Unix] export, echo 명령어 알아보기

IEEE 754 부동 소수점 반올림과 근사