スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

vimclojureのインストール

最近emacsからvimに乗り換えようか迷い中です。

試しにclojureの開発環境を作ってみようとvimclojureのインストールについて調べてみました。
ホームページらしきページがアクセスできなくて焦りましたが、READMEを読めば問題なく設定できました。

作業はubuntuで行いました。
clojureやleiningenのインストールについては特に触れません。


まずはvimclojureをチェックアウトします。
(zip等でのダウンロードも可能です。)

$ sudo aptitude install mercurial
$ hg clone https://bitbucket.org/kotarak/vimclojure


ngサーバーへ接続するためのngクライアントをmakeしておきます。

$ cd vimclojure/client/
$ make


続いて.vimの下へプラグインを置きます。
(私はpathogen.vimを使っているのでbundleの下へ置きました。)

$ cd ../
$ cp -R vim/ ~/.vim/bundle/vimclojure


ftdetectだけは.vim直下へ置かないとfiletypeを特定できないようなので移動します。

$ cd ~/.vim
$ mv bundle/vimclojure/ftdetect ./


.vimrcへ追記します。

syntax on
filetype plugin indent on

let vimclojure#WantNailgun = 1
let vimclojure#NailgunClient = "/path/to/ng" " 先にmakeしたngクライアントのパス
let vimclojure#HighlightBuiltins = 1



それではサンプルのプロジェクトを作ってみます。

$ cd hoge
$ lein new sample
$ cd sample


project.cljに追記します。

:dev-dependencies [[vimclojure/server "2.2.0"]
[org.clojars.autre/lein-vimclojure "1.0.0"]]


依存するjarファイルダウンロードします。

$ lein deps


ngサーバーを起動して、コードを書いてみます。

$ lein vimclojure &
$ vim src/sample/core.clj

(+ 1 2 3)


<LocalReader>etでevalできます。


REPLの起動は<LocalReader>srです。
:help clojure.vimを見ると他にもいろいろ書いてあります。


そのままだとngサーバーの起動が面倒だったのですが、lein-vimclojureというプラグインのおかげで
「lein swank」みたいに起動できて助かります。


[追記 2011/03/29]

後日MacOSXでも同じ設定を行ったのですが、日本語の混じったコードをevalできませんでした。
どうやらMacのJDK6からデフォルトShift_JISになったようで以下の環境変数をセットすれば動くようになりました。
export _JAVA_OPTIONS="-Dfile.encoding=UTF-8"

LLVMチュートリアルのコードをNetBeansで実行してみる

LLVMチュートリアルのコードをNetBeansで実行する際に
設定したオプションの類をメモしておきます。

http://llvm.org/docs/tutorial/LangImpl7.html


[プロジェクト名を右クリック] - [プロパティ]

・[C++コンパイラ] - [追加のオプション]

  `llvm-config --cppflags`

・[リンカー] - [追加のオプション]

  `llvm-config --ldflags`

・[リンカー] - [ライブラリ] - [オプションを追加]

  `llvm-config --libs core jit native`


llvm-configはg++に必要なオプションを与えてくれるプログラムなので

(例えば「llvm-config --libs core」と実行すると
「-lLLVMCore -lLLVMSupport -lLLVMSystem」という文字列が返ってきます。)

適切な位置にオプションが挿入されるよう分割して設定する必要がありました。


以下のページの例が参考になりました。

http://llvm.org/cmds/llvm-config.html

[Haskell]Qtのウィンドウを出してみる

とりあえずQtのウィンドウを出して、ボタンをクリックしたときにHaskellから渡した関数を呼び出すところまでやってみたのでメモしておきます。

Mac OSX 10.6.5
GHC 7.0.1
Qt 4.7.1

