暗号技術入門 秘密の国のアリス

qemu-system-arm で linaro のシステムイメージ (ubuntu) を動かす

必要なパッケージをインストール

  • sudo apt-get install qemu-system-arm qemu-utils

linaro からシステムイメージを取ってきて展開

  • wget -N http://releases.linaro.org/ubuntu/boards/lsk-vexpress/latest/lsk-vexpress-vivid_nano_20150725-725.img.gz
  • zcat lsk-vexpress-*.img.gz > vexpress.img

システムイメージからカーネルと initrd を取り出す

  • sudo modprobe nbd
  • sudo qemu-nbd -r -c /dev/nbd0 -v vexpress.img
  • # (上記コマンドから返ってこなくなった場合は、別のターミナルで以降の処理を継続)
  • mkdir tmp
  • sudo mount -o ro /dev/nbd0p2 tmp
  • sudo cp -p tmp/boot/vmlinuz-* vmlinuz
  • sudo cp -p tmp/boot/initrd.img-* initrd.img
  • sudo chown "$(id -un):$(id -gn)" vmlinuz initrd.img
  • sudo umount tmp
  • rmdir tmp
  • # (別のターミナルでの処理ここまで qemu-nbd は Ctrl-C で終了する)
  • sudo qemu-nbd -d /dev/nbd0 -v
  • # (別のターミナルで処理しなかった場合は上記コマンドを実行)
  • sudo rmmod nbd

以上で準備は完了


  • ls
  • initrd.img  lsk-vexpress-vivid_nano_20150725-725.img.gz  vexpress.img  vmlinuz

あとは起動するだけ (username/password は linaro/linaro)

  • qemu-system-arm -M vexpress-a9 -kernel vmlinuz -initrd initrd.img -m 512 -append "root=/dev/mmcblk0p2 vga=normal mem=512M devtmpfs.mount=0 rw" -drive file=vexpress.img,if=sd,cache=writeback

参考にしたサイト

Ubuntu 16.04 (Xenial Xerus) に VirtualBox (5.0.*) をインストールする

Ubuntu (Debianも同じ?) に VirtualBox をインストールする

apt-get upgrade とかで最新版に更新できるよう、リポジトリを追加する方法でやります。

基本的にはここに書かれているとおりにやります。
http://www.virtualbox.org/wiki/Linux_Downloads

<Ubuntu 16.04 LTS (Xenial Xerus) の場合>

  • echo "deb http://download.virtualbox.org/virtualbox/debian xenial contrib" | sudo tee /etc/apt/sources.list.d/oracle_vbox.list
  • wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
  • sudo apt-key finger
  • sudo apt-get update
  • sudo apt-get install virtualbox-5.0


(以下、説明)

1. リポジトリを追加

  • echo "deb http://download.virtualbox.org/virtualbox/debian xenial contrib" | sudo tee /etc/apt/sources.list.d/oracle_vbox.list

2. キーを追加

  • wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -

3. キーの確認 (任意)

  • sudo apt-key finger

一覧された中にある Oracle Corporation のキーの fingerprint が、上記 VirtualBox サイトの "The key fingerprint is" に書かれている fingerprint と一致することを確認。

4. インストール

  • sudo apt-get update
  • sudo apt-get install virtualbox-5.0

完了です。

その他のバージョンについては、上記 "xenial" をそれぞれ以下に変更して実行します。

"precise"
12.04 LTS (Precise Pangolin)
"trusty"
14.04 LTS (Trusty Tahr)
"vivid"
15.04 (Vivid Vervet)
"wily"
15.10 (Wily Werewolf)
"xenial"
16.04 LTS (Xenial Xerus)

NTP (SNTP) tips / SntpTest.java

もし、いまAndroid(iOSも?)を含むUnix系システムでNTP関連のプログラムを書きたいと思っている場合は、 下の表の <B> の式を使うようにすれば、2104年まで動きます。

period (UTC)conversion (ntp time → unix time)
1900-01-01 00:00:00

1968-01-20 03:14:07
<A>
(ntp_time >>> 32)
- 2208988800L
1968-01-20 03:14:08

2036-02-07 06:28:15
<B>
(ntp_time >> 32)
+ 2085978496L
2036-02-07 06:28:16

2104-02-26 09:42:23
<C>
(ntp_time >>> 32)
+ 2085978496L
2104-02-26 09:42:24

2172-03-15 12:56:31

上の表の式の違いについて書くと、以下のようになります。

date and time (UTC)ntp time (upper 32bit)unix time
<A>
1900-01-01 00:00:000x00000000 00xFFFFFFFF7C558180-2208988800
1968-01-20 03:14:070x7FFFFFFF 21474836470xFFFFFFFFFC55817F -61505153
1968-01-20 03:14:080x80000000 21474836480xFFFFFFFFFC558180 -61505152
1970-01-01 00:00:000x83AA7E80 22089888000x0000000000000000 0
2036-02-07 06:28:150xFFFFFFFF 42949672950x000000007C55817F 2085978495
<B>
1968-01-20 03:14:080x80000000-21474836480xFFFFFFFFFC558180 -61505152
1970-01-01 00:00:000x83AA7E80-20859784960x0000000000000000 0
2036-02-07 06:28:150xFFFFFFFF -10x000000007C55817F 2085978495
2036-02-07 06:28:160x00000000 00x000000007C558180 2085978496
2038-01-19 03:14:070x03AA7E7F 615051510x000000007FFFFFFF 2147483647
2038-01-19 03:14:080x03AA7E80 615051520x0000000080000000 2147483648
2104-02-26 09:42:230x7FFFFFFF 21474836470x00000000FC55817F 4233462143
<C>
2036-02-07 06:28:160x00000000 00x000000007C558180 2085978496
2038-01-19 03:14:070x03AA7E7F 615051510x000000007FFFFFFF 2147483647
2038-01-19 03:14:070x03AA7E80 615051520x0000000080000000 2147483648
2104-02-26 09:42:230x7FFFFFFF 21474836470x00000000FC55817F 4233462143
2104-02-26 09:42:240x80000000 21474836480x00000000FC558180 4233462144
2106-02-07 06:28:150x83AA7E7F 22089887990x00000000FFFFFFFF 4294967295
2106-02-07 06:28:160x83AA7E80 22089888000x0000000100000000 4294967296
2172-03-15 12:56:310xFFFFFFFF 42949672950x000000017C55817F 6380945791

参考まで、Javaでのサンプルも置いておきます。

SntpTest.java
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.text.SimpleDateFormat;
import java.util.Date;

public final class SntpTest
{
    public static final void main(final String... args)
        throws Exception
    {
        final SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd EEE HH:mm:ss.SSS");
        for (final long timestamp: getTime("ntp.nict.jp"))
        {
            System.out.println(formatter.format(new Date(timestamp)));
        }
    }

    private static final long[] getTime(final String hostname)
        throws IOException, SocketException, UnknownHostException
    {
        final long[] timestamps = new long[4];
        final InetAddress address = InetAddress.getByName(hostname);
        final DatagramSocket socket = new DatagramSocket();
        try
        {
            socket.setSoTimeout(500);
            final byte[] buf = new byte[48];
            final DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 123);
            buf[0] = 0x23;
            timestamps[0] = System.currentTimeMillis();
            socket.send(packet);
            socket.receive(packet);
            timestamps[3] = System.currentTimeMillis();
            timestamps[1] = convert(ByteBuffer.wrap(buf).getLong(32));
            timestamps[2] = convert(ByteBuffer.wrap(buf).getLong(40));
        }
        finally
        {
            socket.close();
        }
        return timestamps;
    }

    private static final long convert(final long ntp_time)
    {
        return ((ntp_time >> 32) + 2085978496L) * 1000 + ((ntp_time & 0xFFFFFFFFL) * 1000 >> 32);
    }
}

[SQL] memo SQLite UPSERT (If exists UPDATE else INSERT)

