non vorrei lavorare

ブログ名の通りです。javascript three.js mruby rust OCaml golang julialang blender

MSVC版のVimをビルドしたくて、Win32.makを入れるの滅茶苦茶手間取った件

この記事は@kjunichiのパーソナルアドベントカレンダーの17日目の記事です。

:terminalが使えるVim

github.com

をTLで見かけ、Surface Goに:terminalが使えるVimを入れてないことを思い出して、 MSVC版のVimをビルドするにはWin32.makが必要で、Windows 7.1 SDKを入れるないといけないことも 思い出した。

VS2017にWin7.1 SDK

とりあえず見つけたのが、

入手可能な Windows SDK について – JAPAN Platform SDK(Windows SDK) Support Team Blog

しかし、インストーラーが起動してインストールしているようだが、最終的にはwin32.makがインストールされない。

そこで、さらに調査を進めw、

qiita.com

を見つけ、これでwin32.makが入ると思いきや、インストールされず。。

インストーラのログをたまたま見つけて、覗くと、

21:19:17 2018年12月16日: [SDKSetup:Info] File succesfully downloaded - source:file://rmbp.local/GRMSDKX_EN_DVD/Setup/WinSDKNetFxTools_amd64/cab1.cab target:file:///C:/Users/kjunichi/AppData/Local/Temp/SDKSetup/WinSDKNetFxTools/WinSDKNetFxTools_amd64/cab1.cab size:6844196

と怪しげなcabファイルの存在を知り、file:///C:/Users/kjunichi/AppData/Local/Temp/SDKSetup/WinSDKNetFxTools/WinSDKNetFxTools_amd64フォルダにsetup.exe相当のインストーラーを起動。

すると、何かのインストールが始まり、これが完了して、Win32.makを探すもインストールされていない。

が、このあと、SDKのSDKSetup.exeを再度起動すると、修復オプションが選べるようになって、ここで、改めて、 ヘッダ、ライブラリのチェックをつけてインストール。

これで念願のwin32.makが手に入り、Surface GoでVimをビルドできた。

関連記事

6年前の記事

4年前の記事

2年前の記事

1年前の記事

N-APIはホントにV8以外のJavaScriptエンジンでもリビルドなしでネイティブモジュールが動くのか

qiita.com

この記事はNode.js Advent Calendar 2018の16日目の記事です。 また、ここ数年チャレンジしている@kjunichiのパーソナルアドベントカレンダーの16日目の記事も兼ねてます。

まえがき

Node.jsとは直接関係ないが、V8をPostgreSQLで動かせるplv8にWindows対応のプルリク投げた前科がある。

github.com

このプルリクは残念がらマージに至らなかったが、作者の方が、対応して現在、少し頑張れば、Windowsでも 新しいplv8がビルドできるハズ。

v8以外のエンジンのnode.jsに切り替えられるバージョン管理ツールの導入

とりあえず、macOS mojaveで試す。

node.jsではnvmがメジャーなバージョン管理ツールですが、chakracoreなnode.jsを試すには、以下のnvsが 便利です。

github.com

READMEに従って以下のように入れた。

export NVS_HOME="$HOME/.nvs"
git clone https://github.com/jasongin/nvs "$NVS_HOME"
. "$NVS_HOME/nvs.sh" install

chakracoreを入れる

nvsコマンドで対話的にchakracoreを入れられる。

nvs ls

とする事で、現在インストールされているnode.jsの一覧と選択されているnode.jsが表示される。

  node/10.14.2/x64 (Dubnium)
  node/10.13.0/x64 (Dubnium)
  node/10.12.0/x64
  node/10.7.0/x64
 >chakracore/10.13.0/x64 (Dubnium)

node-gypを入れる

N-APIに限らず、node.jsでネイティブモジュールを作る際に必要なnode-gypを入れる。

npm install -g node-gyp

N-APIを使ったモジュールを作る

以下のリポジトリをクローンしてN-APIのモジュールを用意。

github.com

git clone https://github.com/schahriar/n-api-article.git
cd n-api-article/Getting_Started

以下のコマンドでモジュールをビルドする。

node-gyp configure build

最後に以下のように表示されればモジュールのビルドに成功している。

  CC(target) Release/obj.target/module/src/module.o
  SOLINK_MODULE(target) Release/module.node
gyp info ok 

動かす

念の為、ここでどのnode.jsを使っているかを確認する。

