MinGW gcc 32bit/64bit

投稿日: Leave a comment

mingw gccの64ビット環境を構築しようと思っていろいろ探し回ってみたけどよくわからず。

とりあえず、ここからファイルを展開してみたらmingw32とmingw64というフォルダが出来たので定位置においてパスを通せば大丈夫そう。

  • i686-w64-mingw32-gcc-4.7.2-release-win64_rubenvb.7z (32bit target)
  • x86_64-w64-mingw32-gcc-4.7.2-release-win64_rubenvb.7z (64bit target)

ファイル名がよくわからなかったけど、ここの下の方を見るとどちらも64ビットOS上で動作するコンパイラで、上が32ビットバイナリを作ってくれるコンパイラ、下が64ビットのバイナリを作ってくれるコンパイラ、らしい。

Packages are named as follows:

    [Target]-gcc-[Version]-release-[OS]-rubenvb.*
    [Target]-clang-[Version]-release-[OS]-rubenvb.*

Target:  GCC triplet for the system this toolchain builds code for:
         x86_64-w64-mingw32: 64-bit Windows
         i686-w64-mingw32: 32-bit Windows
Version: GCC version
OS:      OS the toolchain is built for:
         linux64: 64-bit linux
         win64: 64-bit Windows
         win32: 32-bit Windows (also work on 64-bit Windows)
         cygwin: Cygwin (www.cygwin.com)

今日のところはこれまで。おいおい使ってみる。

上のファイル名の解説に出てくるけど、最近はgccよりclangの方に興味あり。FreeBSDのシステムコンパイラがclangになるらしいし、コンパイルエラーの表示も見やすいし。

『リーダブルコード』

投稿日: Leave a comment

こんな本を買ってみた。

周りにプログラムを書く人がおらず、自分が書いたコードを見つめなおすために買ってみた。

まだ読んでる途中だけど、いろいろな言語を例に書かれていて結構参考になる、というか反省させられることが多い。コンピュータ言語の入門書はいくつか買って読んだことがあるけど、この手の本は初めて買ったかも。

ちなみに、本のリンクを張るのにアマゾンから写真を引っ張ってきたくて、アマゾンアソシエイトの登録をしてみた。この日記のアクセス数なんてたかが知れてるので、アフィリエイトとしての効果はほとんど期待してない。効果があればそれはそれでうれしいけど。

C++の参考ページ

投稿日: Leave a comment

C++のSTLコンテナやアルゴリズムなどを調べるのに役に立ちそうなページ

lambda式のメモ

投稿日: Leave a comment

無性にC++でlambda式を使ったコードの書き方を知りたくなって、ちょっと調べて書いてみた。

#include <iostream>
#include <vector>
#include <algorithm>

int main()
{
    std::vector<int> v(10);

    int n = 0;
    std::generate(v.begin(), v.end(), [&n]()->int{return n++;});

    std::for_each(v.begin(), v.end(), [](int a){std::cout << a << std::endl;});

    return 0;
}

これは大したコードではなくて、10要素のvector<int>型の配列に0から順にインクリメントした値をセットして、配列の中身をすべて表示するだけのもの。lambda式をgenerateとfor_eachの引数の2か所で使っている。

[&n]()->int{return n++;}

1つ目のこれは、main関数内で宣言したint型の変数n(=0)を返しつつ、呼び出すごとにnをインクリメントするので、呼び出すたびに0, 1, 2, … とインクリメントされた値が返ってくるlambda式(無名関数)。

[&n]のところを[n]にすると、値渡しになって変数nの実体は変更されないので、ずっとゼロが返ってくる。と思ったら、VC++2010だとエラーが出てコンパイルできなかった。

C:\work\test>cl lambda1.cpp /EHsc
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

lambda1.cpp
lambda1.cpp(10) : error C3491: 'n': a by-value capture cannot be modified in a non-mutable lambda

この部分のコードをfor文で書くとこんな感じになるはず。

//std::generate(v.begin(), v.end(), [&n]()->int{return n++;});
for (int i = 0; i < v.size(); i++) {
    v[i] = n++;
}
 [](int a){std::cout << a << std::endl;}

2つめは引数を取るタイプのlambda式。整数を受け取って、iostreamのcoutに流し込んで改行するだけ。

これもfor文で書くとこんな感じになるはず。

//std::for_each(v.begin(), v.end(), [](int a){std::cout << a << std::endl;});
for (int i = 0; i < v.size(); i++) {
    std::cout << a << std::endl;
}

[]と()の違いというか意味を真面目に調べてなかったので全く理解できてなかったけど、書いてみると思ったより簡単だった。

ここで書いたコードだとfor文でイテレータを回す方がコードとしては見やすいようにも思うけど、複雑なコンテナでソートなどの処理するような場合は、lambda式で比較条件式を書いた方がすっきりしそうなので、STLをバリバリ使ってコードを書く場合は役に立ちそう。

