2014年9月30日火曜日

2014年9月28日日曜日

クロスプラットフォームなC/C++ IDE CLion を使ってみた

標題通り Windows,Linux,Mac で使えるC/C++のIDE CLionをMac OS X (10.9)で使ってみた。
現在のところβ版扱いで60日間に限り無料で使える。

以下CLionのスクリーンショット。


特徴としては、以下2点が挙げられる。
・コンパイル関係の設定をCMakeList.txtに書いていく
・Vim Emulator

試しにOpenCVを使ってMBAのiSightのキャプチャをしてみた。OpenCVはVer.2.4.9をソースからコンパイルして/opt/OpenCV/2.4.9配下にインストールしたものを利用する。
以下main.cpp
#include <iostream>#include "opencv2/objdetect/objdetect.hpp"#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"
using namespace std;using namespace cv;

int main() {
    CvCapture *capture;    Mat frame, frameCopy, image;
     capture = cvCaptureFromCAMCV_CAP_ANY;()
    if(capture== NULL){
        cout << "Failed to open camera" <<endl;
        return -1;    }

    cvNamedWindow("Result", CV_WINDOW_AUTOSIZE);    cout << "Captureing... " << endl;
    while (1) {
        IplImage *iplImage = cvQueryFrame(capture);        frame = iplImage;        if (frame.empty()) break;        if (iplImage->origin == IPL_ORIGIN_TL) {
            frame.copyTo(frameCopy);        } else {
            flip(frame, frameCopy, 0);        }
        cvShowImage("result", iplImage);        if (waitKey(10) >= 0) break;    }

    cvReleaseCapture(&capture);    cvDestroyWindow("Result");    return 0;}
そして、以下がCMakeList.txt
cmake_minimum_required(VERSION 2.8.4)
project(helloCLion)

set(SOURCE_FILES main.cpp)
add_executable(helloCLion ${SOURCE_FILES})

set(OPENCV_PREFIX_PATH /opt/OpenCV/2.4.9)
set(OpenCV_LIBS opencv_core opencv_imgproc opencv_highgui)
FIND_PACKAGE(OpenCV REQUIRED)
INCLUDE_DIRECTORIES(${OPENCV_PREFIX_PATH}/include)
LINK_DIRECTORIES(${OPENCV_PREFIX_PATH}/lib)
TARGET_LINK_LIBRARIES(helloCLion ${OpenCV_LIBS})
7行目以降がOpenCV関係の設定

問題は、デバッグしようとするとコンソールに下記が出力されデバッグできない。
/Users/hayato/Library/Caches/clion10/cmake/generated/6982c880/6982c880/Debug/helloCLion
During startup program exited with code 1.

Process finished with exit code 0

CLionはデバッガとして同梱の(/Applications/CLion EAP.app/Contents/bin/gdb/bin/gdb)を使っているらしく、このgdbにコード証明書があたっていないのが原因かと考えコード証明書をあててみたが現象は改善せず。

2014年8月17日日曜日

Windows の共有ライブラリロード時のサーチパスの優先順位

Linux の場合LD_LIBRARY_PATHに依るけどWindowsの場合は、
[1] アプリケーションがロードされたディレクトリ
[2] System directory
[3] 16bit system directory
[4] Windows directory
[5] カレントディレクトリ
[6] 環境変数PATH

の順らしいです。ということで検証してみた。今回は、検証用の自分自身が配置されている場所を返すプロシージャを含む"studyTest.dll"とそれを用いるコードを書いて確認してみた。

dllを使用する側のプロセス生成時のカレントディレクトリを起点としたディレクトリとファイルツリーは、下記のようになっている。

.\
├─bin
│      studyTest.dll
│      useDll.exe
│    
├─lib
│      studyTest.dll
│    
└─sub
        studyTest.dll

[コマンドプロンプトにおける実行履歴]
set PATH=%CD%\lib;%PATH%
> .\bin\useDLL.exe


"call_Proc"ボタンを押下。

>move .\bin\studyTest.dll .\bin\studyTest_A.dll
"call_Proc"ボタンを押下。

>move C:\Windows\SysWOW64\studyTest.dll C:\Windows\SysWOW64\studyTest_A.dll
"call_Proc"ボタンを押下。

>move C:\Windows\studyTest.dll C:\Windows\studyTest_A.dll
"call_Proc"ボタンを押下。

>move .\sub\studyTest.dll .\sub\studyTest_A.dll
"call_Proc"ボタンを押下。




