Hatena::ブログ(Diary)

yukobaのブログ このページをアンテナに追加 RSSフィード Twitter

2013年07月17日 QEMUでARM版Ubuntuの動作方法

QEMUARMUbuntuの動作方法

QEMUでARM版Ubuntuの動作させるとこんな感じで動きます。速度的に、2コアのノートパソコン第3世代Core i5で動かして、たぶんPentium 3くらいの感じになります。キーボードマウスもマウスホイールネットワークも問題ないです。gccapt-getインストールできます。

f:id:yukoba:20130717165636p:image

Ubuntu 側でやる作業

VMware 上の Ubuntu 12.04 で行いました。SDカードイメージダウンロードして展開しているだけです。yukoba:yukoba になっているところは適当に変えてください。

wget http://releases.linaro.org/13.06/ubuntu/vexpress/vexpress-raring_alip_20130625-379.img.gz
gunzip vexpress-raring_alip_20130625-379.img.gz

sudo mkdir /mnt/mnt
(IMG=vexpress-raring_alip_20130625-379.img ; if [ -e "$IMG" ] ; then sudo mount -o loop,offset="$(file "$IMG" | awk 'BEGIN { RS=";"; } /partition 2/ { print $7*512; }')" -t auto "$IMG" /mnt/mnt; else echo "$IMG not found"; fi )

sudo cp -vr /mnt/mnt/boot .
sudo chown -R yukoba:yukoba boot
sudo umount /mnt/mnt
mv vexpress-raring_alip_20130625-379.img boot/

Windows 側でやる作業

上記の boot フォルダを Windows 側にコピーしてください。そして、http://lassauge.free.fr/qemu/ (QEMU on Windows) から QEMU をダウンロードして、C:\Program Files\Qemu-windows-1.5.1 とかに展開します。

boot フォルダに移動して、以下のコマンドで実行できます。

"C:\Program Files\Qemu-windows-1.5.1\qemu-system-armw.exe" -kernel vmlinuz-3.10.0-1-linaro-vexpress -M vexpress-a9 -cpu cortex-a9 -serial stdio -m 1024 -initrd initrd.img-3.10.0-1-linaro-vexpress -append "root=/dev/mmcblk0p2 rw mem=1024M raid=noautodetect console=ttyAMA0,38400n8 rootwait vmalloc=256MB devtmpfs.mount=0" -sd vexpress-raring_alip_20130625-379.img

以上のやり方は、https://wiki.linaro.org/PeterMaydell/QemuVersatileExpress より修正。

トラックバック - http://d.hatena.ne.jp/yukoba/20130717

2013年02月17日 海外航空券の値段の比較

海外航空券の値段の比較

海外航空券の値段を調べてみました。東京サンフランシスコ 往復(月曜日出発、執筆時は日曜日)。

    明日or明後日 1週間後 2週間後
HIS   111,200 90,680 75,670
JTB 117,550 97,950 74,650
ANA 110,000 99,000 99,000
楽天       99,675
KAYAK 103,880
Expedia 105,000
デルタ航空 110,150 126,150 105,150
スカイゲート113,825 110,465 108,825
阪急交通 123,420 102,330
JAL 331,210 119,210
ユナイテッド航空 120,790

全て、燃油・諸税込。

Yahoo, トラベルコ, AB-ROAD はわけ分からないので除外。KAYAK は米ドルから日本円に換算(カード決済だともっと高くなるはず)。

スカイゲート, JTB 1週間後、非直行 です。

他の地域でも、おおむね、HIS が、だいたい最安です。

トラックバック - http://d.hatena.ne.jp/yukoba/20130217

2012年11月26日 JNAをAndroidで使う方法

JNA を Android で使う方法

C言語ライブラリJava から使うときに便利な https://github.com/twall/jna (JNA) を Android で使う方法のメモです。(追記:JNA 4.0.0 に合わせて大幅に書き換えました)

JNA は 4.0.0 現在、Android に対応していますが、ドキュメントがないです。3.4.0 当時、Android 対応をしようとして、中途半端になっていて、3.5.1 でその残骸が残っていましたが、4.0.0 ではちゃんと対応しています。

