2019年01月14日

2019/01 Musicメモ

2019/01 Musicメモ
* Crazy Glue (2017)
Melanie Ungar
https://www.jamendo.com/track/1480482/crazy-glue
歌声に恵まれてる。テイラー・スイフト風。
どこかで聴いたようなオールディーズっぽい曲。
誰かのカバーなのか? 思い出せない。 orz

* I Love How You Loved Me (2018)
Always the Alibi
https://www.jamendo.com/track/1513477/i-love-how-you-loved-me

* Fire, Fire (2018)
The Devil Music Co.
https://www.jamendo.com/track/1565058/fire-fire

* Constellate (2018)
Fleurie
https://www.jamendo.com/track/1549463/constellate

* Just a Stranger (2018)
MCKOOL
https://www.jamendo.com/track/1567808/just-a-stranger

* By Your Side by Mallz & Deron Alek (2018)
Cartel
https://www.jamendo.com/track/1593685/by-your-side-by-mallz-and-deron-alek


Taylor Swift - Look What You Made Me Do
https://www.youtube.com/watch?v=3tmd-ClpJxA
テイラー・スウィフトのMVに潜むヤバすぎる秘密を完全解説
https://front-row.jp/_ct/17122411
"MV"って何かと思ったらミュージック・ヴィデオのこと。

mvとpv違いとは:どのように捉えるか
https://www.cyring.co.jp/%E6%98%A0%E5%83%8F%E8%B1%86%E7%9F%A5%E8%AD%98/mv%E3%81%A8pv%E9%81%95%E3%81%84%E3%81%A8%E3%81%AF-%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E6%8D%89%E3%81%88%E3%82%8B%E3%81%8B/

アカペラ
https://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%BB%E3%82%AB%E3%83%9A%E3%83%A9
posted by Copyright (C) avrin All Rights Reserved. at 21:04| Comment(0) | その他 | このブログの読者になる | 更新情報をチェックする

2018年12月23日

nim言語:STM32のヘッダファイルをc2nimした時のメモ 2018

nim言語:STM32のヘッダファイルをc2nimした時のメモ 2018
c2nimは、c言語のソースとヘッダファイルをnim言語ソースに変換してしまうツール。
$ nimble install c2nim
でインストールできる。