CREATE TABLE table1(
  id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
  prefecture NOT NULL,
  city NOT NULL,
  team_name,
  team_color,
  UNIQUE(prefecture, city));

idprefecturecityteam_nameteam_color

REPLACE INTO table1
  SELECT id, prefecture, city, 'Izumi Momen', 'White'
    FROM (SELECT 'Osaka' AS prefecture, 'Izumi' AS city) LEFT NATURAL JOIN table1;

idprefecturecityteam_nameteam_color
1OsakaIzumiIzumi MomenWhite

REPLACE INTO table1
  SELECT id, prefecture, city, 'Kakurenbo', 'Brown'
    FROM (SELECT 'Kagoshima' AS prefecture, 'Izumi' AS city) LEFT NATURAL JOIN table1;

idprefecturecityteam_nameteam_color
1OsakaIzumiIzumi MomenWhite
2KagoshimaIzumiKakurenboBrown

REPLACE INTO table1
  SELECT id, prefecture, city, 'I Pearl', 'Brown'
    FROM (SELECT 'Osaka' AS prefecture, 'Izumi' AS city) LEFT NATURAL JOIN table1;

idprefecturecityteam_nameteam_color
1OsakaIzumiI PearlBrown
2KagoshimaIzumiKakurenboBrown

DELETE FROM table1
  WHERE prefecture = 'Kagoshima' AND city = 'Izumi';

idprefecturecityteam_nameteam_color
1OsakaIzumiI PearlBrown

REPLACE INTO table1
  SELECT id, prefecture, city, 'Izumi Mikan', 'Orange'
    FROM (SELECT 'Kagoshima' AS prefecture, 'Izumi' AS city) LEFT NATURAL JOIN table1;

idprefecturecityteam_nameteam_color
1OsakaIzumiI PearlBrown
3KagoshimaIzumiIzumi MikanOrange

[Android] memo

arm lib
android-ndk-r10c/platforms/android-21/arch-arm/usr/lib/libc.so: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=armeabi

arm64 lib
android-ndk-r10c/platforms/android-21/arch-arm64/usr/lib/libc.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=arm64-v8a

x86 lib
android-ndk-r10c/platforms/android-21/arch-x86/usr/lib/libc.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=x86

x86_64 lib64
android-ndk-r10c/platforms/android-21/arch-x86_64/usr/lib64/libc.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

ndk-build APP_ABI=x86_64

x86_64 lib (x86)
android-ndk-r10c/platforms/android-21/arch-x86_64/usr/lib/libc.so: ELF 32-bit LSB shared object, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

ndk-build APP_ABI=x86_64 APP_CFLAGS=-m32 APP_LDFLAGS=-m32

x86_64 libx32 (x32)
android-ndk-r10c/platforms/android-21/arch-x86_64/usr/libx32/libc.so: ELF 32-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), not stripped

ndk-build APP_ABI=x86_64 APP_CFLAGS=-mx32 APP_LDFLAGS=-mx32

mips lib (mips32)
android-ndk-r10c/platforms/android-21/arch-mips/usr/lib/libc.so: ELF 32-bit LSB shared object, MIPS, MIPS32 version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=mips

mips libr2 (mips32r2)
android-ndk-r10c/platforms/android-21/arch-mips/usr/libr2/libc.so: ELF 32-bit LSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=mips APP_CFLAGS=-mips32r2 APP_LDFLAGS=-mips32r2

mips libr6 (mips32r6)
android-ndk-r10c/platforms/android-21/arch-mips/usr/libr6/libc.so: ELF 32-bit LSB shared object, MIPS, version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=mips APP_CFLAGS=-mips32r6 APP_LDFLAGS=-mips32r6 # (4.9 <= NDK_TOOLCHAIN_VERSION)

mips64 lib64 (mips64r6)
android-ndk-r10c/platforms/android-21/arch-mips64/usr/lib64/libc.so: ELF 64-bit LSB shared object, MIPS, version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=mips64

mips64 lib64r2 (mips64r2)
android-ndk-r10c/platforms/android-21/arch-mips64/usr/lib64r2/libc.so: ELF 64-bit LSB shared object, MIPS, MIPS64 rel2 version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=mips64 APP_CFLAGS=-mips64r2 APP_LDFLAGS=-mips64r2

mips64 lib (mips32)
android-ndk-r10c/platforms/android-21/arch-mips64/usr/lib/libc.so: ELF 32-bit LSB shared object, MIPS, MIPS32 version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=mips64 APP_CFLAGS=-mips32 APP_LDFLAGS=-mips32

mips64 libr2 (mips32r2)
android-ndk-r10c/platforms/android-21/arch-mips64/usr/libr2/libc.so: ELF 32-bit LSB shared object, MIPS, MIPS32 rel2 version 1 (SYSV), dynamically linked, not stripped

ndk-build APP_ABI=mips64 APP_CFLAGS=-mips32r2 APP_LDFLAGS=-mips32r2

mips64 libr6 (mips32r6)
android-ndk-r10c/platforms/android-21/arch-mips64/usr/libr6/libc.so: ELF 32-bit LSB shared object, MIPS, version 1, dynamically linked, not stripped

ndk-build APP_ABI=mips64 APP_CFLAGS=-mips32r6 APP_LDFLAGS=-mips32r6

[Android] ndk-buildでstripさせない方法 (disable ndk-build stripping)

Android.mkに以下を追記。

  :
  :
cmd-strip :=
include ${BUILD_SHARED_LIBRARY}

[Android] Fix ndk "definitions.mk".

(patches for fixing below mentioned warnings)

Download: android-ndk-r9-fix-definitions.patch.bz2 (for Android NDK r9)
Download: android-ndk-r9b-fix-definitions.patch.bz2 (for Android NDK r9b)
Download: android-ndk-r9c-fix-definitions.patch.bz2 (for Android NDK r9c)
Download: android-ndk-r9d-fix-definitions.patch.bz2 (for Android NDK r9d)
Download: android-ndk-r10-fix-definitions.patch.bz2 (for Android NDK r10)
Download: android-ndk-r10b-fix-definitions.patch.bz2 (for Android NDK r10b)
Download: android-ndk-r10c-fix-definitions.patch.bz2 (for Android NDK r10c)
Download: android-ndk-r10d-fix-definitions.patch.bz2 (for Android NDK r10d)

Instructions.
(cd /path/to/android-ndk-r10d && bzcat /path/to/android-ndk-r10d-fix-definitions.patch.bz2 | patch -p1)

[armeabi-v7a] Compile thumb  : hoge <= hoge.c
In file included from /path/to/android-ndk-r10c/platforms/android-19/arch-arm/usr/include/linux/stddef.h:21:0,
                 from /path/to/android-ndk-r10c/platforms/android-19/arch-arm/usr/include/linux/posix_types.h:15,
                 from /path/to/android-ndk-r10c/platforms/android-19/arch-arm/usr/include/sys/types.h:37,
                 from /path/to/android-ndk-r10c/platforms/android-19/arch-arm/usr/include/stdio.h:50,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-19/arch-arm/usr/include/linux/compiler.h:25:31: warning: ISO C does not permit named variadic macros [-Wvariadic-macros]
[armeabi-v7a] SharedLibrary  : libhoge.so
[armeabi-v7a] Install        : libhoge.so => libs/armeabi-v7a/libhoge.so

[armeabi-v7a] Compile thumb  : hoge <= hoge.c
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/stdio.h:49:0,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/sys/cdefs.h:550:5: warning: "__LP64__" is not defined [-Wundef]
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/sys/types.h:32:0,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/stdio.h:50,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/stdint.h:41:5: warning: "__LP64__" is not defined [-Wundef]
/path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/stdint.h:49:5: warning: "__LP64__" is not defined [-Wundef]
[armeabi-v7a] SharedLibrary  : libhoge.so
[armeabi-v7a] Install        : libhoge.so => libs/armeabi-v7a/libhoge.so

