node-gypでwindowsのnative moduleをコンパイルしたい

windows-build-toolsは途中で止まってうまくいかなかったので手動でインストールします。
まずはVisual Studio Build Toolsとpython2.7.15をダウンロードしてインストールします。
それとnpmもインストールします。

https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools

https://www.python.org/downloads/windows/

https://nodejs.org/en/

 

BuildToolsのインストールはインストーラーが起動されるので
Visual Studio Build Toolsにチェックを入れてインストールを押しひたすら待ちます。(結構長い...)
Pythonもポチポチインストール
パスはC:\Python27\python.exeになるはずです。
npmもインストール

npm config set msvs_version 2017
pm config set python C:\Python27\python.exe

 

でpythonとbuild toolのセットアップをします。

npm install -g node-gyp

でnode-gypをインストールします。

これでelectronのフォルダーで

node-gyp rebuild --target=2.0.0 --arch=x64 --dist-url=https://atom.io/download/atom-shell

とすればビルドが始まります。

targetはelectronのバージョンです。僕の場合は2.0.0でした。
これでbuild/Release/の中にnodeのバイナリーが出来ていればインストール成功です。

mallocをdebug compileしたい

glibcをダウンロードし解凍します。 glibcのフォルダーないに入りbuildフォルダーをつくります。

cd glibc-2.21
mkdir build
cd build

glibcをインストールするフォルダーを指定してconfigureします。

../configure --prefix=/home/shingo/lib/glibc

そしてmakeです。 フラグはデバッグ用に -g3 -O0 をいれます。

make CFLAGS="-g3 -O0"

するとglibcはoptimizationなしではcompileできないとerrorがでます。

error: #error "glibc cannot be compiled without optimization" 

いろいろ調べてみると最低でも-O1でないとcompileできないようです。 しかしmallocを-O0でコンパイルできれば良いのでちょっとそこだけ変えてみましょう。 まずはこのcompileできないのerrorをコメントアウトしましょう。 バージョンによって場所が違いますがgrepして見つけましょう。 2.21の場合はbuild folder内のconfig.hにあります。

...
# error "glibc cannot be compiled without optimization"
...

そしてmallocのフォルダー内にあるMakefileを編集します。 ついでにDMALLOC_DEBUGもアクティブにしておきましょう。

malloc/Makefile

# Uncomment this for test releases.  For public releases it is too expensive.
CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1
CPPFLAGS-malloc.o += -g3
CPPFLAGS-malloc.o += -O0

これでmakeするとmallocがstep実行できるlibc.aができあがります。

coffee scriptとvueを使ってelectronのappをつくりたい

ファイル構成はこんな感じです。

    my_coffee_electron
    ├── launch
    │   ├── main.js
    │   └── package.json
    ├── package.json
    ├── src
    │   ├── coffee
    │   │   └── app.coffee
    │   ├── pug
    │   │   └── index.pug
    │   └── vue
    │       ├── my_component.coffee
    │       └── my_component.vue
    └── webpack.config.js

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
	target:'electron',
  entry: './src/coffee/app.coffee',
  output: {
    filename: 'bundle.js',
    path: path.join(__dirname, 'build')
  },
	resolve:{
		alias:{
			'vue$':'vue/dist/vue.esm.js'
		}
	},
	plugins:[
		new HtmlWebpackPlugin({
			template:'./src/pug/index.pug'
		})
	],
	module:{
		rules:[
			{
				test: /\.pug$/,
				use: ['raw-loader','pug-html-loader']
			},
			{
				test: /\.coffee$/,
				use: ['coffee-loader']
			},
			{
				test: /\.vue$/,
				use: ['vue-loader','pug-html-loader']
			}
		]
	}
};

Webpackの設定です。target はelectronになっていますが
これを入れなければwebで実行できるファイルが生成されます。
htmlにpugテンプレートを使うためにHtmlWebpackPluginで設定しています。
resolve alias のところはこれが無いとvueがワーニングを出してくるのでいれます。
entryのapp.coffeeがルートになりDomLoad時に実行されます。
これでwebpackはbuildフォルダーの中にindex.htmlとbundle.jsを生成します。

launch/package.json

{
  "name": "electron-test",
  "main": "main.js"
}
 

Webpackが生成したファイルをelectronで実行するための設定です。
main.js では

 ...
  mainWindow.loadURL(url.format({
    pathname: path.join(__dirname, '../build/index.html'),
    protocol: 'file:',
    slashes: true
  }))
 ...

build/index.htmlを読み込んでwindowを作っています。
これでcoffee script と vue js を使って electron app を作れます。

github.com

electronでvue.jsのエラー

もしvue js で

You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build 

 と言われてwebpack使っていないという時は

node_modules/vue/package.json内の"main"を"dist/vue.runtime.common.js"から"dist/vue.js"にするとうまくいく。どっかでoverwrite的に出来ないのかな?

Fortran 千本ノック

1本目 Int の配列をつくって1,2,3を入れる!

 
integer,dimension(3)::arr = (/1,2,3/)
 