2014年7月29日火曜日

PLEX Multimedia Server の構築 on FreeBSD 9.1 STABLE

PLEX Multimedia Server を構築する。なお、FreeBSDは、サポートはされていないので自己責任で。。。

[1] ローカルからのアクセスまで

ports にてサーバーソフトウェアをインストールする。

cd /usr/ports/multimedia/plexmediaserver
make config-recursive
make
make install

起動時にデーモンが起動するように/etc/rc.confに下記を追記

plexmediaserver_enable="YES"

サーバーの起動
/usr/local/etc/rc.d/plexmediaserver start

ブラウザにて 下記アドレスにアクセス

http://[server-address]:32400/manage

下記のようなページが表示されればここまではOK


[2] 外からのアクセス
(1) ルーターの設定
PLEX Multimedia Serverは、TCPの32400番ポートを使うのでルーターの外からサーバーの32400番ポート宛のパケットを通すようにルーターのファイヤーウォールの設定を変更しておく。
 また、NATを使っている場合は、ルーターの外側のIPアドレスの32400番ポートへの接続要求をサーバーの32400番ポートへ転送するように静的NATのエントリを追加しておく。 参考

(2) PLEXの設定
次に、https://plex.tv/ にアクセスしてplexのアカウントを作成。

"[1] ローカルからのアクセスまで"にてアクセスしたローカルに建てたサーバーのページの右上のサインインをクリックして作成したアカウントでログインする。サインインできたら右上の歯車の設定アイコンをクリックして、同アイコンより下に表示される"Server"をクリック。
Friendry name がホスト名になっている場合は、FQDNに変更しておく。


さらに、右側の"Connect"をクリックして、"Manually specify port"にチェック、テキストボックス"32400"が入力されていることを確認して、"Retry"ボタンを押下。下記画像のように2つのチェックが付けばOK。



実際に外からアクセスできるかどうか試してみる。




2014年7月17日木曜日

Mercurial reporitory server

[0] Ubuntu 14.04 のインストール + sshログインの準備

2019年までサポートされる140.04のイメージををダウンロードする。
ダウンロードしたイメージでインストール。スキップできるところはスキップして後からリポジトリサーバーを変更しインストール。

公開鍵を利用してsshでリポジトリサーバーにログインできるようにしておく。クライアント側にて公開鍵を生成(Unixライクな環境では ssh-keygen、Windows ならPuTTYgen等を用いて)。公開鍵をサーバーの~/.ssh/authorized_keys に追記する。

[1] Mercurial のインストール

sudo apt-get install mercurial

試しに使ってみる
ユーザー名の設定 ~/.hgrc を作成して下記を記入。
[ui]
username = FORUM TARO <forum@foo.bar>

mkdir tmp
hg init tmp
cd tmp
touch test.c
hg add
hg commit -m 'first commit'


[2] mercurial-server のインストール

sudo apt-get install mercurial-server

[3]
こちらを参考にリポジトリのrootユーザーの公開鍵の登録とリポジトリの作成を行う

2014年7月16日水曜日

デフォルトのLANGの変更

Ubuntu でシステム全体のデフォルトのLANGの変更は、
/etc/default/locale
に対して行う。

2014年6月16日月曜日

OpenLDAP サーバー構築でハマった点

"failed to start slapd"と言われてデーモンのスタートが失敗する場合は、"slapd.conf"の構文を間違えていないかslaptest(BC) をj実行してみる。

objectClass organizationalUnit を用いる場合は、下記2つのスキーマをslapd.confでインクルードする。

/usr/local/etc/openldap/schema/cosine.schema
/usr/local/etc/openldap/schema/inetorgperson.schema


2014年6月5日木曜日

Unmask floating point exception #2

この投稿の追加投稿。

Gcc 4.4.7 にて下記の除算のみを行うソースをコンパイルして逆アセンブルすると除算は、SSE2の命令である"DIVSD" (*1 p.728)が出力されていることが確認できます。

-div.c-
#include <stdio.h>

int
main(void)
{
  double a,b,c;

  a=3.0;
  b=0.0;
  c=a/b;

  return 0;
}

$ gcc -o div div.c
$ objdump -d div > div.d