[armeabi-v7a] Compile thumb  : hoge <= hoge.c
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/unistd.h:32:0,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/sys/cdefs.h:550:5: warning: "__LP64__" is not defined [-Wundef]
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/sys/types.h:32:0,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/unistd.h:33,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/stdint.h:41:5: warning: "__LP64__" is not defined [-Wundef]
/path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/stdint.h:49:5: warning: "__LP64__" is not defined [-Wundef]
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/asm/siginfo.h:19:0,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/linux/signal.h:22,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/signal.h:48,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/sys/select.h:35,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/unistd.h:34,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/asm-generic/siginfo.h:70:7: warning: ISO C forbids zero-size array '_pad' [-pedantic]
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/sys/ucontext.h:33:0,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/signal.h:51,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/sys/select.h:35,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/unistd.h:34,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm/usr/include/sys/user.h:37:5: warning: "__i386__" is not defined [-Wundef]
[armeabi-v7a] SharedLibrary  : libhoge.so
[armeabi-v7a] Install        : libhoge.so => libs/armeabi-v7a/libhoge.so

[arm64-v8a] Compile        : hoge <= hoge.c
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/asm/siginfo.h:22:0,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/linux/signal.h:22,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/signal.h:43,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/sys/select.h:35,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/unistd.h:34,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/asm-generic/siginfo.h:70:7: warning: ISO C forbids zero-size array '_pad' [-Wpedantic]
  char _pad[sizeof( __ARCH_SI_UID_T) - sizeof(int)];
       ^
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/sys/ucontext.h:33:0,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/signal.h:51,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/sys/select.h:35,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/unistd.h:34,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/sys/user.h:37:5: warning: "__i386__" is not defined [-Wundef]
 #if __i386__
     ^
In file included from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/sys/select.h:35:0,
                 from /path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/unistd.h:34,
                 from jni/hoge.c:1:
/path/to/android-ndk-r10c/platforms/android-21/arch-arm64/usr/include/signal.h:88:4: warning: ISO C99 doesn't support unnamed structs/unions [-Wpedantic]
   };
    ^
[arm64-v8a] SharedLibrary  : libhoge.so
[arm64-v8a] Install        : libhoge.so => libs/arm64-v8a/libhoge.so

patch (for r10d)
--- android-ndk-r10d/build/core/definitions-host.mk
+++ android-ndk-r10d/build/core/definitions-host.mk
@@ -145,6 +145,21 @@
 endif
 
 # -----------------------------------------------------------------------------
+# Function : host-c-system-includes
+# Arguments: 1: list of file paths (e.g. "foo bar")
+# Returns  : list of system include compiler options (e.g. "-isystemfoo -isystembar")
+# Usage    : $(call host-c-system-includes,<paths>)
+# Rationale: This function is used to translate Cygwin paths into
+#            Cygwin-specific ones. On other platforms, it will just
+#            return its argument.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),cygwin)
+host-c-system-includes = $(patsubst %,-isystem%,$(call host-path,$1))
+else
+host-c-system-includes = $(1:%=-isystem%)
+endif
+
+# -----------------------------------------------------------------------------
 # Function : host-copy-if-differ
 # Arguments: 1: source file
 #            2: destination file
--- android-ndk-r10d/build/core/definitions.mk
+++ android-ndk-r10d/build/core/definitions.mk
@@ -1616,7 +1616,7 @@
           $$(LOCAL_CONLYFLAGS) \
           $$(NDK_APP_CFLAGS) \
           $$(NDK_APP_CONLYFLAGS) \
-          $$(call host-c-includes,$$($(my)C_INCLUDES)) \
+          $$(call host-c-system-includes,$$($(my)C_INCLUDES)) \
           -c \
 
 _TEXT := Compile $$(call get-src-file-text,$1)
@@ -1718,7 +1718,7 @@
           $$(NDK_APP_CFLAGS) \
           $$(NDK_APP_CPPFLAGS) \
           $$(NDK_APP_CXXFLAGS) \
-          $$(call host-c-includes,$$($(my)C_INCLUDES)) \
+          $$(call host-c-system-includes,$$($(my)C_INCLUDES)) \
           -c \
 
 _CC   := $$(NDK_CCACHE) $$($$(my)CXX)

[bash] 相対パス取得関数

