2016年10月20日木曜日

opencv2系をgcc6でコンパイルしたらエラーになった

opencv2.4.13をubuntu16.10環境(gcc6)でコンパイルしたらこんなエラーが出て止まった。
In file included from /usr/include/c++/6/bits/stl_algo.h:59:0,
                 from /usr/include/c++/6/algorithm:62,
                 from /opencv-3.1.0/modules/core/include/opencv2/core/base.hpp:53,
                 from /opencv-3.1.0/modules/core/include/opencv2/core.hpp:54,
                 from /opencv-3.1.0/modules/core/include/opencv2/core/utility.hpp:52,
                 from /opencv-3.1.0/build/modules/core/precomp.hpp:49:
/usr/include/c++/6/cstdlib:75:25: fatal error: stdlib.h: そのようなファイルやディレクトリはありません
 #include_next <stdlib.h>
{stdlib.hがありませんって、そんなわけねーだろ!}
一瞬、あせったけど、cmakeで
-D ENABLE_PRECOMPILED_HEADERS=OFF
付けとけば、とりあえずOKっぽい。
opencvの方がおいおいgcc6対応すると思うけど、今のところこれで切り抜けられそうです。

2016年10月6日木曜日

docker buildしたときに、Dockerfileがシンボリックリンクだと失敗する。

タイトルのまんまなんだけど、docker buildしたときに、Dockerfileがシンボリックリンクだと失敗する。こんなエラーね。
% docker build -t image-name:tag-name .

unable to prepare context: The Dockerfile () must be within the build context (.)
そんなときは、リダイレクトでぶち込むととりあえず動きます。
% docker build -t image-name:tag-name - < Dockerfile
pathのところがハイフンになっている所に注意です。

追記
しかし、上の方法だとADDやCOPYでのファイルのコピーができません。
{ムキーッ。動かないし、あわてて上のエントリだしちまって、アホ丸出しだぜ。}
でこんなふうにやってみた。
# -f で相対パス指定 -> ダメ
%  docker build -t image-name:tag-name -f ../another-dir/Dockerfile .
unable to prepare context: The Dockerfile ({.の絶対パス/Dockerfile}) must be within the build context (.)

# -f で絶対パス指定 -> ダメ
%  docker build -t image-name:tag-name -f /xxx/another-dir/Dockerfile .
unable to prepare context: The Dockerfile ({.の絶対パス/Dockerfile}) must be within the build context (.)

# zsh使ってるのでプロセス置換 -> ダメ
% docker build -t image-name:tag-name -f <(cat Dockerfile) .
unable to prepare context: unable to evaluate symlinks in Dockerfile path: lstat /proc/29179/fd/pipe:[1290842]: no such file or directory   
{う~む。かなり、頑固だなあ。}
dockerは、どうしてもcontext dirにDockerfileの実体がないと動いてくれないらしい。
しかたないので、簡単な build.shを↓のように書いてみた。
#!/bin/bash

if [ $# -ne 1 ]; then
  echo "usage: build.sh tag_name" 1>&2
  exit 1
fi

rsync symlinkしてたDir/Dockerfile Dockerfile
docker build -t image-name:$1 .
動いたよ。

しかし、ここでもしやと思い、build context dirの外を向いているsymlinkをDockerfileのCOPYで、コピーしようとしてみたら、こんなエラーが
lstat symlinkの名前: no such file or directory
{docker buildは、徹底的にsymlinkが嫌いなようだ。今回は敗北感が大きいな・・・}
とにかく、dockerさんは、dockerfileやCOPYしたいファイルの「実体」があるところでbuildしてくださいといいたいのだろう。

そして、dockerfileの変更はsymlinkで同期させるのでなく、build可能な、contextディレクトリをgit等で管理するのが作法だぞということなのかもしれない。

仕方ない、従いますよdockerさん。ここまで、読んでくれた方、もしいらしたらごめんなさい。dockerfileをsymlinkにするのはやめたほうがいいと思います。