手順

  1. https://github.com/twall/jna/raw/master/dist/android-arm.jarダウンロードして、解凍して、libjnidispatch.so を取り出します。
  2. libjnidispatch.so を自分の Android アプリプロジェクトフォルダの libs/armeabi に置きます。

注意点

注意点は、下記のように Structure にはフィールドの順番を指定しないといけないです。(追記:昔のJNAはこれが必須ではなかったのですが、JNA 3.5.0 からそもそも必須です。)

@Override
protected List getFieldOrder() {
    return Arrays.asList("x", "y");
}

JP tanaJP tana 2013/05/17 17:27 有難うございます。大変、参考になりました。

2012年10月12日 AndroidでC言語のライブラリのビルド方法のまとめ

AndroidC言語ライブラリビルド方法のまとめ

Android は Linux の一種でもあり、ARM で動く Linux 向けのC言語で書かれたライブラリの多くが動きます。(多少違うので、動かない場合もあり)。ただし、ビルド方法が暗黙の了解事項になってたりして、Android NDK にちゃんと書かれていなかったりするので、ここにまとめます!

以下、架空の libhoge をビルドすることとします。

ビルド対象は一般的に静的ライブラリ (.a) ファイルにしておくと吉です。自分で使う際は、自分の Android.mk に以下の物を追加します。

  • LOCAL_CFLAGS に -Ihoge-1.0/include みたいのを追加
  • LOCAL_LDLIBS に -Lhoge-1.0-android-build/$(TARGET_ARCH_ABI) と -l hoge を追加

ライブラリをビルドしてできた libhoge.a はこのフォルダに置いておきます。

  • hoge-1.0-android-build/armeabi
  • hoge-1.0-android-build/armeabi-v7a
  • hoge-1.0-android-build/x86

必要な物:

手順は以下の順番で検討していくと良いです。

1.Android でのビルド方法がライブラリに明示されている場合

当然、このケースは、ライブラリに従うとビルドできるはずです。

2.Android.mk だけが用意されている場合

export NDK_ROOT=~/android-ndk-r9c
cd ~/hoge-1.0
$NDK_ROOT/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_ABI=armeabi obj/local/armeabi/libhoge.a
$NDK_ROOT/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_ABI=armeabi-v7a obj/local/armeabi-v7a/libhoge.a
$NDK_ROOT/ndk-build NDK_PROJECT_PATH=. APP_BUILD_SCRIPT=./Android.mk APP_ABI=x86 obj/local/x86/libhoge.a

obj/local にできたやつがコンパイル結果です。

3.なにもなくて、gcc の標準のビルドスタイルの場合

./configure → make → make install のパターンの場合です。

まず、スタンドアローンツールチェインをインストールする必要があります。Android NDK の docs/STANDALONE-TOOLCHAIN.html に説明が書いてあります。以下、android-9 にしたので、Android 2.3 用です。

export NDK_ROOT=~/android-ndk-r9c
$NDK_ROOT/build/tools/make-standalone-toolchain.sh --platform=android-9 --toolchain=arm-linux-androideabi-4.6 --install-dir=$HOME/android-toolchain-arm-4.6
$NDK_ROOT/build/tools/make-standalone-toolchain.sh --platform=android-9 --toolchain=x86-4.6 --install-dir=$HOME/android-toolchain-x86-4.6

さて、ビルド方法。以下、configure が置いてある元のソースフォルダを汚さないように別のフォルダを作ってビルドします。ソースは ~/hoge-1.0 とかに展開してあるとします。

export ANDROID_TOOLCHAIN=~/android-toolchain-arm-4.6
export BUILD_HOST=arm-linux-androideabi

export PATH=$ANDROID_TOOLCHAIN/bin:$PATH
export CC=$BUILD_HOST-gcc
export CFLAGS="-mthumb -march=armv7-a -mfloat-abi=softfp -I$ANDROID_TOOLCHAIN/include"
export LDFLAGS="-Wl,--fix-cortex-a8"