2本目 Int の10個の配列をつくって2から5まで1あとは0に!

 
integer,dimension(10)::arr
arr = 0
arr(2:5) = 1
 

3本目 Int の3x3の配列をつくって真ん中は1あとは0に!

 
integer,dimension(3,3)::arr
arr = 0
arr(2,2) = 1
! 0 0 0
! 0 1 0
! 0 0 0


4本目 Int の1x4の配列をつくって2x2の配列に!

 
integer,dimension(4)::arr
integer,dimension(2,2)::arr2
arr = (/1,2,3,4/)
arr2 = reshape(arr,(/2,2/))

! 1 2
! 3 4

5本目 文字を連結!

 
character(5) a
character(5) b

a = "hello"
b = "world"
 
print *,a//b ! helloworld
 

6本目 最初の2文字を交換!

 
character(5) a
character(5) b
character(5) tmp

a = "hello"
b = "world"

tmp(1:2) = a(1:2)
a(1:2)=b(1:2)
b(1:2)=tmp(1:2)
 
print *,a//b ! wolloherld
 

7本目 文字の配列!

 
character(5),dimension(2)::ch_arr

ch_arr(1) = 'abc'
ch_arr(2) = 'def'

8本目 文字を検索!

 
a = "hello"
 
print *, scan(a,'l') ! <--- 3

9本目 namelistを活用!

data

&data
a=1
b=2
/

data.f90

  integer::a
  integer::b
  integer,parameter::f=10
   
  namelist/data/a,b
  open(unit=f, file='data')
  read(unit=f, nml=data)
   
  print *, a, b ! <-- 1, 2
  close(unit=f)

10本目 subroutineを使う!

subroutine my_sub(b)
   integer b
   b = b + 1
end subroutine
 
program main
  implicit none
  integer::a
  a = 1
  call my_sub(a)
  print *, a
end program

Lapackをコンパイルしてみる

Lapackのコードを読んでみたいと思います。
まずはgithub Lapackからダウンロードします。
LapackのfortranのコードはSRCフォルダーに入っているのでそれをコンパイルしてみましょう。
SRCフォルダーをどこかにコピーします。
そのときmake.inc.exampleもコピーしてmake.incに名前を変えておきましょう。
SRCの中にMakefileがあるのでmakeしてみましょう。

cd SRC
make

すると最後にarコマンドでエラーがでました。
MakefileをみてみるとINSTALLフォルダーのオブジェクトファイルを探して失敗しているようです。

 ALLAUX = ilaenv.o ieeeck.o lsamen.o xerbla.o xerbla_array.o iparmq.o iparam2stage.o \
    ilaprec.o ilatrans.o ilauplo.o iladiag.o chla_transtype.o \
    ../INSTALL/ilaver.o ../INSTALL/lsame.o ../INSTALL/slamch.o
 
 SCLAUX = \
    sbdsdc.o \
    sbdsqr.o sdisna.o slabad.o slacpy.o sladiv.o slae2.o  slaebz.o \
    slaed0.o slaed1.o slaed2.o slaed3.o slaed4.o slaed5.o slaed6.o \
    slaed7.o slaed8.o slaed9.o slaeda.o slaev2.o slagtf.o \
    slagts.o slamrg.o slanst.o \
    slapy2.o slapy3.o slarnv.o \
    slarra.o slarrb.o slarrc.o slarrd.o slarre.o slarrf.o slarrj.o \
    slarrk.o slarrr.o slaneg.o \
    slartg.o slaruv.o slas2.o  slascl.o \
    slasd0.o slasd1.o slasd2.o slasd3.o slasd4.o slasd5.o slasd6.o \
    slasd7.o slasd8.o slasda.o slasdq.o slasdt.o \
    slaset.o slasq1.o slasq2.o slasq3.o slasq4.o slasq5.o slasq6.o \
    slasr.o  slasrt.o slassq.o slasv2.o spttrf.o sstebz.o sstedc.o \
    ssteqr.o ssterf.o slaisnan.o sisnan.o \
    slartgp.o slartgs.o \
    ../INSTALL/second_$(TIMER).o
 
 DZLAUX = \
    dbdsdc.o \
    dbdsqr.o ddisna.o dlabad.o dlacpy.o dladiv.o dlae2.o  dlaebz.o \
    dlaed0.o dlaed1.o dlaed2.o dlaed3.o dlaed4.o dlaed5.o dlaed6.o \
    dlaed7.o dlaed8.o dlaed9.o dlaeda.o dlaev2.o dlagtf.o \
    dlagts.o dlamrg.o dlanst.o \
    dlapy2.o dlapy3.o dlarnv.o \
    dlarra.o dlarrb.o dlarrc.o dlarrd.o dlarre.o dlarrf.o dlarrj.o \
    dlarrk.o dlarrr.o dlaneg.o \
    dlartg.o dlaruv.o dlas2.o  dlascl.o \
    dlasd0.o dlasd1.o dlasd2.o dlasd3.o dlasd4.o dlasd5.o dlasd6.o \
    dlasd7.o dlasd8.o dlasda.o dlasdq.o dlasdt.o \
    dlaset.o dlasq1.o dlasq2.o dlasq3.o dlasq4.o dlasq5.o dlasq6.o \
    dlasr.o  dlasrt.o dlassq.o dlasv2.o dpttrf.o dstebz.o dstedc.o \
    dsteqr.o dsterf.o dlaisnan.o disnan.o \
    dlartgp.o dlartgs.o \
    ../INSTALL/dlamch.o ../INSTALL/dsecnd_$(TIMER).o

