Это просто быстрое воспоминание о шагах, которые я предпринял, чтобы запустить свой собственный helloworld, используя scala-native. На самом деле я еще не начал подробно рассматривать родной язык scala, но идея, стоящая за ним, действительно хороша. Некоторые общие сведения о scala-native можно найти здесь:
- Репозиторий Github: https://github.com/scala-native/scala-native
- Презентация из Scaladays NY: https://github.com/densh/talks/blob/517b20c30dd4aaf390785039cdd002f623ea…
- Twitter, чтобы следовать: @scala_native
Поскольку scala-native зависит от доступности LLVM и Clang ++, эта настройка может отличаться в вашей среде, чем в моей. Я все еще на OS-X Yosemite:
|
1
2
3
4
|
$ sw_versProductName: Mac OS XProductVersion: 10.10.3BuildVersion: 14D136 |
Но для пользователей Mac шаги будут примерно такими же. Теперь давайте приступим к настройке среды, чтобы вы могли запустить пример проекта, предоставляемого scala-native, и мы также создадим базовый проект helloworld. Еще раз, эти шаги работали в моей среде, и ваши могут отличаться. Есть несколько проблем с github, за которыми вы можете следить или узнать больше о том, как настроить вашу среду.
Шаги, которые работали для меня, были следующие:
Проверка кода
Нам, конечно, сначала нужно получить код, из командной строки сделаем следующее:
|
1
2
3
4
5
6
7
|
$ git clone --recursive https://github.com/scala-native/scala-nativeCloning into 'scala-native'...remote: Counting objects: 8295, done.remote: Compressing objects: 100% (14/14), done.remote: Total 8295 (delta 3), reused 0 (delta 0), pack-reused 8278Receiving objects: 100% (8295/8295), 1.31 MiB | 94.00 KiB/s, done.Resolving deltas: 100% (2955/2955), done. |
Это должно, теоретически, получить вам все необходимые источники. Я, однако, столкнулся с первой проблемой, что субмодельная скала не вытащила правильно. Каким-то образом git хочет использовать аутентификацию с открытым ключом вместо https. Самый простой способ быстро решить эту проблему, просто сделать это:
|
01
02
03
04
05
06
07
08
09
10
11
12
|
$ cd scala-native/submodules$ git clone https://github.com/scala/scalaCloning into 'scala'...remote: Counting objects: 333614, done.remote: Total 333614 (delta 0), reused 0 (delta 0), pack-reused 333613Receiving objects: 100% (333614/333614), 83.31 MiB | 5.63 MiB/s, done.Resolving deltas: 100% (226320/226320), done.Checking connectivity... done.Checking out files: 100% (10492/10492), done. $ cd scala$ git checkout 2.11.x |
Публикуйте библиотеки локально
На данный момент у вас есть все необходимые источники, но при попытке его создать вы можете столкнуться со следующими проблемами:
|
1
2
3
4
5
6
7
8
|
# from the scala-native directory$ sbt> publish-local... lots of output[trace] Stack trace suppressed: run last scalalib/compile:compileIncremental for the full output.[trace] Stack trace suppressed: run last javalib/compile:doc for the full output.[error] (scalalib/compile:compileIncremental) java.lang.NoClassDefFoundError: scala/scalanative/nscplugin/NirGlobalAddons$nirPrimitives$[error] (javalib/compile:doc) java.nio.charset.MalformedInputException: Input length = 1 |
Почему-то, кажется, что-то не так с некоторыми скалярными вещами, что приводит к провалу нашего проекта. Откройте файл build.sbt и измените проект javalib . Чтобы решить эту проблему, мы можем просто отключить скалярные вещи, например, добавив следующие две строки:
|
1
2
|
sources in (Compile,doc) := Seq.empty,publishArtifact in packageDoc := false |
Сюда:
|
1
2
3
4
5
6
7
|
83 lazy val javalib =84 project.in(file("javalib")).85 settings(libSettings,86 sources in (Compile,doc) := Seq.empty,87 publishArtifact in packageDoc := false88 ).89 dependsOn(nativelib) |
Теперь снова выполните локальную публикацию, и это должно как минимум успешно завершиться:
|
1
2
3
4
5
|
> reload> publish-local... again, lots of output[info] published ivy to /Users/jos/.ivy2/local/org.scala-native/scalalib_2.11/0.1-SNAPSHOT/ivys/ivy.xml[success] Total time: 17 s, completed May 14, 2016 4:06:31 PM |
На данный момент мы можем попытаться запустить демонстрационное приложение, но вы, вероятно, столкнетесь со следующими двумя ошибками: (по крайней мере, я сделал)
|
1
2
3
4
5
6
7
8
|
# This one:/Users/jos/dev/git/scala-native-clean/scala-native/demo-native/target/scala-2.11/demonative-out.ll:152:40: error: expected '{' in function bodydeclare double @"llvm.sqrt.f64"(double) ^ # And this onert.cpp:3:10: fatal error: 'gc.h' file not found#include <gc.h> |
Ах … плохо. Что-то еще пошло не так. Первая ошибка вызвана неправильной версией LLVM (требуется 3.7, у меня версия 3.6), а вторая — тем, что библиотеки Boehm GC недоступны.
Настройте LLVM и Clang ++ правильно
Я не знаю, какая версия на более новых версиях OS-X, но у меня все еще было 3.6:
|
1
2
3
4
|
$ clang++ -vApple LLVM version 6.1.0 (clang-602.0.49) (based on LLVM 3.6.0svn)Target: x86_64-apple-darwin14.3.0Thread model: posix |
Чтобы это исправить, не вмешиваясь, возможно, в другие инструменты, в зависимости от 3.6, я использовал brew для установки 3.7 версии LLVM и Clang ++. Возможно, вам придется сначала сделать ** brew tap homebrew / version **, если вы не можете найти llvm37
|
01
02
03
04
05
06
07
08
09
10
11
12
|
$ brew install llvm37 --with-clang==> Installing llvm37 from homebrew/versions==> Downloading https://homebrew.bintray.com/bottles-versions/llvm37-3.7.1.yosemite.bottle.1.tar.gzAlready downloaded: /Library/Caches/Homebrew/llvm37-3.7.1.yosemite.bottle.1.tar.gz==> Pouring llvm37-3.7.1.yosemite.bottle.1.tar.gz==> CaveatsExtra tools are installed in /usr/local/opt/llvm37/share/clang-3.7 To link to libc++, something like the following is required: CXX="clang++-3.7 -stdlib=libc++" CXXFLAGS="$CXXFLAGS -nostdinc++ -I/usr/local/opt/llvm37/lib/llvm-3.7/include/c++/v1" LDFLAGS="$LDFLAGS -L/usr/local/opt/llvm37/lib/llvm-3.7/lib" |
Вы можете увидеть каталог, в котором установлены Clang и LLVM. Прежде чем мы снова запустим SBT, нам нужно создать символическую ссылку, чтобы плагин мог найти правильный исполняемый файл clang .
|
1
2
|
$ cd /usr/local/opt/llvm37/bin$ ln -s clang++-3.7 clang++ |
И, наконец, нам просто нужно обновить переменную PATH, чтобы она указала на каталог установки перед запуском SBT :
|
1
2
3
4
5
|
$ export PATH=/usr/local/opt/llvm37/bin:$PATH$ clang++ -vclang version 3.7.1 (tags/RELEASE_371/final)Target: x86_64-apple-darwin14.3.0Thread model: posix |
На данный момент у нас должна быть одна из наших проблем, поэтому давайте просто проверим, что произойдет, если мы попробуем запустить демо:
|
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
|
<br/># go back to the directory where you cloned scala-native$ cd ~/dev/git/scala-native-clean/scala-native$ sbt> demoNative/run[info] Updating {file:/Users/jos/dev/git/scala-native-clean/scala-native/}demoNative...[info] Resolving org.scala-lang#scalap;2.11.8 ...[info] Done updating.[info] Compiling 1 Scala source to /Users/jos/dev/git/scala-native-clean/scala-native/demo-native/target/scala-2.11/classes...warning: overriding the module target triple with x86_64-apple-macosx10.10.0 [-Woverride-module]1 warning generated./Users/jos/.scalanative/rtlib-0.1-SNAPSHOT/rt.cpp:3:10: fatal error: 'gc.h' file not found#include <gc.h> ^1 error generated. |
Как видите, у нас на одну ошибку меньше, но все равно что-то не так
Установить библиотеку Boehm GC
Чего не хватает и на что указывает ошибка, так это библиотеки Boehm GC. Есть несколько способов установить это. Мы можем использовать предварительно упакованный экземпляр brew или просто загрузить исходные тексты напрямую и установить Boehm таким образом. В этом примере мы сделаем последнее. Это означает, что следуйте инструкциям здесь: http://hboehm.info/gc/
|
01
02
03
04
05
06
07
08
09
10
11
|
$ mkdir boehm$ cd boehm$ git clone https://github.com/ivmai/libatomic_ops.git$ git clone https://github.com/ivmai/bdwgc.git$ cd bdgwc$ ln -s ../libatomic_ops$ autoreconf -vif$ automake --add-missing$ ./configure$ make$ sudo make install |
Кроме того, вы также можете установить пакет bdw-gc в brew.
|
1
|
$ brew install bdw-gc |
И после этого добавьте следующий build.sbt в демонстрационный проект с дополнительными настройками clang:
|
1
2
|
$ cat build.sbtnativeClangOptions := Seq("-I/usr/local/Cellar/bdw-gc/7.4.2/include", "-L/usr/local/Cellar/bdw-gc/7.4.2/lib") |
Однако я предпочитаю установку из источника *. На данный момент мы должны запустить демо.
|
1
2
3
4
|
> demoNative/runwarning: overriding the module target triple with x86_64-apple-macosx10.10.0 [-Woverride-module]1 warning generated.Rendering (8 spp) 100.00%[success] Total time: 13 s, completed May 14, 2016 6:30:42 PM |
Woohoo … успех !!! Чтобы увидеть, что мы на самом деле выполняем код, сделаем небольшое изменение в источнике в каталоге demoNative. В файле smallpt.scala измените количество семплов на 8 следующим образом:
|
1
2
3
4
|
153 final val W = 800154 final val H = 600155 final val SAMPLES = 8156 def main(args: Array[String]): Unit = { |
Теперь запустите программу снова (что должно занять намного больше времени):
|
1
2
3
4
5
|
> demoNative/run[info] Compiling 1 Scala source to /Users/jos/dev/git/scala-native-clean/scala-native/demo-native/target/scala-2.11/classes...warning: overriding the module target triple with x86_64-apple-macosx10.10.0 [-Woverride-module]1 warning generated.Rendering (32 spp) 100.00%[success] Total time: 52 s, completed May 14, 2016 6:34:11 PM |
Кажется, это работает. Кстати, результатом этой программы является трехмерная отрисованная сцена (пример программы — raytracer). Если вы установите большое количество сэмплов, вы получите довольно хороший рендер:
Мы также можем проверить, является ли вывод настоящей нативной программой:
|
1
2
3
4
5
|
otool -L demonative-outdemonative-out: /usr/local/lib/libgc.1.dylib (compatibility version 2.0.0, current version 2.3.0) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1213.0.0) |
Теперь давайте создадим пустой проект helloworld, где мы создадим собственную минимальную программу native-scala.
Helloworld scala-native
В проекте scala-native создайте новый каталог с именем helloworld-native. В этом каталоге создайте следующий файл (** helloworld.scala **):
|
01
02
03
04
05
06
07
08
09
10
|
package helloworld import scalanative.native._, stdlib._ object Main { def main(args: Array[String]): Unit = { fprintf(__stdoutp, c"Hello World: Scala Native!!!") }} |
Прежде чем мы сможем запустить его, нам также необходимо обновить основной файл build.sbt и определить этот проект. Для этого добавьте следующее:
|
1
2
3
4
5
6
7
8
|
lazy val helloworldNative = project.in(file("helloworld-native")). settings(libSettings). settings( nativeVerbose := true, nativeClangOptions := Seq("-O2") ). dependsOn(scalalib) |
Не забудьте использовать Seq («- I / usr / local / Cellar / bdw-gc / 7.4.2 / include», «-L / usr / local / Cellar / bdw-gc / 7.4.2 / lib») для Ваше определение сборки helloworld, если вы не устанавливаете Boehm GC с нуля.
Теперь перезагрузите sbt, и вы сможете запустить наше собственное scala-native приложение:
|
1
2
3
4
5
|
> helloworldNative/run[info] Compiling 1 Scala source to /Users/jos/dev/git/scala-native-clean/scala-native/helloworld-native/target/scala-2.11/classes...warning: overriding the module target triple with x86_64-apple-macosx10.10.0 [-Woverride-module]1 warning generated.Hello World: Scala Native!!! |
Или мы можем просто запустить его из командной строки напрямую:
|
1
2
3
4
|
$ pwd/Users/jos/dev/git/scala-native-clean/scala-native/helloworld-native/target/scala-2.11$ ./helloworldnative-outHello World: Scala Native!!! |
Я надеюсь, что вы также можете начать с этого краткого вступления. Если позволит время, я планирую немного глубже погрузиться в родной язык scala и изучить некоторые его особенности.
| Ссылка: | Начало работы с scala-native от нашего партнера JCG Йоса Дирксена в блоге Smart Java . |