$ c2nim foo.c $ c2nim boo.h $ c2nim --cpp moo.cpp
等で変換できる。 でも、中身がC言語で拡張子が*.cppファイルのソースはうまくいかない感じ。 その場合、拡張子を*.cにするとOKだった。orz 以下は、STM32マイコンのヘッダファイルを変換したときの記録。 STM32CubeMXで生成された「Nucleo-F030R8」用のプロジェクトフォルダ以下にある、 Drivers\CMSIS\Device\ST\STM32F0xx\Include\stm32f030x8.h というヘッダファイル。 5500行くらいあるんだけど、これをc2nimで変換してみました。 そのままではエラーで変換できないので「手動」で修正しました。 以下その時の記録。 誰かが変換スクリプトを作るのを期待したい。 (1) [置換対応] 「__IO」は「volatile」に置換。 (2) c2nimの実行時オプションに --skipincludeを追加。 これは#include文をimport文に変換しないオプション。 手動でやってもたいした違いはない。 (3) [置換対応] 先頭が一つ以上のアンダースコアで始まる名前はアンダースコアをカットする。
例: __FOO_BAR ---> FOO_BAR _FOO_FUZZ ---> FOO_FUZZ
この手のプレフィックスについては、コマンドラインオプションで --prefix:__ --prefix:_を追加で自動カットできそう。(試してないけど) これで「c2nim」が通るはず。 次は変換されたnimファイルを実際にインポートして出たエラーを潰していきます。 (4pre) volatileは結局エラーになるので全部カット。 (1)の時点で__IOをカットしたほうがよかったか。 (4)[置換対応] unin32_t、uint16_t、uint8_tはそれぞれuint32、uint16、uint8に置換 これらはサフィックスをカットする--suffix:_tオプションで 自動カットできるかも。(試してない) (5) キャストエラーを修正する。数カ所。
const CRC_IDR_IDR* = (cast[uint8_t](0x000000FF)) ## !< General-purpose 8-bit data register bits
const CRC_IDR_IDR* = (0x000000FF.uint8) ## !< General-purpose 8-bit data register bits
uint16版のエラーも出るのでそれも同様に修正する。 (6)名前の衝突エラーを修正する。 これはnimが「_」(アンダースコア)を無視して"識別子を認識する"ことに由来している場合と、 c2nimのバグの可能性と2種類ある様ですが、対処します。 例えば以下の行はエラーになるが、なぜエラーなのは不明。
GPIO_MODER_MODER10* = GPIO_MODER_MODER10_Msk
しかたがないので、単にコメントアウトします。(適当なサフィックスを付けて残す手もある)
# GPIO_MODER_MODER10* = GPIO_MODER_MODER10_Msk
これは名前の衝突の例:コメントアウトします。 WWDG_CR_T0* = WWDG_CR_T_0 (7) 未定義の識別子をコメントアウトする。 RCC_AHBENR_TSCEN等々が未定義エラーになるのでコメントにする。 (8) 外部参照の関数名もコメントアウト 今のところ対処法が不明なので全部コメントアウトします。 例えば、ADC1_IRQHandlerは割り込みハンドラーなので外部ファイルに存在するが、 インポート方法がわからないので全部when文でカット。 リネームしているだけなので不要かと。
when false: const ADC1_COMP_IRQHandler* = ADC1_IRQHandler ... ...
実際に使った例 実際には、core_cm0.hを変換したものをインクルードして使っています。 ここで使ったもの。 nim言語でNucleo-F030R8を動かした時のメモ 2018/12
posted by Copyright (C) avrin All Rights Reserved. at 11:55| Comment(0) | nim言語 | このブログの読者になる | 更新情報をチェックする

2018年12月22日

nim言語でNucleo-F030R8を動かした時のメモ 2018/12