参考までに実行結果

C:\work\test>cl lambda1.cpp /EHsc
Microsoft (R) C/C++ Optimizing Compiler Version 16.00.40219.01 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

lambda1.cpp
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:lambda1.exe
lambda1.obj

C:\work\test>lambda1
0
1
2
3
4
5
6
7
8
9

日記のタイトル周りの表示を変更

投稿日: Leave a comment

前々から日記のタイトル行の先頭に日めくりカレンダー的なのをつけたいと思っていて、頑張ってテーマのphpをいじってみた。いじったのは、content.phpとstyle.css。

で、できたのがこれ↓

ついでに、”Leave a reply”のリンクも投稿日時の後ろにコンパクトに入れてみた。

テーマをTwenty Twelveに変更

投稿日: Leave a comment

WordPress 3.5beta1のアナウンスの下の方にTwenty Twelveのリリースについて触れられていたので、インストールしてテーマを変更してみた。

インストール

ダッシュボードの外観→テーマを開き、「テーマのインストール」タブを開く。

twentytwelveで検索すると出てくるのでインストールを押す。

子テーマの作成

そのまま、このテーマを適用してもいいけど、いじるときに元のファイルを触りたくないので、子テーマを作って変更するところだけファイルを用意するようにする。

ウェブからはできないので、サーバにログイン

%cd www/snapshots/wp-content/themes/
%mkdir snapshots2012
%vi style.css
%vi functions.php

style.cssには親テーマを定義するコメント行を書く。

/*
Theme Name:     Snapshots 2012
Description:    Child theme for the Twenty Twelve theme
Author:         s.ueda
Author URI:     http://aperire.sakura.ne.jp/snapshots/
Template:       twentytwelve
Version:        1.0.0
*/

functions.phpには、どのスタイルシートを呼ぶのかを書く。

<?php
// load stylesheet
if ( !is_admin() ) {
    wp_enqueue_style(
        'twentytwelve-style',
        get_template_directory_uri() . '/style.css',
        array(),
        date('YmdHis', filemtime(get_template_directory() . '/style.css'))
        );
    wp_enqueue_style(
        'snapshots2012-style',
        get_stylesheet_uri(),
        array('twentytwelve-style'),
        date('YmdHis', filemtime(get_stylesheet_directory() . '/style.css'))
        );
}

少しカスタマイズ

そのままだと記事のタイトル付近に日付が出なくて少しさみしいのでcontent.phpをいじって日時を出すようにしてみた。

%diff -uN twentytwelve/content.php snapshots2012/content.php
--- twentytwelve/content.php    2012-10-16 21:11:10.000000000 +0900
+++ snapshots2012/content.php   2012-10-16 22:48:41.000000000 +0900
@@ -5,6 +5,8 @@
  * @package WordPress
  * @subpackage Twenty_Twelve
  * @since Twenty Twelve 1.0
+ *
+ * modified by s.ueda
  */
 ?>

@@ -18,10 +20,12 @@
                        <?php the_post_thumbnail(); ?>
                        <?php if ( is_single() ) : ?>
                        <h1 class="entry-title"<>?php the_title(); ?></h1>
+                       <p><?php the_time('Y/m/d H:i') ?></p>
                        <?php else : ?>
                        <h1 class="entry-title">
                                <a href="<?php the_permalink(); ?>" title="<?php echo esc_attr( sprintf( __( 'Permalink to %s', 'twentytwelve' ), the_title_attribute( 'echo=0' ) ) ); ?>" rel="bookmark"><?php the_title(); ?></a>
                        </h1>
+                       <p><?php the_time('Y/m/d H:i') ?></p>
                        <?php endif; // is_single() ?>
                        <?php if ( comments_open() ) : ?>
                                <div class="comments-link">

 その他

ついでにTwitterのウィジェットを変更して、ヘッダーのメニュー構成も少し変えてみた。

FreeBSD 9.xのネットワーク設定

投稿日: Leave a comment

FreeBSD-9.0Rのネットワーク設定が8.xと違っていて少し手こずったので忘れないように書いておく。ちなみに、先日入れた9.1RC2でも同じ。

NICはIntel PRO/1000なので em0。DHCPは使わない。

IPv4

IPアドレスとデフォルトルータ

/etc/rc.conf:
ifconfig_em0="inet 192.168.100.3 netmask 255.255.255.0"
defaultrouter="192.168.100.1"

IPv6

RAを受け取る設定。
8.3Rでは ipv6_enable=”YES” と ipv6_network_interfaces=”em0″ と書いたら自動的に設定してくれていた。ifconfigコマンドのみで設定できるようになったのはシンプルでいい。