mkdir ~/hoge-1.0-android
cd ~/hoge-1.0-android
../hoge-1.0/configure --host=$BUILD_HOST --prefix=$PWD/build-result
make -j 4
make install

すると、~/hoge-1.0-android/build-result にビルド結果が作られるので、lib/libhoge.a を探してください。

上記の方法は、armeabi-v7a の方で Cortex-A シリーズしか動かなく、このようにすると、armeabi になり、全ての Android で動くようになります。

export CFLAGS="-mthumb -march=armv5te -I$ANDROID_TOOLCHAIN/include"

また、NEON (Advanced SIMD) を有効にするには、このようにします。NVIDIA Tegra 2 で動かなくなります。

export CFLAGS="-mthumb -march=armv7-a -mfloat-abi=softfp -mfpu=neon -I$ANDROID_TOOLCHAIN/include"

ちなみに、configure の --host、arm-linux-androideabi ($BUILD_HOST) ですが、arm-linux にして Android であることを隠してしまうとうまくいく場合もあったりなかったりします。Android NDK r8b 現在、Elf32_auxv_t が未定義だったり、微妙に Android は Linux と差があるんですが…

次に Android x86。

export ANDROID_TOOLCHAIN=~/android-toolchain-x86-4.6
export BUILD_HOST=i686-linux-android

export PATH=$ANDROID_TOOLCHAIN/bin:$PATH
export CC=$BUILD_HOST-gcc
export CFLAGS="-I$ANDROID_TOOLCHAIN/include"
export LDFLAGS=""

mkdir ~/hoge-1.0-android-x86
cd ~/hoge-1.0-android-x86
../hoge-1.0/configure --host=$BUILD_HOST --prefix=$PWD/build-result
make -j 4
make install

同じく、~/hoge-1.0-android-x86/build-result にビルド結果が作られるので、lib/libhoge.a を探してください。

2012年09月30日 GMOクラウド Public APIのJavaクライアント

GMOクラウド Public APIJavaクライアント

GMOクラウド Public APIのJavaクライアントを作りました

https://github.com/yukoba/GmoCloudAPI

使い方

GmoCloud gmoCloud = new GmoCloud(ACCESS_KEY_ID, SECRET_KEY, "jp002");
String json = gmoCloud.listNodesJson();
トラックバック - http://d.hatena.ne.jp/yukoba/20120930

2012年04月11日 AndroidでPOCO C++ Librariesの実行方法

AndroidでPOCO C++ Librariesの実行方法

http://pocoproject.org/ ですが、1.4.2 から Android 対応しているのですが、マニュアルドキュメント不足でいまいちわからなかったので、ここにメモしておきます。

ライブラリ自体のコンパイル方法

http://pocoproject.org/docs/99300-AndroidPlatformNotes.html どおりです。Ubuntu 12.04 (x64) でも MinGW でもどちらでもコンパイルできました。Ubuntu x64 の場合aptitude install ia32 する必要があります。

こんな感じで、my-android-toolchain を作って、

export NDK=$HOME/android-ndk-r7c
$NDK/build/tools/make-standalone-toolchain.sh --platform=android-8 --install-dir=$HOME/my-android-toolchain
export PATH=$HOME/my-android-toolchain/bin:$PATH

こんな感じでコンパイルできます。

cd poco-1.4.3p1
./configure --config=Android --no-samples --no-tests
make -s -j4
make -s -j4 ANDROID_ABI=armeabi-v7a

そして、--platform=android-8 を --arch=x86 に変え、ANDROID_ABI=x86 にすると、x86 Android でも動作します。エミュレータで高速に動作するようになります。

ndk-build との併用方法

この部分がドキュメント不足でした。

まず、Application.mk に

APP_STL      := gnustl_static

gnustl_static でも gnustl_shared でもどちらでも動作しますが、gnustl_shared の場合、Java 側から、System.loadLibrary("gnustl_shared"); する必要があります。

Android.mk に

LOCAL_CPP_FEATURES += exceptions rtti