node -p -e process.versions
{ http_parser: '2.8.0',
  node: '10.13.0',
  chakracore: '1.11.1.0',
  uv: '1.23.2',
  zlib: '1.2.11',
  ares: '1.14.0',
  modules: '64',
  nghttp2: '1.34.0',
  napi: '3',
  openssl: '1.1.0i',
  icu: '62.1',
  unicode: '11.0',
  cldr: '33.1',
  tz: '2018e' }

と、chakracoreの文字列が入っているので、v8エンジンでは無い事が確認できた。

それでは、実行してみる。

node module.js 



JSエンジンを変更して実行してみる

今度はJSエンジンをv8に変更して実行。

nvsコマンドで通常のnode.jsを入れて、

nvs ls
>node/10.14.2/x64 (Dubnium)
  node/10.13.0/x64 (Dubnium)
  node/10.12.0/x64
  node/10.7.0/x64
  chakracore/10.13.0/x64 (Dubnium)

だめ押しで、

node -p -e process.versions
{ http_parser: '2.8.0',
  node: '10.14.2',
  v8: '6.8.275.32-node.45',
  uv: '1.23.2',
  zlib: '1.2.11',
  ares: '1.15.0',
  modules: '64',
  nghttp2: '1.34.0',
  napi: '3',
  openssl: '1.1.0j',
  icu: '62.1',
  unicode: '11.0',
  cldr: '33.1',
  tz: '2018e' }
node module.js
8 times 2 equals 16

動いた!

Windows10でもやってみた

Windowsでnodeのネイティブモジュールをビルドできるようにするのに手っ取り早いのは

npm install --global --production windows-build-tools --vs2017

としてwindows-build-toolsを入れてしまうのがお手軽。

Rustを入れた時、構成変更して、C++周りのツールやらライブラリを入れる必要があったが、 対応できるので、Node.js以外の処理系でC/C++のMSの処理系が必要なら、これで入れてしまうのが楽。

Windowsではnvsを常用しているものの、chakracoreをこれまで入れた事なかったw。

前述のmacOS同様にchakracoreなnode.jsnvsで入れて、 node-gypを入れる。

トラブル発生!

以下のように、node-gypでモジュールをビルドしたら、

node-gyp configure build

以下のように、リンクでエラーが発生。

LINK : fatal error LNK1181: 入力ファイル 'chakracore.lib' を開けません。 [C:\Users\kjunichi\Documents\work\nod
ejs\n-api-ar
ticle\Getting_Started\build\module.vcxproj]

WindowsではMSVCでは共有ライブラリを利用する際に、ビルド時にリンカーに.libファイルを参照させる必要がある。 このエラーは、この.libファイルが見つからないというエラー。

対応方法

%homepath%\.node-gyp配下にchakracore版のnode.jsの.libファイルをコピーする。

コピー元の.libファイルは%homepath%\AppData\Local\nvs\chakracore\配下にある。 この記事を書いた際は

%homepath%\AppData\Local\nvs\chakracore\10.13.0\x64\sdk\Release

に配置されていた。

コピー先の詳細なパスは後述のmodule.vcxprojのAdditionalDependenciesセクションのnode.libのパスの指定に従い、 そこにコピーする。

buildフォルダのmodule.vcxprojファイルのchakracore.libの指定個所を先ほどコピーしたするパスで指定する。

複数箇所あるので、検索して該当個所を書き換える。

変更前

<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;DelayImp.lib;&quot;C:\Users\kjunichi\.node-gyp\10.13.0\x64\node.lib&quot;;chakracore.lib</AdditionalDependencies>

変更後

<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;DelayImp.lib;&quot;C:\Users\kjunichi\.node-gyp\10.13.0\x64\node.lib&quot;;&quot;C:\Users\kjunichi\.node-gyp\10.13.0\x64\chakracore.lib&quot;</AdditionalDependencies>

configureをつけずに

node-gyp build
  module.vcxproj -> C:\Users\kjunichi\Documents\work\nodejs\n-api-article\Getting_Started\build\Release\\modu
  le.node
gyp info ok

あとは、macOSの時同様、JSのエンジンを切り替えてもリビルドなしで、動かせた。

まとめ

N-APIの謳い文句通りにリビルドなしで、v8エンジンでもMSのchakracoreエンジンでもネイティブモジュールが 動くとこが確認できた。