なにかの依存関係でしょう。
消しましょう。
INSTALLのあるラインをコメントしてもう一度make。

 ALLAUX = ilaenv.o ieeeck.o lsamen.o xerbla.o xerbla_array.o iparmq.o iparam2stage.o \
    ilaprec.o ilatrans.o ilauplo.o iladiag.o chla_transtype.o \
  #  ../INSTALL/ilaver.o ../INSTALL/lsame.o ../INSTALL/slamch.o
 
 SCLAUX = \
    sbdsdc.o \
    sbdsqr.o sdisna.o slabad.o slacpy.o sladiv.o slae2.o  slaebz.o \
    slaed0.o slaed1.o slaed2.o slaed3.o slaed4.o slaed5.o slaed6.o \
    slaed7.o slaed8.o slaed9.o slaeda.o slaev2.o slagtf.o \
    slagts.o slamrg.o slanst.o \
    slapy2.o slapy3.o slarnv.o \
    slarra.o slarrb.o slarrc.o slarrd.o slarre.o slarrf.o slarrj.o \
    slarrk.o slarrr.o slaneg.o \
    slartg.o slaruv.o slas2.o  slascl.o \
    slasd0.o slasd1.o slasd2.o slasd3.o slasd4.o slasd5.o slasd6.o \
    slasd7.o slasd8.o slasda.o slasdq.o slasdt.o \
    slaset.o slasq1.o slasq2.o slasq3.o slasq4.o slasq5.o slasq6.o \
    slasr.o  slasrt.o slassq.o slasv2.o spttrf.o sstebz.o sstedc.o \
    ssteqr.o ssterf.o slaisnan.o sisnan.o \
    slartgp.o slartgs.o \
  #  ../INSTALL/second_$(TIMER).o
 
 DZLAUX = \
    dbdsdc.o \
    dbdsqr.o ddisna.o dlabad.o dlacpy.o dladiv.o dlae2.o  dlaebz.o \
    dlaed0.o dlaed1.o dlaed2.o dlaed3.o dlaed4.o dlaed5.o dlaed6.o \
    dlaed7.o dlaed8.o dlaed9.o dlaeda.o dlaev2.o dlagtf.o \
    dlagts.o dlamrg.o dlanst.o \
    dlapy2.o dlapy3.o dlarnv.o \
    dlarra.o dlarrb.o dlarrc.o dlarrd.o dlarre.o dlarrf.o dlarrj.o \
    dlarrk.o dlarrr.o dlaneg.o \
    dlartg.o dlaruv.o dlas2.o  dlascl.o \
    dlasd0.o dlasd1.o dlasd2.o dlasd3.o dlasd4.o dlasd5.o dlasd6.o \
    dlasd7.o dlasd8.o dlasda.o dlasdq.o dlasdt.o \
    dlaset.o dlasq1.o dlasq2.o dlasq3.o dlasq4.o dlasq5.o dlasq6.o \
    dlasr.o  dlasrt.o dlassq.o dlasv2.o dpttrf.o dstebz.o dstedc.o \
    dsteqr.o dsterf.o dlaisnan.o disnan.o \
    dlartgp.o dlartgs.o \
  #  ../INSTALL/dlamch.o ../INSTALL/dsecnd_$(TIMER).o

liblapack.aができあがります。
なにかこの中にある関数を呼んでみましょう。
CLACRT( N, CX, INCX, CY, INCY, C, S )を呼んでみましょう。
この関数はCXとCYの配列に入っている座標を時計回りに回転させる関数です。

program main
	INTEGER            INCX, INCY, N
	INTEGER  DEG
	COMPLEX            C, S
	COMPLEX,dimension(3)::CX = sqrt(2.0)
	COMPLEX,dimension(3)::CY = 0

	REAL,PARAMETER::PI = 3.14
	print *, CX
	print *, CY

	DEG = 45 
	INCX = 1
	INCY = 1
	N = 3 
	C = cos(DEG * (PI/180))
	S = sin(DEG * (PI/180))

	call CLACRT( N, CX, INCX, CY, INCY, C, S )
	print *, CX
	print *, CY
end program main

こんな感じで3つの(√2,0)の座標を45度回転させています。 このコードをtest.f90としてコンパイルしてみます。

	gfortran -o test test.f90 SRC/clacrt.f -llapack -L.

./にあるliblapack.aファイルをリンクしています。

(  1.00039804    ,  0.00000000    ) (  1.00039804    ,  0.00000000    ) (  1.00039804    ,  0.00000000    )
(-0.999601781    ,  0.00000000    ) (-0.999601781    ,  0.00000000    ) (-0.999601781    ,  0.00000000    )

実行してみるとCX, CY が(1,-1)になってprintされました。