を追加し、更に、

  • LOCAL_CFLAGS には -Ipoco-1.4.3p1/Foundation/include -Ipoco-1.4.3p1/Net/include -Ipoco-1.4.3p1/Xml/include -Ipoco-1.4.3p1/Util/include を追加します。
  • LOCAL_LDLIBS の先頭に、-Lpoco-1.4.3p1/lib/Android/armeabi-v7a -lPocoNet -lPocoXml -lPocoUtil -lPocoFoundation を追加します。
  • LOCAL_STATIC_LIBRARIES に、libgnustl_static を追加します。

poco-1.4.3p1 へのパスは適切に変えてください。exceptions rtti は動作させるのに必須です。それ故、APP_STL は gnustl を使わないとダメです。

NativeActivity を使っているのですが、AndroidManifest.xml は例えば、こんな感じにします。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.example.hoge"
      android:versionCode="1"
      android:versionName="1.0">

    <uses-permission android:name="android.permission.INTERNET" />
    <uses-sdk android:minSdkVersion="10" />

    <application android:label="@string/app_name" android:hasCode="true" android:debuggable="true">
        <activity android:name="android.app.NativeActivity" android:label="@string/app_name">
            <meta-data android:name="android.app.lib_name" android:value="hoge" />
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest> 

HTTP 通信とか、StringTokenizer とかがちゃんと動作するところまで確認しました。

ただし、POCO の Thread.start() が Android NDK r7c + POCO 1.4.3p1 の組み合わせでは正常に動作しませんでした。原因不明。自分で Pthread を使う分には問題無いです。

(追記)最初にこのブログを書いた際、大幅に間違いを含んでいたので色々修正しました。

トラックバック - http://d.hatena.ne.jp/yukoba/20120411

2012年03月21日 SWT + JNA + Cairo

SWT + JNA + Cairo

Win32 ではこんな感じで出来ます。Cairo は http://www.gtk.org/download/win32.phpall-in-one bundle から入手するのがおすすめ

import com.sun.jna.Pointer;
import org.eclipse.swt.internal.win32.OS;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.junit.Test;

public class SWTTest {
    @Test
    public void test() {
        Display display = new Display();
        Shell shell = new Shell(display);
        shell.setText("Shell");
        shell.setSize(200, 200);
        shell.open();

        int hWnd = shell.handle;
        int hdc = OS.GetDC(hWnd);
        try {
            Cairo cairo = Cairo.INSTANCE;
            Pointer surface = cairo.cairo_win32_surface_create(hdc);
            Pointer pattern = cairo.cairo_pattern_create_rgba(1, 0, 0, 0.1);
            Pointer cr = cairo.cairo_create(surface);
            cairo.cairo_set_source(cr, pattern);
            cairo.cairo_rectangle(cr, 0, 0, 100, 100);
            cairo.cairo_fill(cr);
            cairo.cairo_destroy(cr);
            cairo.cairo_pattern_destroy(pattern);
            cairo.cairo_surface_destroy(surface);
        } finally {
            OS.ReleaseDC(hWnd, hdc);
        }

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) display.sleep();
        }
        display.dispose();
    }
}
import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;

public interface Cairo extends Library {
    final Cairo INSTANCE = (Cairo) Native.loadLibrary("libcairo-2", Cairo.class);

    // cairo_t
    Pointer cairo_create(Pointer target);
    void cairo_destroy(Pointer cr);
    void cairo_set_source(Pointer cr, Pointer source);
    void cairo_fill(Pointer cr);
    void cairo_rectangle(Pointer cr, double x, double y, double width, double heigth);

    // pattern
    Pointer cairo_pattern_create_rgb(double red, double green, double blue);
    Pointer cairo_pattern_create_rgba(double red, double green, double blue, double alpha);
    void cairo_pattern_destroy(Pointer pattern);

    // Surface
    void cairo_surface_destroy(Pointer surface);

    // Win32
    Pointer cairo_win32_surface_create(int hdc);
}
トラックバック - http://d.hatena.ne.jp/yukoba/20120321