本命?のWindowsでは.libファイルの扱いがnvs側の考慮不足なのか、node-gyp側なのかとにかく上手く扱われていないので、 node-gyp一発で作業ができないことが分かった。

あと、

myakura.hatenablog.com

に書いてあるような状況なので、chakracoreの未来は暗いのかも。。

Rustで実装されているRapidusがN-APIに対応する事に期待。

関連記事

10年前の記事

4年前の記事

3年前の記事

2年前の記事

1年前の記事

Juliaでゼータ関数を直接jupyterにプロットしたり、マインクラフト(MCPI)にプロットした

この記事はJulia Advent Calendar 2018の15日目の記事です。 また、ここ数年チャレンジしている@kjunichiのパーソナルアドベントカレンダーの15日目の記事も兼ねてます。

背景

JuliaにはSpecialFunctionsパッケージにゼータ関数が用意されている。 これを使ってJuliaはllvmを吐けるから、WASMにして、ブラウザに描画させたらは高速な描画が 期待できるのでは?

と思いやってみたが、llvmの吐き出し方が分からず挫折したw。

abrakatabura.hatenablog.com

でも、PyPlotのようにPythonに頼らずも、Juliaで直接3Dのグラフを描画するくらいなら なんとかなるかもと始めた。

JuliaからJupyterに直接3Dグラフを描画する

原理

juliaからjupyterにhtmlを出力できる命令がある。

以下のようにdisplay関数を使うことで、Jupyterのノートブックに直接HTMLやJavaScriptを埋め込める。

これを使って、JuliaからJupyterのブラウザ側に様々なデータを送ることが出来る。

display("text/html", """
<h1>hoge</h1>
""")

PyPlotなどがJupyterに描画しているのもこの仕組みをつかってる模様。

Juliaで虚数を扱うには

im

虚数単位のiを表すことができる。

3D描画

WebGLを生で扱うと長くなりがちなので、Three.jsを利用した。

また、Jupyterのブラウザ側にJsのライブラリを管理する目的でRequireJSが利用されているようだったので、 この流儀に従い、Three.jsを組み込んだ。

頂点データの渡し方

ブラウザ(Three.js)側で処理しやすいだろうということで、Julia側でJSONにして渡すことにした。

Pkg.add("JSON")
using JSON

zdata=JSON.json(z);

あとはThree.jsで頂点のデータをいい感じにポリゴンにして描画すればOK

$zdataにJavaScript実行時には先ほどのJulia側で作成したJSONが展開される。

const data = $zdata

const geometry = new THREE.PlaneBufferGeometry(10, 10, xsize-1, ysize-1);
const plane = new THREE.Mesh(geometry, material);
scene.add(plane);

const vertices = geometry.attributes.position.array;
for (let y = 0; y < ysize; y++) {
  for (let x = 0; x < xsize; x++) {
    vertices[3 * ((xsize) * y + x) + 2] = data[y][x]
  }
}

geometry.computeFaceNormals();
geometry.computeVertexNormals();

取り組んで得た知見

  • 直接canvasをJulia側から出力するとmacOSSafariでスクロールできなくて死んだ。
    • divタグをかますことで、これを回避できた。

実行結果

www.youtube.com

成果物

マインクラフト(MCPI)編

これまではJupyterへ描画する話でしたが、今度は、マインクラフトを描画先にしてみます。

以降はRaspberry PiでJuliaを動かして Raspberry Piで動くマイクラゼータ関数を描画します。 (イマイチ話のつながりがありませんが、親子で今年の後半はマイクラ三昧だったので許してくださいw)

イクラ(MCPI)用に陰関数のプロットツール

実は以前の記事

abrakatabura.hatenablog.com

Pythonでマイクラ(MCPI)用に陰関数のプロットツールを作っていたので、 これを今回のアドベントカレンダーの記事用にプロット範囲を複素平面にしてJuliaで実装し直したのでした。

実行結果

成果物

あとがき

イクラはWindows10版をターゲットに進めたのですが、Juliaで使えるWebSocketのライブラリだと、 マイクラとうまくWebSocketが繋がらず、途方に暮れていたのですが、Juliaのバージョン1.0.0以降はArmにも 対応しているのを公式で見かけ、幸運なことにRaspberry Pi用のマインクラフト向けのパッケージまで 用意されていたので、なんとか進めることができました。

参考資料

関連記事

5年前の記事

4年前の記事

3年前の記事

2年前の記事

1年前の記事