relpath()
{
  local IFS=/
  local path=($(readlink -f "${1:-.}"))
  local base=($(readlink -f "${2:-.}"))
  local n=$((${#path[@]} <= ${#base[@]} ? ${#path[@]} : ${#base[@]}))
  local i

  for ((i = 0; i < n; ++i))
  do
    [ "${path[i]}" = "${base[i]}" ] || break
  done
  base=("${base[@]/*/..}")
  path=(. "${base[@]:i}" "${path[@]:i}")
  path="${path[*]}"
  echo "${path#.${IFS}}"
}

[Androidメモ] ndk-build (definitions.mk) の修正 (for r9 and r9b)

(patchs for fixing below mentioned warnings)

Download: android-ndk-r9-fix-definitions.patch.bz2 (for Android NDK r9)
Download: android-ndk-r9b-fix-definitions.patch.bz2 (for Android NDK r9b)

たとえば、Application.mk で "APP_CFLAGS := -pedantic -std=c99" と書いたりしてコンパイラスイッチを追加したりすると、 <stdio.h> 等をインクルードしたソースを ndk-build を用いてコンパイルした際に以下のような警告が出る。

[armeabi-v7a] Compile thumb : hoge <= hoge.c
In file included from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/linux/stddef.h:21:0,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/linux/posix_types.h:15,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/sys/types.h:37,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/stdio.h:42,
from jni/hoge.c:1:
/path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/linux/compiler.h:25:31: warning: ISO C does not permit named variadic macros [-Wvariadic-macros]
[armeabi-v7a] SharedLibrary : libhoge.so
[armeabi-v7a] Install : libhoge.so => libs/armeabi-v7a/libhoge.so

<unistd.h> 等をインクルードするともう少し増えて、以下のように。

[armeabi-v7a] Compile thumb : hoge <= hoge.c
In file included from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/linux/stddef.h:21:0,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/linux/posix_types.h:15,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/sys/types.h:37,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/unistd.h:33,
from jni/hoge.c:1:
/path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/linux/compiler.h:25:31: warning: ISO C does not permit named variadic macros [-Wvariadic-macros]
In file included from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/asm/siginfo.h:15:0,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/signal.h:39,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/sys/select.h:34,
from /path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/unistd.h:34,
from jni/hoge.c:1:
/path/to/android-ndk-r9b/platforms/android-14/arch-arm/usr/include/asm-generic/siginfo.h:58:7: warning: ISO C forbids zero-size array '_pad' [-pedantic]
[armeabi-v7a] SharedLibrary : libhoge.so
[armeabi-v7a] Install : libhoge.so => libs/armeabi-v7a/libhoge.so

いわゆる(?)システムヘッダファイルに問題があるので、システムヘッダファイルを直すのも方法だけど、 本来、GCCはシステムヘッダファイルに対しては警告を出さないので、要するにシステムヘッダファイルがシステムヘッダファイルとしてインクルードされていないのが問題とも言える。
ということで、このパッチではコンパイルスイッチ -isystem を用いて、システムヘッダファイルはシステムヘッダファイルとしてインクルードされるように修正する。

Download: android-ndk-r9-fix-definitions.patch.bz2 (for Android NDK r9)
Download: android-ndk-r9b-fix-definitions.patch.bz2 (for Android NDK r9b)

念のためパッチの当て方を。
bzcat android-ndk-r9b-fix-definitions.patch.bz2 | (cd /path/to/android-ndk-r9b && patch -p1)

ファミリーマート(ファミマ)の店番号(店舗番号)の調べ方

(この記事の内容は非公式です。活用の際は自己責任で行なってください)


ファミリーマート店舗一覧 (非公式) [ http://wxh.jp/famima/ ] を見るか、


もしくは、ファミマ公式Webサイトの店舗検索 [ http://www.family.co.jp/store.html ] から店舗を検索して、
URLを見れば調べられる。


例えば、秋田県の鹿角大湯店なら、検索結果のURLは以下のようになる。


http://as.chizumaru.com/famima/detailMap?account=famima&accmd=0&bid=61353&c2=1&kkw001=%E9%B9%BF%E8%A7%92%E5%A4%A7%E6%B9%AF%E5%BA%97&pgret=2


bid=61353なので、店番号(店舗番号)は61353となる。 (5ケタ未満の場合は先頭にゼロがつく)

ネットに転がっていた写真を見ると確認できる。入り口右上の囲み数字が店番号。

http://livedoor.blogimg.jp/nagakigawa/imgs/b/0/b0a9905c.JPG


他にもいくつか挙げておく。


4147 西早稲田二丁目店 (東京都)

http://www.wasemachi.com/shop/shop-image/fm-nishiwaseda2.jpg


20692 目黒東山一丁目店 (東京都)

http://farm7.staticflickr.com/6001/5892598839_b1d0d32495_o.jpg


20740 荏原一丁目店 (東京都)

http://www.cocokala.jp/wp/wp-content/uploads/2013/08/946562_682007585162219_1212646068_n.jpg


21634 新宿税務署通り店 (東京都)

http://livedoor.blogimg.jp/shinjuku_news/imgs/7/1/71cc849c.jpg


34701 笠岡市民病院前店 (岡山県)

http://blog-imgs-56.fc2.com/d/a/r/darklord47/2012-0819-113653.jpg


72012 名護バイパス宮里店 (沖縄県)

http://userdisk.webry.biglobe.ne.jp/004/741/10/N000/000/004/136187848306713204059_CA3I0102.JPG


(この記事の内容は非公式です。活用の際は自己責任で行なってください)

[Androidメモ] ndk-build (definitions.mk) の修正 (for r8e)

(Patch for suppressing below-mentioned warnings)

ndk-build すると、こんな警告が出ていた。

/usr/include/linux/compiler.h: warning: ISO C does not permit named variadic macros [-Wvariadic-macros]
/usr/include/asm/siginfo.h: warning: ISO C forbids zero-size array '__pad0' [-pedantic]
/usr/include/asm/siginfo.h: warning: ISO C forbids zero-size array '_pad' [-pedantic]

システムヘッダーがシステムヘッダーとしてインクルードされていないのが原因のようなので、システムヘッダーは -isystem でパスを指定するようにする。これで警告が出なくなる。

ちなみに、android-ndk-r8e/build/core/build-binary.mk に対する修正は、ndk-build clean でエラーが出る不具合への対応。

android-ndk-definitions-fix-r8e.patch
diff -ru android-ndk-r8e/build/core/build-binary.mk android-ndk-r8e/build/core/build-binary.mk
--- android-ndk-r8e/build/core/build-binary.mk
+++ android-ndk-r8e/build/core/build-binary.mk
@@ -46,7 +46,7 @@
 $(cleantarget): PRIVATE_CLEAN_FILES := $(LOCAL_BUILT_MODULE) \
                                        $($(my)OBJS)
 else
-$(cleantarget): PRIVATE_CLEAN_FILES := ($(my)OBJS)
+$(cleantarget): PRIVATE_CLEAN_FILES := $($(my)OBJS)
 endif
 $(cleantarget)::
 	@$(HOST_ECHO) "Clean: $(PRIVATE_MODULE) $(PRIVATE_TEXT)"
diff -ru android-ndk-r8e/build/core/definitions-host.mk android-ndk-r8e/build/core/definitions-host.mk
--- android-ndk-r8e/build/core/definitions-host.mk
+++ android-ndk-r8e/build/core/definitions-host.mk
@@ -121,6 +121,21 @@
 endif
 
 # -----------------------------------------------------------------------------
+# Function : host-c-system-includes
+# Arguments: 1: list of file paths (e.g. "foo bar")
+# Returns  : list of system include compiler options (e.g. "-isystemfoo -isystembar")
+# Usage    : $(call host-c-system-includes,)
+# Rationale: This function is used to translate Cygwin paths into
+#            Cygwin-specific ones. On other platforms, it will just
+#            return its argument.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),cygwin)
+host-c-system-includes = $(patsubst %,-isystem%,$(call host-path,$1))
+else
+host-c-system-includes = $(1:%=-isystem%)
+endif
+
+# -----------------------------------------------------------------------------
 # Function : host-copy-if-differ
 # Arguments: 1: source file
 #            2: destination file
diff -ru android-ndk-r8e/build/core/definitions.mk android-ndk-r8e/build/core/definitions.mk
--- android-ndk-r8e/build/core/definitions.mk
+++ android-ndk-r8e/build/core/definitions.mk
@@ -1461,7 +1461,7 @@
           $$(call host-c-includes,$$(LOCAL_C_INCLUDES) $$(LOCAL_PATH)) \
           $$(LOCAL_CFLAGS) \
           $$(NDK_APP_CFLAGS) \
-          $$(call host-c-includes,$$($(my)C_INCLUDES)) \
+          $$(call host-c-system-includes,$$($(my)C_INCLUDES)) \
           -c \
 
 _TEXT := "Compile $$(call get-src-file-text,$1)"
@@ -1512,7 +1512,7 @@
           $$(NDK_APP_CFLAGS) \
           $$(NDK_APP_CPPFLAGS) \
           $$(NDK_APP_CXXFLAGS) \
-          $$(call host-c-includes,$$($(my)C_INCLUDES)) \
+          $$(call host-c-system-includes,$$($(my)C_INCLUDES)) \
           -c \
 
 _CC   := $$(NDK_CCACHE) $$($$(my)CXX)

念のためパッチの当て方を。
(cd /path/to/android-ndk-r8e && patch -p1 < /path/to/android-ndk-definitions-fix-r8e.patch)

[Androidメモ] ndk-build (definitions.mk) の修正

(Patch for suppressing below-mentioned warnings)

ndk-build すると、こんな警告が出ていた。

/usr/include/linux/compiler.h: warning: ISO C does not permit named variadic macros [-Wvariadic-macros]
/usr/include/asm/siginfo.h: warning: ISO C forbids zero-size array '__pad0' [-pedantic]
/usr/include/asm/siginfo.h: warning: ISO C forbids zero-size array '_pad' [-pedantic]

システムヘッダーがシステムヘッダーとしてインクルードされていないのが原因のようなので、システムヘッダーは -isystem でパスを指定するようにする。これで警告が出なくなる。

android-ndk-definitions-fix.patch
diff -ru android-ndk-r8d/build/core/definitions.mk android-ndk-r8d/build/core/definitions.mk
--- android-ndk-r8d/build/core/definitions.mk
+++ android-ndk-r8d/build/core/definitions.mk
@@ -242,6 +242,21 @@
 endif
 
 # -----------------------------------------------------------------------------
+# Function : host-c-system-includes
+# Arguments: 1: list of file paths (e.g. "foo bar")
+# Returns  : list of system include compiler options (e.g. "-isystemfoo -isystembar")
+# Usage    : $(call host-c-system-includes,<paths>)
+# Rationale: This function is used to translate Cygwin paths into
+#            Cygwin-specific ones. On other platforms, it will just
+#            return its argument.
+# -----------------------------------------------------------------------------
+ifeq ($(HOST_OS),cygwin)
+host-c-system-includes = $(patsubst %,-isystem%,$(call host-path,$1))
+else
+host-c-system-includes = $(1:%=-isystem%)
+endif
+
+# -----------------------------------------------------------------------------
 # Function : copy-if-differ
 # Arguments: 1: source file
 #            2: destination file
@@ -1500,7 +1515,7 @@
           $$(call host-c-includes,$$(LOCAL_C_INCLUDES) $$(LOCAL_PATH)) \
           $$(LOCAL_CFLAGS) \
           $$(NDK_APP_CFLAGS) \
-          $$(call host-c-includes,$$($(my)C_INCLUDES)) \
+          $$(call host-c-system-includes,$$($(my)C_INCLUDES)) \
           -c \
 
 _TEXT := "Compile $$(call get-src-file-text,$1)"

念のためパッチの当て方を。
(cd /path/to/android-ndk-r8d && patch -p1 < /path/to/android-ndk-definitions-fix.patch)

[Androidメモ] 最適なテキストサイズの取得 (時計アプリ)

画面に収まる最大のテキストサイズ(フォントサイズ)を取得(計算)したかったので、そのメモ。
二分探索を用いている。

テキストサイズは、
  • paint.measureText(text) で幅
  • paint.getFontMetrics(null) で高さ (= descent - ascent)
が得られるので、それを使用する。

描画位置は metrics.ascent を引いてやらないといけないので、
  • paint.getFontMetrics(metrics)
を使う。

com/example/ilo_oll/clock/Clock.java

package com.example.ilo_oll.clock;

import static java.lang.Math.*;

import java.util.TimeZone;

import android.app.Activity;
import android.graphics.*;
import android.os.Bundle;
import android.view.*;

public final class Clock
    extends Activity
{
    @Override
    protected final void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        final int offset =
            TimeZone.getDefault().getOffset(System.currentTimeMillis());
        final View view = new SurfaceView(this)
        {
            @Override
            protected final void onDraw(final Canvas canvas)
            {
                // ビューのサイズを取得
                final int viewWidth = getWidth(), viewHeight = getHeight();
                /* Viewのサイズが変わったらテキストサイズ(フォントサイズ)を計算する */
                if ((viewWidth != this.viewWidth) || (viewHeight != this.viewHeight))
                {
                    this.viewWidth = viewWidth;
                    this.viewHeight = viewHeight;

                    // 描画時と同じ条件にする
                    paint.setStyle(Paint.Style.FILL);
                    paint.setColor(Color.BLACK);
                    paint.setTypeface(Typeface.MONOSPACE); // 固定幅フォントにしておく
                    paint.setAntiAlias(true);

                    // 二分探索で最適なサイズを取得する (100回やれば十分)
                    float lower = 0.0f;
                    float upper = 2.0f * max(viewWidth, viewHeight);
                    for (int i = 0; i < 100; ++i)
                    {
                        // lowerとupperの中間値middleを計算し、
                        // テキストサイズがmiddleの場合の幅と高さを取得する
                        final float middle = 0.5f * (lower + upper);
                        paint.setTextSize(middle);
                        final float textWidth =
                            paint.measureText(text, 0, text.length);
                        final float textHeight = paint.getFontMetrics(null);

                        // テキストが画面に 収まる or 収まらない で場合わけする
                        if ((textWidth <= viewWidth) && (textHeight <= viewHeight))
                        {
                            // 収まる場合は、lowerにmiddleを格納する
                            // (探索範囲をmiddle 以上 に絞り込む)
                            lower = middle;
                        }
                        else
                        {
                            // 収まらない場合は、upperにmiddleを格納する
                            // (探索範囲をmiddle 以下 に絞り込む)
                            upper = middle;
                        }
                    }
                    // 最終的なテキストサイズはlowerとする (lowerは必ず画面に収まる)
                    textSize = lower;

                    // 描画位置を計算する (画面中央)
                    paint.setTextSize(textSize);
                    final float textWidth = paint.measureText(text, 0, text.length);
                    final float textHeight = paint.getFontMetrics(metrics);
                    x = 0.5f * (viewWidth - textWidth);
                    y = 0.5f * (viewHeight - textHeight) - metrics.ascent;
                }

                // 現在時刻を取得して文字列を更新
                long t0 = System.currentTimeMillis() + offset, t1, t2;
                for (final int[] table : TABLE)
                {
                    t1 = t0 % table[0];
                    t0 = t0 / table[0];
                    for (int i = 0; i < table[1]; ++i)
                    {
                        t2 = t1 % 10;
                        t1 = t1 / 10;
                        text[table[2] - i] = (char)('0' + t2);
                    }
                }

                // テキストサイズ計算時と同じ条件にする
                paint.setStyle(Paint.Style.FILL);
                paint.setColor(Color.BLACK);
                paint.setTypeface(Typeface.MONOSPACE); // 固定幅フォントにしておく
                paint.setAntiAlias(true);
                // テキストサイズを設定し、描画する
                paint.setTextSize(textSize);
                canvas.drawText(text, 0, text.length, x, y, paint);

                // ひたすら再描画
                invalidate();
            }

            private final Paint paint = new Paint();
            private final Paint.FontMetrics metrics = new Paint.FontMetrics();
            private final char[] text = "HH:MM:SS.XXX".toCharArray();

            private int viewWidth, viewHeight;
            private float textSize, x, y;
        };
        view.setBackgroundColor(Color.WHITE);
        view.setKeepScreenOn(true);
        setContentView(view);
    }

    private static final int[][] TABLE =
        {{1000, 3, 11}, {60, 2, 7}, {60, 2, 4}, {24, 2, 1}};
}

[Androidメモ] 前のconfigを保存する

onConfigurationChanged(Configuration)のnewConfigのインスタンスが使いまわされるみたい。
ということで、new Configuration(Configuration)で新しいインスタンスとして保存する。

AndroidManifest.java (抜粋)
        <activity
            android:name="XXX"
            android:label="XXX"
            android:configChanges="orientation|screenSize" >

MainActivity.java (抜粋)
public final class MainActivity
    extends Activity
{
    @Override
    public final void onConfigurationChanged(final Configuration newConfig)
    {
        Log.d("stdout",
            String.format("orientation: %d (prev: %d)", newConfig.orientation, config.orientation));
        config = new Configuration(newConfig);
        super.onConfigurationChanged(newConfig);
    }
    
    @Override
    protected final void onCreate(final Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        config = new Configuration(getResources().getConfiguration());
        Log.d("stdout", String.format("orientation: %d", config.orientation));
    }
    
    private Configuration config;
}

Linux (Unix-like) で共同作業を行う方法 (共有アカウント + sudo)

(共同作業についての一提案)

Linux (Unix-like system) で共同作業を行うために、アカウントの共有を行っている場合があるのではないかと思う。
しかし、アカウントの共有は情報セキュリティ上、好ましくない。

IPA(独立行政法人情報処理推進機構)によると、以下のように書かれている。

http://www.ipa.go.jp/security/ciadr/faq01.html#Q0-11 (抜粋)
Q0-11:アカウントの共有は何がまずいのでしょうか?

アカウントを共有した場合、パスワード管理に関して以下のような問題が考えられます。

  • 適切なパスワードを設定するのが困難である
  • 管理形態が曖昧になり変更が行われにくくなる
  • 変更の際に共有者への連絡が必要であるため、漏洩の可能性が増す
  • パスワードが不明になっての問い合わせが想定されるため、漏洩の可能性が増す

また、同時使用や自分がした覚えのない操作が行われていても当然であるため、誰かが成り済まして利用していても識別しにくくなります。

基本的にはアカウントの共有=パスワードの共有が問題ということだが、なりすましの識別がしにくくなるといった問題もあるようだ。

そこで、共同作業を行う場合には、setgid-bitを用いて、同じグループに属しているユーザなら書き込みができるような方法が取られることが多いと思う。
しかし、umaskが0002でないとうまく動かない。これ以外に何かうまい方法はないものだろうか。

ところで、アカウント共有の問題は管理者(root)についても言えることである。
上記のような背景からか、最近のLinux (Unix-like system)では、`sudo'を用いることで、パスワードを共有することなく管理者権限を得る方法がとられている。

ということは、共同作業にもこの方法を適用できるのではないかと考えてみた。


手順としては、共同作業用のアカウント、共同作業者用のグループを用意し、visudoで、/etc/sudoersを適切に設定しておき、共同作業の開始時にコマンドをひとつ実行するだけだ。

具体的には、以下のようになるだろう。
(コマンドはUbuntu Linuxでの例)

(1) 共同作業用のアカウントを用意する

sudo useradd -g users -m -N -s /usr/sbin/nologin project1
sudo passwd -l project1
(一般ユーザとして、共同作業用アカウントを追加し、ログインできないようにしておく)

(2) 共同作業者用のグループを用意する

sudo groupadd project1members
sudo usermod -a -G project1members user1
sudo usermod -a -G project1members user2
(共同作業者用グループを追加し、共同作業者をそのグループに属させる)

(3) visudoで/etc/sudoersを設定する

/etc/sudoers (追加部のみ抜粋)

  :

Defaults>project1 always_set_home
Defaults>project1 shell_noargs

  :

%project1members ALL=(project1) ALL

  :

(共同作業者用グループに属するユーザのみ、共同作業用アカウントとしてコマンドの実行を許可する)


これで、project1membersに属するユーザはsudoでproject1としてコマンドを実行できるようになる。
shell_noargsを設定しておけば、引数なしの場合はシェルが起動するので便利かもしれない。*1


共同作業を行う場合には、以下のコマンドで共同作業用アカウントとしての作業を開始すればいい。

sudo -u project1


共同作業用アカウントがいちいち必要になるといった欠点もあるが、使える方法ではないかと思う。




*1 shell-escapingという問題があるので、管理者権限を取得する場合はシェルは起動しないほうが良いのだが、この方法に慣れてしまうとついついシェルを起動してしまうようになってしまうかもしれない……。


gitのbundleファイルを展開する

「gitのbundleファイルをもらった。展開したい。」というときに。

$ cd /path/to/where
$ mkdir tmp
$ cd tmp
$ git init
$ git pull /path/to/bundle-file
$ ls -alF

(2012-06-14追記)
こちらのほうが良さげ。

$ cd /path/to/where
$ mkdir tmp
$ cd tmp
$ git clone /path/to/bundle-file
$ ls -alF

Android用のcurl/libcurl(+OpenSSL)をビルドする (configure/make)

Androidで動くlibcurlのビルド方法。

以下の記事を組み合わせて、httpsを処理できるlibcurlをビルドします。

まず、Android用のOpenSSLをビルドする (configure/make) のとおりにOpenSSLをビルド。

つづいて、適当なディレクトリを作成してそこに移動。

$ mkdir ~/build_curl && cd ~/build_curl

インストール先を~/android_libsにしておく。
どこでも良いが、OpenSSLと揃えておくと楽なのでそうしておく。

$ PREFIX="${HOME}/android_libs"

tarballをとってきてそれを展開、そこに移動。

$ wget -N -P .tarball http://curl.haxx.se/download/curl-7.26.0.tar.bz2
$ tar xf .tarball/curl-7.26.0.tar.bz2
$ cd curl-7.26.0

シェル変数を設定。
- ANDROID_NDK_HOMEはそれぞれの環境に応じて変えること。
  (ndk-buildのおいてあるディレクトリを指定する)
- ANDROID_VERSIONも適宜設定すること。

$ ANDROID_NDK_HOME="/path/to/android-ndk"
$ ANDROID_VERSION="android-14"

環境変数PATHを設定。
"4.4.3"の部分は将来変わると思うので、findの結果に応じて適宜変えること。

$ find "${ANDROID_NDK_HOME}/" -name arm-linux-androideabi-gcc
$ ANDROID_NDK_BIN="${ANDROID_NDK_HOME}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin"
$ export PATH="${ANDROID_NDK_BIN}:${PATH}"

CFLAGSを指定して configureする。
ポイントは --sysroot くらい。

$ CFLAGS="--sysroot=${ANDROID_NDK_HOME}/platforms/${ANDROID_VERSION}/arch-arm -fPIC -fomit-frame-pointer -ftree-vectorize -O3 -march=armv7-a -mandroid -mfpu=neon -mvectorize-with-neon-quad" \
  ./configure --prefix="${PREFIX}" --host=arm-linux-androideabi \
  --with-ssl="${PREFIX}"

makeしてインストールする

$ make && make install

エラーがなければ完了。
実行ファイルとライブラリはそれぞれ~/android_libs/binと~/android_libs/libに作られる

$ ls -alF ~/android_libs/{bin,lib}

Android用のOpenSSLをビルドする (configure/make)

Androidで動くOpenSSLのビルド方法。

ndk-buildを使わずに、configure/makeでOpenSSLをビルドします。
OpenSSLのConfigureはAndroidに対応していますのでビルドは容易です。

curlをビルドしたい場合はこの記事のあとで Android用のlibcurl(+OpenSSL)をビルドする (configure/make) を参照のこと。

とりあえず、適当なディレクトリを作成してそこに移動。

$ mkdir ~/build_openssl && cd ~/build_openssl

インストール先を~/android_libsにしておく。
どこでも良いので適宜変えること。

$ PREFIX="${HOME}/android_libs"

tarballをとってきてそれを展開、そこに移動。

$ wget -N -P .tarball http://www.openssl.org/source/openssl-1.0.1c.tar.gz
$ tar xf .tarball/openssl-1.0.1c.tar.gz
$ cd openssl-1.0.1c

シェル変数を設定。
- ANDROID_NDK_HOMEはそれぞれの環境に応じて変えること。
  (ndk-buildのおいてあるディレクトリを指定する)
- ANDROID_VERSIONも適宜設定すること。

$ ANDROID_NDK_HOME="/path/to/android-ndk"
$ ANDROID_VERSION="android-14"

環境変数を設定。
PATHとANDROID_DEV。
"4.4.3"の部分は将来変わると思うので、findの結果に応じて適宜変えること。

$ find "${ANDROID_NDK_HOME}/" -name arm-linux-androideabi-gcc
$ ANDROID_NDK_BIN="${ANDROID_NDK_HOME}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin"
$ export PATH="${ANDROID_NDK_BIN}:${PATH}"
$ export ANDROID_DEV="${ANDROID_NDK_HOME}/platforms/${ANDROID_VERSION}/arch-arm/usr"

configureする。

$ ./Configure --prefix="${PREFIX}" --cross-compile-prefix=arm-linux-androideabi- \
  android-armv7 threads zlib-dynamic shared no-asm no-sse2

makeしてインストールする

$ make && make install

エラーがなければ完了。
実行ファイルとライブラリはそれぞれ~/android_libs/binと~/android_libs/libに作られる

$ ls -alF ~/android_libs/{bin,lib}

configure && make for Android OS

Androidで動くバイナリとかライブラリとかを作る方法

Linux上で configure && make を使ってAndroid用バイナリをビルドする、というお話。

たとえばこんな感じ。
/path/to/install にインストールされる。

ANDROID_NDK_ROOT="/path/to/android-ndk" # (ndk-buildのあるところ)
ANDROID_VERSION="android-14"

ANDROID_SYSROOT="${ANDROID_NDK_ROOT}/platforms/${ANDROID_VERSION}/arch-arm"

export PATH="${ANDROID_NDK_ROOT}/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin:${PATH}"

CFLAGS="--sysroot=${ANDROID_SYSROOT} \
  -fPIC -fomit-frame-pointer -ftree-vectorize -O3 \
  -march=armv7-a -mandroid -mfpu=neon -mvectorize-with-neon-quad" \
./configure \
  "--prefix=/path/to/install" \
  "--host=arm-linux-androideabi" \
  &&
make &&
make install &&
echo OK

"--sysroot"がキモか。

gnome-keyring で warning が出るのを work-around してみる

xfce (xubuntu) で subversion とか使ってると、

WARNING: gnome-keyring:: couldn't connect to: /tmp/keyring-XXXXXX/pkcs11: No such file or directory

とか warning が出る。

work-around として、/etc/pkcs11/modules/gnome-keyring-module を削除する方法を見つけた。
(→ http://www.beduine.de/?p=618)

$ sudo rm /etc/pkcs11/modules/gnome-keyring-module

warning が出なくなった。
よくわからないが、クライアント認証を使う予定はいまのところないので、とりあえずこれで。

Ubuntu 11.10 (Oneiric Ocelot) に VirtualBox (4.1.*) をインストールする

Ubuntu (Debianも同じ?) に VirtualBox をインストールする

apt-get update とかで最新版に更新できるよう、リポジトリを追加する方法でやります。

基本的にはここに書かれているとおりにやります。

http://www.virtualbox.org/wiki/Linux_Downloads

2012年4月7日現在の最新版である、4.1 (4.1.*) をインストールします。


<Ubuntu 11.10 (Oneiric Ocelot) の場合>

$ echo "deb http://download.virtualbox.org/virtualbox/debian oneiric contrib" | sudo tee /etc/apt/sources.list.d/oracle_vbox.list
$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
$ sudo apt-key finger
$ sudo apt-get update
$ sudo apt-get install virtualbox-4.1

(以下、説明)

リポジトリを追加

$ echo "deb http://download.virtualbox.org/virtualbox/debian oneiric contrib" | sudo tee /etc/apt/sources.list.d/oracle_vbox.list

キーを追加

$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -

キーの確認 (任意)

$ sudo apt-key finger

一覧された中にある Oracle Corporation のキーの fingerprint が、上記 VirtualBox サイトの "The key fingerprint is" に書かれている fingerprint と一致することを確認。

インストール

$ sudo apt-get update
$ sudo apt-get install virtualbox-4.1

完了です。


その他のバージョンについてはこちらをご覧ください。

Independent JPEG Group (IJG)のJpegライブラリ (libjpeg) をVisual Studioでビルドする (コマンドライン編)

IJGから最新のパッケージをとってきて、何らかの方法で展開する。

Independent JPEG Group

展開できたらVisual Studioのコマンドプロンプトを起動後、例えばjpeg-9にcdして、

C:\jpeg-9>nmake /f makefile.vc setup-vc6
C:\jpeg-9>nmake /f makefile.vc cdebug="/Z7"
C:\jpeg-9>nmake /f makefile.vc test

で完了。同ディレクトリにlibjpeg.libができる。らくちん。

ヘッダファイルは以下の4つをコピーしておく。

  • jconfig.h
  • jerror.h
  • jmorecfg.h
  • jpeglib.h


「win32.mak が見つからない」と言われた場合は、以下のコマンドをnmakeの前に実行してみる。

http://support.microsoft.com/kb/2791460/ja

SET INCLUDE="C:\Program Files (x86)\Microsoft SDKs\Windows\v7.1A\Include;%INCLUDE%"

[Androidメモ] detach(View)

子ビューを親から切り離す。

java.lang.IllegalStateException: The specified child already has a parent. You must call removeView() on the child's parent first.

{
    private static final void detach(final View view)
    {
        final ViewParent parent = view.getParent();
        if (parent instanceof ViewGroup)
        {
            ((ViewGroup)parent).removeView(view);
        }
    }
}

パーティションテーブルの順番と最外周パーティション

普段は LVM を使っているので、たまに仮想マシンのセッティングを行う際に。
何の意味もないけれど、気分で。

ただ、swap が動作するような状況になる運用は基本的にはもうダメなわけで。
そうすると最外周に割り当てる必要もないけれど。。


以下の要求を満たすために。

  * swap パーティションはディスクの最外周に配置したい
  * でもパーティションテーブルの先頭には置きたくない (root=/dev/sda1 としたい)

以下は / と swap のみの単純な例。

1. ダミーのパーティションを最後尾に作成 → /dev/sda1 になる
2. swap パーティションを先頭に作成 → /dev/sda2 になる
3. ダミーのパーティションを削除し、/ パーティションを作成する → /dev/sda1 になる

これでパーティションテーブルの先頭は swap ではなく / となりつつも、
最外周に swap を割り当てることができる。

Ubuntu に VirtualBox をインストールする

Ubuntu に VirtualBox をインストールする

基本的にはここに書かれているとおりにやります。

http://www.virtualbox.org/wiki/Linux_Downloads

2012年4月7日現在の最新版である、4.1 (4.1.*) をインストールします。


<Ubuntu 11.10 (Oneiric Ocelot) の場合>

$ echo "deb http://download.virtualbox.org/virtualbox/debian oneiric contrib" | sudo tee /etc/apt/sources.list.d/oracle_vbox.list
$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
$ sudo apt-key finger
$ sudo apt-get update
$ sudo apt-get install virtualbox-4.1

(以下、説明)

リポジトリを追加

$ echo "deb http://download.virtualbox.org/virtualbox/debian oneiric contrib" | sudo tee /etc/apt/sources.list.d/oracle_vbox.list

キーを追加

$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -

キーの確認 (任意)

$ sudo apt-key finger

一覧された中にある Oracle Corporation のキーの fingerprint が、上記 VirtualBox サイトの "The key fingerprint is" に書かれている fingerprint と一致することを確認。

インストール

$ sudo apt-get update
$ sudo apt-get install virtualbox-4.1

完了です。


<Ubuntu 11.04 (Natty Narwhal) の場合>

上記 11.10 の場合と「リポジトリを追加」で行うことが変わります。それ以外は同じです。

$ echo "deb http://download.virtualbox.org/virtualbox/debian natty contrib" | sudo tee /etc/apt/sources.list.d/oracle_vbox.list
$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
$ sudo apt-key finger
$ sudo apt-get update
$ sudo apt-get install virtualbox-4.1


<Ubuntu 10.04 LTS (Lucid Lynx) の場合>

上記 11.10 の場合と「リポジトリを追加」で行うことが変わります。それ以外は同じです。

$ echo "deb http://download.virtualbox.org/virtualbox/debian lucid contrib non-free" | sudo tee /etc/apt/sources.list.d/oracle_vbox.list
$ wget -q http://download.virtualbox.org/virtualbox/debian/oracle_vbox.asc -O- | sudo apt-key add -
$ sudo apt-key finger
$ sudo apt-get update
$ sudo apt-get install virtualbox-4.1


<その他のバージョン>

11.04 や 10.04 と同様に参照するリポジトリを変える以外は 11.10 と同じ手順でインストールできます。
参照すべきリポジトリの記述に Ubuntu のコードネームが用いられるので、VirtualBox サイトの一覧等を参照して、適切にリポジトリを選択してください。

"gusty" : Ubuntu 7.10 (Gutsy Gibbon)
"hardy" : Ubuntu 8.04 LTS (Hardy Heron)
"interpid" : Ubuntu 8.10 (Intrepid Ibex)
"jaunty" : Ubuntu 9.04 (Jaunty Jackalope)
"kermic" : Ubuntu 9.10 (Karmic Koala)
"lucid" : Ubuntu 10.04 LTS (Lucid Lynx)
"maverick" : Ubuntu 10.10 (Maverick Meerkat)
"natty" : Ubuntu 11.04 (Natty Narwhal)
"oneiric" : Ubuntu 11.10 (Oneiric Ocelot)

VirtualBox の vdi ファイルをマウントする

VirtualBox の vdi ファイルをマウントする方法。

$ sudo modprobe nbd
$ sudo qemu-nbd -v -c /dev/nbd0 (vdi ファイル)
$ sudo mount /dev/nbd0p1 (マウント先)

/dev/nbd* は /dev/nbd0 から /dev/nbd15 まであるので、好きなのを選択。
qemu-nbd でファイルをデバイスに割り当てるとパーティションが/dev/nbd0p1 とか /dev/nbd0p2 とかにそれぞれ割り当てられるので、必要なものを使えばOK。

アンマウント。念の為 rmmod までしておく。

$ sudo umount /dev/nbd0p1
$ sudo qemu-nbd -v -d /dev/nbd0
$ sudo rmmod nbd

qemu-nbd にはスナップショットを使うオプションもあるけど、そちらは未調査。

半ディスクレス化

VirtualBox を使って Ubuntu Server の半ディスクレス化を試す。

/bootはローカルにあって、それ以外をNFSにしたい。

以下、DHCPが192.168.0.1/24で動いているとして。
NFSサーバ側/etc/exportsは、

[ /etc/exports ]
/export 192.168.0.1/24(rw,sync,no_subtree_check,no_root_squash)

としておいて、

VirtualBoxにUbuntu 11.04 Server をインストール。
ネットワークはブリッジにしておいて、HDDも2つ付けておく。
ひとつはインストール後に取り除く。
名前はhogeとしておく。HDDはhoge-1.vdiとhoge-2.vdiで。
hoge-1.vdi に/bootを割り当てて、hoge-2.vdiに/を割り当てる。

インストールが終わったら、とりあえず普通に再起動して、
GRUBの設定を変えて再起動。
(ここは好みに応じて)

[ /etc/default/grub ]
GRUB_CMDLINE_LINUX_DEFAULT=""
GRUB_TERMINAL=console

$ sudo update-grub
$ sudo reboot

再起動後にディスクレスブートの設定。
( 参考 http://philos0.blog94.fc2.com/blog-entry-39.html )

[ /etc/fstab ]
/dev/nfs / errors=remount-ro,hard,intr 0 1

[ /etc/initramfs-tools/initramfs.conf ]
MODULES=netboot
BOOT=nfs
NFSROOT=192.168.0.1:/export/diskless/hoge

[ /etc/network/interfaces ]
# auto eth0
# iface eth0 inet dhcp

で、
$ sudo update-initramfs -u
$ sudo poweroff


NFSサーバにインストールされたシステムを持ってくる。
VirtualBoxのvdiをマウントしてmvで持ってくることに。

$ sudo modprobe nbd
$ sudo qemu-nbd -v -c /dev/nbd0 /virtualbox/hoge/hoge-2.vdi
$ sudo mount /dev/nbd0p1 /mnt/hoge
$ sudo mkdir -p /export/diskless/hoge
$ (cd /mnt/hoge && sudo mv * /export/diskless/hoge/)
$ sudo umount /dev/nbd0p1
$ sudo qemu-nbd -v -d /dev/nbd0
$ sudo rmmod nbd

仮想マシンを起動すれば半ディスクレス化が完了。

しかし問題があって、update-grubがうまく動かないのでカーネルのバージョンアップができない。
$ sudo apt-get update
$ sudo apt-get dist-upgrade -y
失敗しちゃう。
grub-probeが/がNFSだとうまく動かないみたい。←イマココ

/usr/sbin/grub-probe: error: cannot stat `192.168.0.1:/export/diskless/hoge'.

/bootはローカルに置きたいのでgrubは動かしたい。。



(追記)
Quick Hackについて書かれていた。これやるとできた!
ひとまず完了。

http://groups.google.com/group/linux.debian.bugs.dist/browse_thread/thread/2b9384e230bb97c9/9aa2550126b0ab2e?pli=1

[ /usr/sbin/grub-mkconfig ]
GRUB_DEVICE="`${grub_probe} --target=device /boot`"

ファイルサーバ

ファイルサーバを立てるとする。
冗長化とバックアップをどうするか。
RAIDレベル、内蔵/外付け、バックアップ頻度とかも。

いろいろあって、以下のような構成が前提となった。
  • 内蔵250GB (システム用) 
  • 内蔵2TB x3 (データ用)
  • 外付け2TBx2 (バックアップ用)

バックアップは何かあったときに対応が楽なように、
Windowsからでも見れるような形で置いておきたい。
ということで、上記2機をFAT32でフォーマットすることにしよう。
で、こいつらはフルバックアップ用とすることに。

フルバックは用途的に1回/週くらいで良いかと(もっと低頻度でも良いかも)。
2台を1世代ずつに割り当てて、2世代分置いておくことにしたい。
で、差分バックアップを1回/日くらいに実施。

データ6TBに対してバックアップ2TB。うーん。

なんか違うなー。こうじゃない。

バックアップはポータブルかつリストアが容易な構成としたい一方、
内蔵はLVMとかでリサイザブルなシングルストレージとしたくなる。

[C] 要素数1の配列を使う

C言語でオブジェクト指向っぽいコードを書くときに、インスタンスを要素数1の配列とすると便利。
スタック上にメモリを自動確保してくれるポインタとして扱うイメージ。

こんな感じで。

typedef struct class1 class1_t;
struct class1
{
    :
};

extern int
class1_init(class1_t *self)
{
    :
}

extern int
class1_proc(class1_t *self, int argc, char *argv[])
{
    :
}

extern int
class1_free(class1_t *self)
{
    :
}

extern int
main(int argc, char *argv[])
{
    class1_t instance[1];
    
    class1_init(instance);
    class1_proc(instance, argc, argv);
    class1_free(instance);

    :
}

普通(?)は&を使って↓みたく書くんだろうけどね。なんかもっさり感があるので嫌。

extern int
main(int argc, char *argv[])
{
    class1_t instance;
    
    class1_init(&instance);
    class1_proc(&instance, argc, argv);
    class1_free(&instance);

    :
}

[Java]バイナリサーチ (二分探索)

バイナリサーチ(二分探索)。lo が inclusive で hi が exclusive。

private static final int binarySearch(final int[] a, int lo, int hi, final int x)
{
    int mi;
    hi = x <= a[lo] ? lo : hi;
    while ((mi = (lo + hi) >>> 1) > lo)
    {
        lo = x <= a[mi] ? lo : mi;
        hi = x <= a[mi] ? mi : hi;
    }
    return hi;
}

無理やり短くしてみる。

private static final int binarySearch(final int[] a, int l, int h, final int x)
{
    h = x <= a[l] ? l : h;
    for (int m; (m = (l + h) >>> 1) > l; l = x <= a[m] ? l : m, h = x <= a[m] ? m : h) ;
    return h;
}

(lo + hi) >>> 1 よりは lo + ((hi - lo) >> 1) のほうが大きな値まで対応できるけれど、配列の添字なので前者を使用。

Subversionアクセス制御中 (1)

Subversionのアクセス制御とその管理についてちまちまと。

Apacheでhttps経由アクセスにして、Basic認証をかける。
AuthzSVNAccessFileでリポジトリ・ディレクトリ単位の細かなアクセス制御をする。
管理用のWebUIを別途開発する。

環境はubuntu-10.10-server-amd64。

Basic認証はdbmのほうが性能が良いとのことなのでdbmで。

/etc/apache2/conf.d/svn_auth (の一部)
  :
AuthType Basic
AuthBasicProvider dbm
AuthDBMUserFile "/etc/apache2/svn_auth/dbm"
AuthDBMGroupFile "/etc/apache2/svn_auth/dbm"
  :

dbmを扱うときはpythonでこんな感じに。

$ sudo -u www-data python
>>> import base64, anydbm, hashlib
>>> db = anydbm.open("/etc/apache2/svn_auth/dbm", "rw")
>>> db
{'user': '{SHA}Et6pb+wgWTVmq3VpLJlJWWgzrck=:group'}
>>> db["user"]
'{SHA}Et6pb+wgWTVmq3VpLJlJWWgzrck=:group'
>>> db["user"] = "{SHA}%s:%s" % (base64.b64encode(hashlib.sha1("password").digest()), "group")
>>> db["user"]
'{SHA}W6ph5Mm5Pz8GgiULbPgzG37mj9g=:group'
>>> db.close()

Hello, world!

HelloWorld.java
public final class HelloWorld
{
    public static final void main(final String[] args)
    {
        System.out.println("Hello, world!");
    }
}

ilo_oll

ブログ開設
記事検索

月別アーカイブ
プロフィール

ilo_oll