nim言語でNucleo-F030R8を動かした時のメモ 2018/12
はじまり
    源流
    nimについて (https://nim-lang.org/)
STM32F3-DiscoveryでLEDチカチカ
Nucleo-F030R8で動かす
STM提供のレジスタ定義ファイルをc2nimで変換して使う
    c2nimのインストール
    変換のポイント:
    c2nimで変換中:
    実際の使用時:
nim言語で書いたSTM32F0用設定コード
    コンパイルに必要なもの
ハマりポイント
    Makefile:
    SPIとNSS設定
    volatile効いてない !? orz
main.nim
ファイル構成
ダウンロード
その後


はじまり
源流
    基本的に、こちらのかたのブログ記事に触発されて、いろいろやってみた記録。感謝。
         なんとなく活動記録。
        電子工作・プログラミングの備忘録
        NimでLチカ on STM32 (1)
        http://blueeyes.sakura.ne.jp/2018/05/22/1243/
        NimでLチカ on STM32 (2)
        http://blueeyes.sakura.ne.jp/2018/05/28/1256/
        Githubオリジナルソース
        https://github.com/shima-529/STM32OnNim

nimについて (https://nim-lang.org/)
    現在の最新版。
    nim Nim Compiler Version 0.19.0

    rust言語に挫折してから。。。時は流れた。。。
    nim言語を発見して勉強用にライフゲームなどを作っていたところ、
    上記ブログに遭遇したのだった。

STM32F3-DiscoveryでLEDチカチカ
最初は、 https://github.com/shima-529/STM32OnNim
このソースを頂いてSTM32F3-Discovery用に変更してLEDチカチカさせました。
結局、変更点はLEDポートの変更だけでした。
コアが同じなのでリンカスクリプトもベクタファイルもLED点灯程度なら無変更でOKでした。(^^)/
https://www.st.com/ja/evaluation-tools/stm32f3discovery.html


Nucleo-F030R8で動かす
STM32F3-Discoveryで簡単に動いたのに気をよくして、
以前よく遊んだmbedボード「Nucleo-F030R8」で動かそうと決意しました。
NucleoボードのほうがUSB-CDC(UART)が付いているので便利。
以下、Nucleo-F030R8で動くまでの記録を記述。

https://os.mbed.com/platforms/ST-Nucleo-F030R8/
 

STM提供のレジスタ定義ファイルをc2nimで変換して使う
使う分のレジスタ構造体だけを定義していく手もあるけど、
STM32CubeMXについてくるヘッダーファイルをc2nimで変換してみました。
変換したファイルは「stm32f030x8.h」、「core_cm0.h」、
あと 「cmsis_gcc.h」 から「wfi」とかを少し持ってきました。
変換のポイント:
    nim言語:STM32のヘッダファイルをc2nimした時のメモ 2018

nim言語で書いたSTM32F0用設定コード
基本的にレジスタをビット単位で直たたき、"Reset初期値のままでいける場合は
あえて変更しない"という方針。(^^;
(1) PLLで48MHzまでクロックアップ。
(2) Systickタイマー10msec周期で割り込みハンドラ起動。
(3) USART2(PA3,PA3)を115200bpsで設定。Nucleo-F030R8の標準UARTポート。
(4) TIM3。PWM用の設定。
(5) PWM周期で割り込みハンドラ起動。
(6) PWM出力を4ch分設定。固定デューティで出力。
(7) SPI1をSCK=12MHzで設定。8bit/16bitポーリング通信。
    PB6はCS(チップセレクト)で使用。
(8) printf()関数、呼び出し可能に設定。
    syscalls.cを追加。
(9) ChaNさんのxprintf()関数、呼び出し設定。
    軽量なので、こちらをデバッグ用にメインで使用。
(10) コードサイズを小さくしたいのでgccのオプションは「-Os」。

コンパイルに必要なもの
Winodws上でmakeしますが、Linux上でもそのままmakeできます。
Windowsの場合、下記(1)〜(3)のコマンドへ実行パスを通しておく必要があります。

(1) nimコンパイラ。上記の本家から取ってきてインストールしておきます。
    現時点では以下のバージョン
    nim Nim Compiler Version 0.19.0
    少なくともこれ以降のバージョンが良い。
    Ubuntu系の場合、「apt install nim 」だと古い可能性があるので、
    $nim -vでバージョンを確認します。
    以下から Version 0.19.0のdebファイルを取得して
    https://packages.debian.org/sid/i386/nim/download
    $ sudo dpkg -i nim_0.19.0-1.deb
    で最新版がインストールできます。
(2) gccは、arm-none-eabi-gcc: https://launchpad.net/gcc-arm-embedded ここから
    最新版をもらってきてインストールしておきます。 (最新じゃなくても別にいいけど)
(3) make,rm コマンドが必要。
(4) コンパイルはMakefileがあるトップフォルダに移動、MS-DOSコマンドラインで
    $ make
    成功すれば「nucleo_f030r8.hex」ができているので、
    STM32CubeProgrammer(注2)やOpenOCDなどで書き込みます。
    自分の場合はST-Link Utilityに付属の「ST-LINK_CLI.exe」で書き込んでいます。(注2)
    Makefile内の以下の行の「#」をカットすればmake後、自動でFLASHに書き込まれます。
    #   "d:\STM32-ST-LINK-Utility\ST-LINK Utility\ST-LINK_CLI.exe" -c SWD -P $(TARGET).hex -Rst
    (フォルダ名は書き換える必要あり)

ハマりポイント
苦労した点、という意味。
Makefile:
    nimとgccのコンパイルを「Make 一発」できる様に変更。
    これがなんとも悶絶した。orz
    makeの実行直後には、まだnimが生成した*.cファイル群は存在しないが、
    その存在しないファイルに対して依存関係を記述しないといけない、
    えっ? パニック。(^^;
    で、なんとかやっつけた。(オイ
    ただし、状況依存で途中で止まる場合があるので、その時はもう一度
    makeすればOK.

SPIとNSS設定
    これと次の問題が同時に発生して地獄に落ちました。orz
    STMのF0マイコンでNSSピンの制御が可能なものは、「NSSピンを使わない単純なマスター通信」を
    するために、以下のどちらかの設定が必ず必要、
    (a)SPI_CR1_SSM = 1 且つ SPI_CR1_SSI = 1
     または、
    (b) CR2_SSOE = 1
    上のどちらかを設定しないと、SPIはピクリとも動かない。
    orz orz orz

    STM32CubeMXが生成した初期化コードだと以下の行が該当部分。
    SPI_InitStruct.NSS = LL_SPI_NSS_SOFT;
    これを基に、
    LL_SPI_Init(SPI1, &SPI_InitStruct)内でこっそり上記のビットが設定されている。
    こっそり !?
    mbedやSTM32CubeMXに頼りすぎた呪いだ。
    呪い !?

volatile効いてない !? orz
    (i)SPI通信がさっぱり動かないので、SPIのレジスタを色々変えてみたり、
       設定を見直してみたりしたけどダメ。
    (ii) printfでSPI_CR1等のレジスタ値を見ると設定したはずの値が返ってこないし、
         設定値を変えるたびに、その値も微妙に変化するも規則性はないようだ。orz
    (iii) な、なんか壊れてる。。。 orz (i) に戻る。
    というループから「break」できなくて、
    orz orz orz だった。
    結局、
    逆アセンブラリストを順に確認していって、最後の最後に送信レジスタに値を設定するところ、
    よく見ると、
    SPIを有効にする前に、送信レジスタ(SPI_DR)に送信データが入り、
    その後、SPIを有効にしていた。    じゅ、順番が逆!
    アセンブラレベルだと順番が逆になっていた。orz
    で、ようやく
    実はvolatileが効いてないことがわかる。

    volatileについてはvolatileLoad/volatileStoreでケリがついていると思ったが
    微妙なようだ。(全部効いてないということではない感じ、ではある)
    正当な対処方法がわからないのでvolatile{Load,Store}関数呼び出しの最後に
    「nop()挿入」でやっつけた。(注1)

    ということで、SPIが意図どおり動くようになって、かなりすっきりしました。
    (^^)/

犯人は自分だった orz
    その後、全てうまく動いたので、このvolatile問題を再調査してみたところ、
    実は、自分で追加したコードが非volatileになっていたことがわかったのだ。
    orz orz orz
    話すと長いんだけどnimコンパイラのバグを避けるためのコードを入れたら、
    それがバグっていたという話。 orz

nimのvolatileバグについて
    マイコンのペリフェラルレジスタ(volatileアクセスで)を8bit/16bitのデータ長を明示的に
    指定してアクセスする場合に、volatileStore/volatileLoad関数がが不正なコードを
    吐き出す問題を以下の関数を追加することで回避した。
proc volatileLoad8*(src: ptr uint8):uint8 {.inline.} =
    {.emit: [result, " = *(", uint8, " volatile *)", src, ";"].}

proc volatileStore8*(dst: ptr uint8, val: uint8){.inline.} =
    {.emit: ["*(", uint8, " volatile *)", dst, " = ", val, ";"].}

proc volatileLoad16*(src: ptr uint16):uint16 {.inline.} =
    {.emit: [result, " = *(", uint16, " volatile *)", src, ";"].}

proc volatileStore16*(dst: ptr uint16, val: uint16){.inline.} =
    {.emit: ["*(", uint16, " volatile *)", dst, " = ", val, ";"].}
main.nim
# For NUCLEO-F030R8
import startup
import stm32f030x8
import systick, uart, pwm, gpio, sys, spi

#proc printf(formatstr: cstring){.header: "<stdio.h>", importc: "printf", varargs.}
proc xprintf(formatstr: cstring){.header: "xprintf.h", importc: "xprintf", varargs.}

proc IO_Test(spi:auto){.used.} =
    var x = 0
    var sdata :uint8 = 0
    while true:
        setTickCounter(200)
        while getTickCounter() > 0: # wait 2sec
            # SPI loop back test
            cs_on()
            var n = spi.send(sdata)
            n = spi.send(n)
            n = spi.send(n)
            n = spi.send(n)
            cs_off()
            if sdata != n:
                xprintf("\nSPI data EEROR!")
                while true:
                    discard
            inc(sdata)
        # Core register viewing
        xprintf("\n%04d",x)
        xprintf("\nSPI.CR1 = %08X(%X)" ,SPI1.CR1,cast[int](SPI1.CR1.addr) )
        xprintf("\nSPI.CR2 = %08X(%X)" ,SPI1.CR2,cast[int](SPI1.CR2.addr) )
        xprintf("\nRCC.AHBENR  = %08X" ,RCC.AHBENR)
        xprintf("\nRCC.APB1ENR = %08X" ,RCC.APB1ENR)
        xprintf("\nRCC.APB2ENR = %08X" ,RCC.APB2ENR)
        xprintf("\nGPIOA.MODER = %08X" ,GPIOA.MODER)
        xprintf("\nGPIOA.AFR[0]= %08X" ,GPIOA.AFR[0])
        xprintf("\nGPIOA.AFR[1]= %08X" ,GPIOA.AFR[1])
        xprintf("\nGPIOB.MODER = %08X" ,GPIOB.MODER)
        xprintf("\nGPIOB.AFR[0]= %08X" ,GPIOB.AFR[0])
        xprintf("\nGPIOB.AFR[1]= %08X" ,GPIOB.AFR[1])
        xprintf("\n")
        inc(x)

block: # main function
    initSysClock48mhz()
    # Start systick timer and interrupt
    discard SysTick_Config(SYSTEM_CLOCK div 100) # 10msec (100Hz)
    initGPIO()
    initSerial(USART2)
    initSPI(SPI1)
    initPwm()
    # PWM tset  Duty setting
    pwmDutyRHi( 512)
    pwmDutyLHi( 512 shr 1)
    #
    pwmDutyRLow(512 shr 2)
    pwmDutyLLow(512 shr 3)

    IO_Test(SPI1) 
上のxprintf()のUART出力は以下、
1767
SPI.CR1 = 0000034C(40013000)
SPI.CR2 = 00001700(40013004)
RCC.AHBENR  = 000E0014
RCC.APB1ENR = 00020002
RCC.APB2ENR = 00001000
GPIOA.MODER = 2800A8A0
GPIOA.AFR[0]= 00001100
GPIOA.AFR[1]= 00000000
GPIOB.MODER = 00001A00
GPIOB.AFR[0]= 00110000
GPIOB.AFR[1]= 00000000
ファイル構成
Top
│  LICENSE
│  Makefile
│  README.md
│
└─src
    │  gpio.nim
    │  main.nim
    │  panicoverride.nim
    │  port_setting.txt
    │  pwm.nim
    │  spi.nim
    │  sys.nim
    │  uart.nim
    │
    ├─f0
    │      STM32F030R8Tx_FLASH.ld
    │      stm32f030x8.nim
    │      vector_f030.c
    │
    ├─lib
    │  └─xprintf
    │          xprintf.c
    │          xprintf.h
    │
    ├─nimcache
    │      dummy.txt
    │
    └─sys
            core_cm0.inc
            nimbase.h
            reg_utils.inc
            startup.nim
            syscalls.c
            systick.nim
ダウンロード stm32f0nim_v0.7rel-201812.zip (2018/12/23) その後 上のソフトをベースに「SDカードをSPIモードで初期化」まで成功したので、 難関は切り抜けたという感じ。 (^^)/ (注1) {.volatile.}プラグマを使ってみると、ゾッとする様な「ゾッとしないコード」を吐いてきたので 使うのやめました。orz 経緯的には、"{.volatile.}使えない"、じゃあ ってことでvolatileLoad/volatileSoreが作られたらしい。 (注2) STM32CubeProgrammerにもコマンドライン版がある様なので、ちょっと使ってみる。
posted by Copyright (C) avrin All Rights Reserved. at 19:49| Comment(0) | nim言語 | このブログの読者になる | 更新情報をチェックする

2018年12月16日

nim言語に入門した時のメモ 2018/12

nim言語に入門した時のメモ 2018/12
はじまり
2017年末にrust言語を発見した時、同時に発見していた言語、nim。
rust言語はそれから3ヶ月弱で挫折しました。orz
。。。時は流れて。。。ようやくnim言語のことを思い出した。



公式FAQ
https://nim-lang.org/faq.html

特徴
Pascal/Delphi/Lazarus風味
    公式FAQでは影響が強い順に以下となっている
     Modula3, Delphi, Ada, C++, Python, Lisp, Oberon.
    緑色の言語がPascal系。

Pascal風味なところ:
    Type宣言、Set型、case文の書式、関数内関数、
    整数の割り算は「div」、余りは「mod」、
    シフト命令は 「shl, shr」、
    論理演算子は、「xor, and, or, not」、
    等々、Pascalと同じだ。

Python風味なインデント構文
    "スペース文字"を使ってインデント構文を形成するのはPythonと同じ。
    インデント量は自分の場合「4」にした。
    公式系では「2」。
    さすがに「2」は、みずらくて やだなぁ。。。orz
    https://nim-lang.org/docs/manual.html#lexical-analysis-indentation

Pythonのpass
    https://nim-lang.org/docs/manual.html#statements-and-expressions-discard-statement
    Pythonでたまに使う「pass」はnimでは「discard」になる。
    空っぽの関数は以下になる。
proc foo() = discard
ちなみに、この空き関数を関数テーブルに入れると意味不明のエラーが出て、 これが原因だと気づくのに時間がかかった orz 変数は、すべて初期化済み https://nim-lang.org/docs/manual.html#statements-and-expressions-var-statement プログラムが開始した時点で、全てのグローバル、ローカル変数は 規定値で初期化済みである。規定値が何かはリンク先を参照。 例えば、数値型は0,文字列は「""」, シーケンス(seq)は「@[]」で初期化される。 この初期化動作を回避させることもできる。 result変数は「定義済みで初期化済み」 https://nim-lang.org/docs/manual.html#statements-and-expressions-return-statement 値を返す関数は、関数内で暗黙的に「result変数」が"返り値と同じ型"で定義済みで、 且つ、初期化済みである。(注1) 初期化値は上と同じ。 (注意点:result変数を関数内に於いて自前で定義してしまうと、 正しい値を返さないのでやってはいけない。)
proc intAdd(n:int): int = for i in 1..n: result += i # 1からnまで加算して返す proc strAdd(s:string): string = for i in 1..3: resutl &= s # resut = result + s と同じ意味
以下は全て正しく動作し、同じ値を返す。 「...」は、他の文があってもなくても良いという意味。
(1) proc add(x,y:int):int = ... return x + y (2) proc add(x,y:int):int = ... result = x + y (3) proc add(x,y:int):int = ... result = x + y ... return result (4) proc add(x,y:int):int = ... result = x + y ... return (5) proc add(x,y:int):int = ... x + y
(3)と(4)は表現がしつこすぎて使わないと思う。 戻り値のある関数呼び出しで、"戻り値を使っていない"と怒られた https://nim-lang.org/docs/manual.html#statements-and-expressions-discard-statement 呼び出し側で戻り値を使わない時は「discard」を付けないとコンパイルエラーになる。
定義時: proc add(x,y:int): int = x + y 呼び出し時: discard add(2,3)
この動作仕様は回避可能。 関数内のスタティック変数は{.global.}で定義 C言語でたまに使う「変数の"関数内static宣言"」は、nimでは
proc foo() = var 変数名 {.global.} = 5 ... ...
の様に書く。 関数名、変数名、等々の命名規則 https://nim-lang.org/docs/manual.html#statements-and-expressions-if-expression これが結構変わっていて、Pascal系の「大文字、小文字は区別しない」の 類似型と思われる。その規則はこう、 (1) 大文字、小文字は区別しない。但し、最初の一文字目を除く。 (2) "_"(アンダースコア)は無視する。 なので以下の2つの識別子は同じものと見なされる。
get_outque_count() getOutQueCount()
以下は違うものと見なされる。
var barbar = 1 var Barbar = 1
これについてのスレッドがこちら、 https://forum.nim-lang.org/t/4388 ifとcaseは値を返せる ifとcaseは式でもあるので値を返せる。 elif節は省略可だが、else節は省略できない。
var y = 10 let x = if y > 3: 複文も可 返す値 elif y == 1: 複文も可 返す値 else: 複文も可 返す値
(注1) Pascalの場合、result変数は未初期化。
posted by Copyright (C) avrin All Rights Reserved. at 10:01| Comment(0) | nim言語 | このブログの読者になる | 更新情報をチェックする

nim言語のコンパイル時間を3倍速くする方法 2018

nim言語のコンパイル時間を3倍速くする方法 2018
はじまり
お気楽極楽なスクリプト風味なプログラミング言語、nim言語。

(1) ネイティブコードコンパイラ(正確にはトランスレータ)
(2) Hello Worldのバイナリサイズは、たったの35Kbyte(Windows版)
(3) 実行速度はC言語も真っ青になる場合もある。くらい高速。
    (そうでない場合も当然ある :-)

nim言語のコンパイラは正確には、C言語に変換するトランスレータである。
生成されたC言語のコンパイルには標準でgccが使われる。
(LLVMやMSVC(VCC)等に変更することも可能)

初回のコンパイルではフルコンパイルがかかるので結構遅い感じだ。
2回目以降はインクリメンタルコンパイルになるので、こそまで遅い感じではないが、
スクリプト言語に比べれば遅さは否めないのだった。

コンパイル速度を3倍速くする方法
結論から言うと、gccより9倍高速にコンパイル可能な「tcc」を使います。
https://bellard.org/tcc/
ダウンロード
http://download.savannah.gnu.org/releases/tinycc/
(1) 32bit(Windows)
        http://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27-win32-bin.zip
    64bit(Windows)
        http://download.savannah.gnu.org/releases/tinycc/tcc-0.9.27-win64-bin.zip
    ダウンロード後、解凍して「tcc」フォルダを「c:\tcc」等に移動する。
    (1b) Linux(Ubuntu/Debian系)
        $ sudo apt install tcc
        で完了。簡単。Linuxの場合、もともとWindowsほどコンパイルは遅くないかも。
(2) (Windowsのみ)環境変数に「c:\tcc」を加える。
(3) nimのソースコードがあるフォルダでMS-DOSコマンドプロンプトを開いて、
    「--cc:tcc」を加えるだけ。
    gccコンパイルに戻したいときは「--cc:tcc」をカットするだけ。
自分の場合は以下で使用中。
    
nim c -d:release --opt:size --passL:-s --cc:tcc ファイル名.nim
ただし、tccの場合、最適化オプションは一切無効になるので「--opt:size」は無視される。 Win32API・GUIライブラリ tccコンパイラで「winim」「wNim」などのGUIライブラリも普通にコンパイルできた。 とういうか、gccとの互換性は問題なさそう。 デメリット 実行速度が3倍遅くなります。 tccでちゃちゃっと作って、そろそろ完成に近づいたらgccに戻せばいいでしょう。
posted by Copyright (C) avrin All Rights Reserved. at 09:59| Comment(0) | nim言語 | このブログの読者になる | 更新情報をチェックする