-- Main.hs
{-# LANGUAGE ForeignFunctionInterface #-}

module Main where

import System.Environment
import Foreign.C.Types
import Foreign.C.String
import Foreign.Ptr
import Foreign.Marshal.Array

main = do
(argc, argv) <- getArgs >>= makeCArgs
funptr <- makeFunPtr (putStrLn "Haskell function")
qtExample argc argv funptr

makeCArgs :: [String] -> IO (CInt, Ptr CString)
makeCArgs args =
mapM (newArray . (map castCharToCChar)) args
>>= newArray
>>= \argv -> return ((fromIntegral . length) args, argv)

foreign import ccall "wrapper" makeFunPtr :: IO () -> IO (FunPtr (IO ()))
foreign import ccall "qt_example" qtExample
:: CInt -> Ptr (Ptr CChar) -> FunPtr (IO ()) -> IO ()


/* example.cpp */
#include <QtGui>
#include "SlotProxy.h"

extern "C" {

void qt_example(int argc, char *argv[], void (*slot)())
{
QApplication *app = new QApplication(argc, argv);

QWidget *window = new QWidget();
window->resize(300, 150);

QPushButton* button = new QPushButton("Button", window);
button->setGeometry(100,50,100,50);

QObject::connect(button, SIGNAL(clicked()), new SlotProxy(button, slot), SLOT(run()));

window->show();
app->exec();

delete window;
delete app;
}

}


/* SlotProxy.h */
#ifndef __SlotProxy
#define __SlotProxy

#include <QtGui>

class SlotProxy : public QObject
{
Q_OBJECT

public:
SlotProxy(QObject* parent, void (*slot)());
~SlotProxy();
public slots:
void run();
private:
void (*slot)();
};

#endif


/* SlotProxy.cpp */
#include "SlotProxy.h"
#include <stdio.h>

SlotProxy::SlotProxy(QObject* parent, void (*slot)()) : QObject(parent){
this->slot = slot;
}
SlotProxy::~SlotProxy(){
printf("SlotProxy::~SlotProxy\n");
}
void SlotProxy::run(){
this->slot();
}


ビルド。

moc SlotProxy.h -o moc_SlotProxy.cpp
ghc --make Main.hs example.cpp SlotProxy.cpp moc_SlotProxy.cpp -lstdc++ -framework QtCore -framework QtGui -I/Library/Frameworks/QtGui.framework/Headers

mocは、SIGNALやSLOTを利用できるようQ_OBJECTマクロを持つクラスを拡張してくれるそうです。

[Haskell]FFI使ってC++バインディングに入門

この記事はHaskell Advent Calendarのために書いたものです。

FFIでCの関数を呼び出すところまではすんなりいったので、次C++行ってみよう!として
ドハマりしたという内容です。


C++でクラスを作成して、ラッパー関数を書き、Haskellから呼び出すという手順でやってみます。

とりあえず何も考えずに以下のコードを書きました。

point.h
point.cpp
wrapper.cpp
main.hs


/* point.h */

class Point{
public:
Point(int, int);
int getX();
int getY();
private:
int x, y;
};

/* point.cpp */

#include "point.h"

Point::Point(int x, int y){
this->x = x;
this->y = y;
}

int Point::getX(){
return this->x;
}

int Point::getY(){
return this->y;
}

/* wrapper.cpp */

#include "point.h"

Point* createPoint(int x, int y){
return new Point(x, y);
}

int getPointX(Point* p){
return p->getX();
}

int getPointY(Point* p){
return p->getY();
}

void destroyPoint(Point* p){
delete p;
}

-- main.hs

{-# LANGUAGE ForeignFunctionInterface #-}

module Main where

import Foreign
import Foreign.Ptr
import Foreign.C.Types

data Point = Point

main = do
p <- c_createPoint 1000 2000
x <- c_getPointX p
y <- c_getPointY p
c_destroyPoint p
print x
print y

foreign import ccall "createPoint" c_createPoint :: CInt -> CInt -> IO (Ptr Point)
foreign import ccall "getPointX" c_getPointX :: Ptr Point -> IO CInt
foreign import ccall "getPointY" c_getPointY :: Ptr Point -> IO CInt
foreign import ccall "destroyPoint" c_destroyPoint :: Ptr Point -> IO ()


ビルドしてみます。

$ g++ -c point.cpp wrapper.cpp
$ ghc --make main.hs point.o wrapper.o



すると以下のようなエラーが。

[1 of 1] Compiling Main             ( main.hs, main.o )
Linking main ...
ld: warning: in point.o, file was built for unsupported file format which is not the architecture being linked (i386)
ld: warning: in wrapper.o, file was built for unsupported file format which is not the architecture being linked (i386)
Undefined symbols:
"_destroyPoint", referenced from:
_rKi_info in main.o
_sTt_info in main.o
"_getPointX", referenced from:
_rKg_info in main.o
_sTx_info in main.o
"_createPoint", referenced from:
_rKe_info in main.o
_sWN_info in main.o
ld: symbol(s) not found
collect2: ld returned 1 exit status


「Undefined symbols?」が目にはいったので調べてみると、
CとC++ではコンパイル後の関数名が異なるとのこと。

オーバーロード機能があるC++では同名の関数をユニークな名前に
変換する必要があると書いてあります。
(マングリングっていうらしい)

納得。


でC++で用意した関数をCからも呼べるようにこのマングリングを回避するのが
よく目にする、「extern "C" { }」ってことでした。

早速、Haskellから直接呼ぶ関数を並べているwrapper.cppを
「extern "C" { }」で囲って再度ビルド。


同じエラーが・・・

よくよく見ると

file was built for unsupported file format



というエラーが一緒に出てます。

Mac SnowLeopardで作業していたのですが、そのgccが64bitでコンパイルしていたことによるものでした。
ghcは64bitコードを扱えないそうです。

32bitでコンパイルすればこの問題は解決します。

$ g++ -c point.cpp wrapper.cpp -m32
$ ghc --make main.hs point.o wrapper.o



今度はエラー内容が変わりました。

[1 of 1] Compiling Main             ( main.hs, main.o )
Linking main ...
Undefined symbols:
"operator delete(void*)", referenced from:
_destroyPoint in wrapper.o
_createPoint in wrapper.o
"operator new(unsigned long)", referenced from:
_createPoint in wrapper.o
"___gxx_personality_v0", referenced from:
___gxx_personality_v0$non_lazy_ptr in wrapper.o
(maybe you meant: ___gxx_personality_v0$non_lazy_ptr)
ld: symbol(s) not found
collect2: ld returned 1 exit status



new とか deleteを使えないって言ってるっぽい・・。


でもC++ライブラリのバインディングが存在してるのでできるはず!
とドキュメントを漁っていたら以下の記事に遭遇。

http://www.haskell.org/haskellwiki/CPlusPlus_from_Haskell

この記事の中段あたりに

ghc --make main.hs -o hybrid_program -lstdc++ nifty_code.o



と書かれているのを発見。

「-lstdc++」って、もろいけそうじゃん!

ってことで・・

$ g++ -c point.cpp wrapper.cpp -m32
$ ghc -lstdc++ --make main.hs point.o wrapper.o



ビルドできたー!
C/C++周りの知識に乏しい自分にはきつかった・・org


「-lstdc++」ってgccでC++をビルドする際に使われていたオプションみたいですね。


以上をまとめると・・

・Haskellから呼び出す関数は、extern "C" { }で囲っておく。
・ghcは64bitコードを現在サポートしていない。
・リンクのとき、「-lstdc++」をオプションとして指定する。


C++コードをghciで扱う方法が分かりませんでした。
どなたかご存知でしたらぜひ教えていただきたいです。


最後にMecabで試してみました。
(Mecabのホームページに掲載されていたコードを拝借しました。)

-- main.hs

{-# LANGUAGE ForeignFunctionInterface #-}

module Main where

main = c_mecabTest

foreign import ccall "mecabTest" c_mecabTest :: IO ()

/* wrapper.cpp */

#include <mecab.h>
#include <iostream>

extern "C" {

void mecabTest(){
char input[1024] = "太郎は次郎が持っている本を花子に渡した。";
MeCab::Tagger *tagger = MeCab::createTagger (0, 0);
const MeCab::Node* node = tagger->parseToNode(input);
for (; node; node = node->next) {
std::cout << node->id << ' ';
if (node->stat == MECAB_BOS_NODE)
std::cout << "BOS";
else if (node->stat == MECAB_EOS_NODE)
std::cout << "EOS";
else
std::cout.write (node->surface, node->length);

std::cout << ' ' << node->feature
<< ' ' << (int)(node->surface - input)
<< ' ' << (int)(node->surface - input + node->length)
<< ' ' << node->rcAttr
<< ' ' << node->lcAttr
<< ' ' << node->posid
<< ' ' << (int)node->char_type
<< ' ' << (int)node->stat
<< ' ' << (int)node->isbest
<< ' ' << node->alpha
<< ' ' << node->beta
<< ' ' << node->prob
<< ' ' << node->cost << std::endl;
}

delete tagger;
}

}


ビルドと実行。

$ ghc --make main.hs wrapper.cpp /usr/local/lib/libmecab.dylib -lstdc++
$ ./main
0 BOS BOS/EOS,*,*,*,*,*,*,*,* 0 0 0 0 0 0 2 1 0 0 0 0
5 太郎 名詞,固有名詞,人名,名,*,*,太郎,タロウ,タロー 0 6 1291 1291 44 2 0 1 0 0 0 8614
8 は 助詞,係助詞,*,*,*,*,は,ハ,ワ 6 9 261 261 16 6 0 1 0 0 0 9699
15 次郎 名詞,固有名詞,人名,名,*,*,次郎,ジロウ,ジロー 9 15 1291 1291 44 2 0 1 0 0 0 20566
18 が 助詞,格助詞,一般,*,*,*,が,ガ,ガ 15 18 148 148 13 6 0 1 0 0 0 21070
22 持っ 動詞,自立,*,*,五段・タ行,連用タ接続,持つ,モッ,モッ 18 24 742 742 31 2 0 1 0 0 0 25702
31 て 助詞,接続助詞,*,*,*,*,て,テ,テ 24 27 307 307 18 6 0 1 0 0 0 24174
40 いる 動詞,非自立,*,*,一段,基本形,いる,イル,イル 27 33 919 919 33 6 0 1 0 0 0 24723
46 本 名詞,一般,*,*,*,*,本,ホン,ホン 33 36 1285 1285 38 2 0 1 0 0 0 29905
53 を 助詞,格助詞,一般,*,*,*,を,ヲ,ヲ 36 39 156 156 13 6 0 1 0 0 0 29095
54 花 名詞,一般,*,*,*,*,花,ハナ,ハナ 39 42 1285 1285 38 2 0 1 0 0 0 33000
63 子 名詞,接尾,一般,*,*,*,子,コ,コ 42 45 1298 1298 51 2 0 1 0 0 0 39627
65 に 助詞,格助詞,一般,*,*,*,に,ニ,ニ 45 48 151 151 13 6 0 1 0 0 0 39654
77 渡し 動詞,自立,*,*,五段・サ行,連用形,渡す,ワタシ,ワタシ 48 54 735 735 31 2 0 1 0 0 0 42751
86 た 助動詞,*,*,*,特殊・タ,基本形,た,タ,タ 54 57 435 435 25 6 0 1 0 0 0 41874
89 。 記号,句点,*,*,*,*,。,。,。 57 60 8 8 7 3 0 1 0 0 0 38440
91 EOS BOS/EOS,*,*,*,*,*,*,*,* 60 60 0 0 0 0 3 1 0 0 0 36904



動いたー!

[Android]android-scripting

最近android-scriptingを使って
Android端末上でPerlを動かしたりしていたのですが、
昨日アプリ自体がアップデートされたみたいだったので
再度インストールしてみました。

sl4a_r0.apk」というのをインストールすれば良いみたいです。

アプリ名が「ase」だったのが「sl4a」に変わり
それに伴いスクリプトが保存されている場所も
「/mnt/sdcard/sl4a/scripts」に移動したりしていました。

また、Perlの場合だと「utf8.pm」あたりが最初から入っている状態になったので
JSONを利用する場合等でも落ちなくなりました。
自分でモジュールをつっこんで回避していたので、これはありがたいです。

インタープリタのインストール方法も変更されたみたい。
例えば「perl_for_android_r0.apk」などのインタープリタをインストールするための
専用アプリが用意されていました。少し面倒くさなった感じです。
自分の環境ではJRubyとかのインストールでこけていたので
それが解消されたのは良かったです。
プロフィール

jou4

Author:jou4
FC2ブログへようこそ!

最新記事
最新コメント
最新トラックバック
月別アーカイブ
カテゴリ
検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。