-div.d のmainの一部-
  40048f:       f2 0f 10 45 e8          movsd  -0x18(%rbp),%xmm0
  400494:       f2 0f 5e 45 f0          divsd  -0x10(%rbp),%xmm0
  400499:       f2 0f 11 45 f8          movsd  %xmm0,-0x8(%rbp)



 前回投稿したコードは、x87 FPUのFPE(Floating Point Exception)のマスクを解除するものであり、当たり前ですがSSE2のFPEを解除しているわけではないので、mainの最後でdouble同士の除算をしてもSSE2の命令が出力されているのでFPEは発生しません。

今回は、SSE2のFPEのマスクを外すコードをメモ。
 - sse2.c -
     1    #include <stdio.h>
     2   
     3    int
     4    main(void)
     5    {
     6      double a,b,c;
     7      unsigned char buff[512] __attribute__((aligned(16)));
     8   
     9      a=3.0;
    10      b=0.0;
    11      c=1.0;
    12   
    13      c = a/b;
    14   
    15      asm volatile(
    16        "fxsave %0" // get valueof mxcsr register
    17        :"=m"(buff):);
    18   
    19      printf("SSE2 FPE bit mask= %X\n", buff[25]);
    20      buff[25] = buff[25] ^ 0x2;
    21      printf("SSE2 FPE bit mask= %X\n", buff[25]);
    22   
    23      asm volatile(
    24        "fxrstor %0"  // set operand to mxcsr register
    25        : :"m"(*buff));
    26   
    27      c = a/b;
    28   
    29      return 0;
    30    }


fxsave(*1 P.846)/fxstor(*1 P.843) は、指定されたメモリ領域から/にMXCSR(*1 P.230)というSSE2の浮動小数点演算時に用いる情報を保持するレジスターに/の値を保存する。
20行目で該当するビットをクリアすることで、ゼロ割によるFPEのマスクを外している。

$ gcc --o sse2 sse2.c
$ ./sse2
SSE2 FPE bit mask= 1F
SSE2 FPE bit mask= 1D
Floating exception (core dumped)

[補足]
ちなみに、-mfpmath=387 というオプションをつけてコンパイルするとx87 FPUの除算命令を出力する。




*1 Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B, and 3C

2014年5月30日金曜日

[Windows 8.1] UEFI設定画面の確実な入り方

Windows 8.1がインストールされたPCで用があってUEFIの下記設定変更を行い。
・ディバイスの起動順の変更
・UEFIのセキュアブートの無効化
別のディバイスからブートして作業。作業終了後UEFIの設定を元にもどそうと設定画面に入るためのキーを押すが設定画面が表示されないし、Windowsも起動しない。

しょうがなく、電源ボタン長押しで電源断後、再度電源ボタンを押して暫くするとWindowsは起動した。

そんな事があったので対処法をメモ。
管理者権限のあるコマンドプロンプトで

shutdown /r /o
/r - Full shutdown and restart computer
/o - Go to the advanced options menu and restart computer. Must be used with /r option.

すると再起動後に"オプションの選択"という画面が表示されるので、トラブルシューティング]-[詳細オプション]-[UEFI ファームウェアの設定]の順にクリックする。



2014年5月22日木曜日

Unmask floating point exception


 x86 なプロセッサ上のLinuxでは、浮動小数点同士の除算でゼロ割を行ってもSIGFPEは普通発生しない。これは、FPU control word*1 というFPUのレジスタ中のFloating point exception のマスク状態を表すフラグが立っているためである。

gfortran -ffpe-trap=zero というオプションを指定すると浮動小数点のゼロ割でSIGFPEが発生するようになる。今回は、gcc インラインアセンブラでFloating point exception のマスクを解除してみた。



#include <stdio.h>

int
main(void)
{
  double a,b,c;
  unsigned short int fctr;

  a=3.0;
  b=0.0;
  c=1.0;

  asm volatile(
    "fstcw %w1\n\t" // get FPU control word
    "fdiv %3,%2"
    :"=&t"(c):"m"(fctr),"f"(a),"f"(b));
  printf("c= %f     FPU control word= %X\n", c, fctr);

  fctr = fctr ^ 0x4;
  printf("Value for FPU control word= %X\n", fctr);

  asm volatile(
    "fldcw %w1\n\t"  // set operand to FPU control word
    "fdiv %3,%2"
    :"=&t"(c):"m"(fctr),"f"(a),"f"(b));
  printf("c= %f     FPU control word= %X\n", c, fctr);

  return 0;
}


[実行結果]
$ ./a.out
c= inf     FPU control word= 37F
Value for FPU control word= 37B
Floating exception (core dumped)


*1 Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 2C, 3A, 3B, and 3C p.p.189-190