/etc/rc.conf:
ifconfig_em0_ipv6="inet6 accept_rtadv"

エイリアスをつける (長いアドレスはさすがに覚えられない)

/etc/rc.conf:
ifconfig_em0_alias0="inet6 2001:240:xxxx:xxxx::3 prefixlen 64"

テンポラリアドレスをつけて、通信時はこのテンポラリアドレスをなるべく使うように指定。

/etc/sysctl.conf:
net.inet6.ip6.use_tempaddr=1
net.inet6.ip6.prefer_tempaddr=1

DNS

DHCPを使わないのでresolv.confにDNSサーバのアドレスを書く。

/etc/resolv.conf:
nameserver 192.168.100.2
nameserver 192.168.100.1

 

これで、ifconfig em0の結果はこんな感じになる。

% ifconfig em0
em0: flags=8843<UP,BROADCAST,RUNNING,SIMPLEX,MULTICAST> metric 0 mtu 1500
        options=4219b<RXCSUM,TXCSUM,VLAN_MTU,VLAN_HWTAGGING,VLAN_HWCSUM,TSO4,WOL_MAGIC,VLAN_HWTSO>
        ether 00:19:d1:xx:xx:xx
        inet 192.168.100.3 netmask 0xffffff00 broadcast 192.168.100.255
        inet6 fe80::219:d1ff:fexx:xxxx%em0 prefixlen 64 scopeid 0x1
        inet6 2001:240:xxxx:xxxx::3 prefixlen 64
        inet6 2001:240:xxxx:xxxx:219:d1ff:fexx:xxxx prefixlen 64 autoconf
        inet6 2001:240:xxxx:xxxx:6cb1:4cd2:ec24:e946 prefixlen 64 autoconf temporary
        nd6 options=23<PERFORMNUD,ACCEPT_RTADV,AUTO_LINKLOCAL>
        media: Ethernet autoselect (1000baseT )
        status: active

FreeBSD 9.1RC2 on ZFS

投稿日: Leave a comment

zfsなファイルシステムにFreeBSD 9.1RC2を入れたのでその記録。

手順は「Installing FreeBSD 9.0-RELEASE Root on ZFS using GPT」がベース。途中、ちょっと変えたので念のためすべてのメモを残しておく。

一応前提 (参考にしたページと違っているところ)。

  • HDD 1個、ada0として認識。これにzfsパーティション1つにしてインストール。
  • スワップ領域はパーティションではなくファイルで領域を確保する。

1. ブート

余っていた2GBのmicroSDカードをUSBのカードリーダに挿してPC接続。これに、”FreeBSD-9.1-RC2-amd64-memstick.img”を書き込んで、このSDカードから起動。

書き込みは、ChkFlshというフラッシュメモリをチェックしたりフォーマットしたりするツールを使用。他にもいろいろツールはあるはず。

2. インストーラ開始

9.0Rから採用されたbsdinstallでインストールを開始。途中のパーティションを設定するところで、”shell”を選択する。

3.パーティション作成

たぶん、一つ目の肝。今回はディスク1個なので、ミラーは組まない。最初のzpool createのところ、なぜか -f をつけないとエラーがでてだめだった(赤字のところ)。
# virtualbox上で同じことをしたら -f は無くても大丈夫だった。(2012/10/28)

# gpart create -s gpt ada0
# gpart add -s 64K -t freebsd-boot -l boot0 ada0
# gpart add -t freebsd-zfs -l disk0 ada0
# gpart bootcode -b /boot/pmbr -p /boot/gptzfsboot -i 1 ada0

# zpool create -f -o altroot=/mnt zroot /dev/gpt/disk0
# zfs create zroot/tmp
# chmod 1777 /mnt/tmp
# zfs create zroot/usr
# zfs create zroot/var
# zfs create zroot/home
# exit

exitと打つとインストーラに戻る。

4.インストール実行

いつも通りのインストールをする。コピーするファイルやらネットワークの設定やら、アカウント作成やら。

インストールが終わると、Shellを立ち上げるよう促されるけど、そこはexitですぐ抜ける。

5. Live CDオプションでrootログイン

後半の肝。次回のブート時にちゃんとzfsが見えるように設定する。

# echo 'zfs_enable="YES"' >> /mnt/etc/rc.conf
# echo 'zfs_load="YES"' >> /mnt/boot/loader.conf
# echo 'vfs.root.mountfrom="zfs:zroot"' >> /mnt/boot/loader.conf
# zfs unmount -a
# zpool export zroot
# zpool import -o cachefile=/tmp/zpool.cache -o altroot=/mnt zroot

# zfs set mountpoint=/ zroot
# cp /tmp/zpool.cache /mnt/boot/zfs/
# zfs unmount -a
# zpool set bootfs=zroot zroot
# zpool set cachefile='' zroot
# zfs set mountpoint=legacy zroot
# zfs set mountpoint=/tmp zroot/tmp
# zfs set mountpoint=/usr zroot/usr
# zfs set mountpoint=/var zroot/var
# zfs set mountpoint=/home zroot/home

最後のmountpointを設定するところはエラーが出るけど無視する。

6. 再起動してswapファイルを作る

無事再起動したらrootでログインしてswapファイルを作る。

# dd if=/dev/zero of=/swapfile bs=1m count=4096
# chmod 600 /swapfile
# echo 'swapfile="/swapfile"' >> /etc/rc.conf
# /etc/rc.d/addswap start

これで4GBのスワップ領域が有効になる。topコマンドあたりで確認可能。

IPv6の設定 (FreeBSD)

投稿日: Leave a comment

今朝、tobyにログインしてifconfigしたらem0にIPv6の一時アドレスがついていないことに気づいて、いろいろ調べた。

/etc/network.subrを見るとnetwork6_interface_setup()の定義のところで、

       if [ ${rtsol_available} = yes -a -n "${rtsol_interfaces}" ]; then
                # Act as endhost - automatically configured.
                # You can configure only single interface, as
                # specification assumes that autoconfigured host has
                # single interface only.
                sysctl net.inet6.ip6.accept_rtadv=1
                set ${rtsol_interfaces}
                ifconfig $1 up
                if ! checkyesno rtsold_enable; then
                        rtsol ${rtsol_flags} $1
                fi
        fi

とあるので、rtsol_available=yesになるインターフェースじゃないとaccept_rtadv=1にならないらしい。では、どうしたらrtsol_available=yesになるのかさかのぼってみてみると、rtsol_availableを触るのは3か所。

1か所目

        case ${ipv6_gateway_enable} in
        [Yy][Ee][Ss])
                rtsol_available=no
                ;;
        *)
                rtsol_available=yes
                ;;
        esac

ここは、ipv6_gateway_enable=noにしているので、rtsol_available=yesになっているはず。

2か所目

                prefix=`get_if_var $i ipv6_prefix_IF`
                if [ -n "${prefix}" ]; then
                        rtsol_available=no
                        rtsol_interface=no
                        laddr=`network6_getladdr $i`
                        hostid=`expr "${laddr}" : 'fe80::\(.*\)%\(.*\)'`

ここは実行してみたけど、prefixは空文字列になっていて、test -n はFalseになって、rtsol_available=yesは維持。

3か所目

               ipv6_ifconfig=`get_if_var $i ipv6_ifconfig_IF`
                if [ -n "${ipv6_ifconfig}" ]; then
                        rtsol_available=no
                        rtsol_interface=no
                        ifconfig $i inet6 ${ipv6_ifconfig} alias
                fi

ここはアドレスがついてしまっている。なので test -nがTrueになって、rtsol_available=noになってしまっている模様。

ん?と思って、rc.confを見たら、サーバ待ち受けようにipv6アドレスを付ける設定のaliasを消してしまって、メインのアドレスとして設定する状態になってしまっていたようで、これが怪しそうなので、aliasになるように変更してリブートしてみた。

するとちゃんと一時アドレスがついて、デフォルトルートもちゃんとつくようになった。めでたしめでたし。

というか、rc.confの ipv6_ifconfig_em0 と ipv6_ifconfig_em0_alias0 の違いがやっとわかった。

 

test-ipv6.com

投稿日: Leave a comment

いつも9/10で1項目Failが出るので調べてみたら、ds.v6ns.test-ipv6.comのAAAAがIPv6のDNSサーバでしか問い合わせできないようになってして、それが出来ていなかったのでFAILになっていた。

RTX810のDNSプロキシへはipv6で問い合わせているので、RTX810がIPv4でDNS問い合わせしているっぽい感じなので調べてみたら、ずばりdns server selectコマンドで問い合わせ順序を指定できるらしく、今の設定はipv4(pp1)の優先順位が上になっていた。

dns server select 100003 pp 3 any v4flets-east.jp restrict pp 3
dns server select 500001 pp 1 any . restrict pp 1
dns server select 500002 pp 2 any . restrict pp 2

というわけで、IPv4(pp1)の500001より上になるよう、IPv6(pp2)の順位を500002から200002に変更して、

dns server select 100003 pp 3 any v4flets-east.jp restrict pp 3
dns server select 200002 pp 2 any . restrict pp 2
dns server select 500001 pp 1 any . restrict pp 1

としたら 10/10 OKになった。

めでたしめでたし。

ちなみに、フレッツのPPPoEセッション数が2までなので、設定に書いてあるpp3は使用しておらず。v4とv6で2個消費するんだから、フレッツネクストは3個くらいまで対応してくれてもいいのになぁ。