2016年1月26日火曜日

[Doxygen] 必ずインクルード的なことをしてみた

Doxygen で必ずインクルード的なオプションってないの?

ないっぽい。

ので、回避策。

INPUT_FILTER を使う
Doxygen のオプションに INPUT_FILTER というものがあり、これを利用して実現しました。

Doxygen 設定
INPUT_FILTER タグでは、各入力ファイルをフィルタリングするのに使うプログラムを指定します。doxygen は、フィルタープログラムを起動するために、次のコマンドを (popen() を介して) 実行します。

<filter> <input-file>
ここで、<filter> は、INPUT_FILTER タグの値です。 また、<input-file> は、入力ファイルの名前です。 doxygen は、その後、フィルタープログラムが標準出力に書き出した出力を使用します。

今回用意したフィルタープログラムは python で以下のように書きました。
import sys

def main():
    f = open(sys.argv[1])
    n = 0
    if f:
        for line in f:
            sys.stdout.write(line)
            if line.find("//=========================================================") != -1:
                n += 1;
                if n == 2:
                    print('#include "iutest_config.hpp"')
    f.close()

if __name__ == '__main__':
    main()

ファイルの先頭にある Doxygen コメントの直後に「必ずインクルードしたいファイル」のインクルードディレクティブを挿入しているだけです。
先頭のコメントを読み飛ばす方法は、もっと汎用性あるやり方にもできますが、今回は iutest でのみ使えればよかったので簡単に済ませました。


必ずインクルードができたことで…
iutest では iutest.hpp ヘッダーファイルをインクルードして使うことを想定しています。
そのため、#include も端折れるところは端折ってます。
なので、include/*.hpp の別のファイルを"それだけで"インクルードしても、#include が足らずに使えなかったりします。

Doxygen はファイル個別に評価されるため、同様に #include が足りない状態で解析がされてしまいます。
そうするとマクロ定義がなかったりして、#if/#endif ブロックが有効にならずにドキュメント化されない、というのが問題になってました。
今回、「必ずインクルード」ができるようになったことで、このようなファイルの解析が期待通りにできるようになりました。


設定ファイルで指定できたら一番いいんですけどね。
今回は以上。

2016年1月19日火曜日

「Effective Modern C++読書会 vol.3」に行ってきた

Effective Modern C++読書会 vol.3」に行ってきました。



読書会、前々から行きたいな~と思っていたものの行けてなかったですが、
本も新しくなったし、今年こそは!ということで行ってきました。

知らなかったこととかがさらっと出てきたりして、非常に勉強になりました。
あとラムダのサイズで警告云々の話は、見返してみたらちょっと勘違いしてました。
ラムダから関数オブジェクトを返してて、警告されてたのはそれでした。
ただ、ラムダがそれぞれサイズが異なるというのは今まで意識したことがなかったので、新鮮でした。
[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ http://melpon.org/wandbox/permlink/W1fPrqECoaRu8hG0


また余裕があるときには参加したいです。

2016年1月18日月曜日

無料で使える CI サービス比較

完全に個人的な備忘録です。
こちらは 2015年11月 に調べた情報をもとに書いています。
間違いや古い情報が含まれている可能性があります。
承知のうえで見てください。


2016/9/3 追記:

CircleCI now supports Bitbucket
Circle CI が Bitbucket に対応しました。他のサービスも更新されていることが予想されます。
本家ページで最新の情報をご確認ください。



はじめに
最近 CI ネタをよく投稿していましたので、このへんで iutest のテスト用に使っている(使おうと思っている)CI サービスの比較をまとめてみました。


参考にしたところ:

はじめに
今回比較するサービスは以下の10個。(アルファベット順)
AppVeyorCircle CICodeshipDrone.ioMagnum CIsemaphoreShippableSnap CITravis-CIWercker
サポート言語
まずはサポート言語を比較します。

AppVeyorCircle CICodeshipdrone.ioMagnum CIsemaphoreShippableSnap CITravis CIWercker
サポート言語 - Ruby
/Rails
Python
Node.js
PHP
Java
Haskell
Scala
Dart
Go
Java
JVM※1
Node.js
PHP
Python
Ruby
C/C++
Dart
Go
Haskell
Groovy
Java
Node.js
PHP
Python
Ruby
Scala
Ruby
Node.js
Go
PHP
C/C++
Clojure
Elixir
Erlang
Go
Java
JavaScript
PHP
Python
Ruby
Scala
Clojure
Go
Java
Node.js
PHP
Python
Ruby
Scala
Ruby
/JRuby
Python
Node.js
/io.js
PHP
Java
Groovy
/Gradle
Scala
/SBT
Clojure
/Leiningen
C/C++
Android
C/C++
Clojure
C#
D
Dart
Erlang
F#
Go
Groovy
Haskell
Haxe
Java
JavaScript※2
Julia
Objective-C
Perl
PHP
Python
R
Ruby
Rust
Scala
Smalltalk
Visual Basic
Golang
Node.js
Python
Ruby
g++4.8.1※34.6.44.8.44.6.34.6.34.8.44.6.34.4.74.6.34.6.3
clang++-3.0-3.0--3.0-3.4-
※1:JVM based languages
※2:JavaScript(with Node.js)
※3:MinGW

こちらはあくまでも公式がサポートしていると謳っている言語で、どこまで何ができるかはそれぞれ違うので注意。
また、ここに載っていない言語でも基本的には環境をセットアップする処理を書けば、CI 可能だと思います。

自分の場合 C++ で書かれたプログラムの CI で利用しているので、素もしくは C++ 環境で実行したときにインストールされている g++ と clang++ のバージョンを載せておきます。

リポジトリホスティングサービス連携
AppVeyorCircle CICodeshipdrone.ioMagnum CIsemaphoreShippableSnap CITravis CIWercker
Github
Bitbucket×××
その他
  • VS Online
  • Kiln
  • GitHub Enterprise
  • Stash
  • Google Code
  • GitLab
  • Beanstalk
  • GitLab
    ※1
Github PR 対応×
private リポジトリ×5×××
Self Hosted
Git×××※1××××
Mercurial××××××××
Subversion××××××××
※1: GitLab and self-hosted git repositories is coming soon.

次はリポジトリホスティングサービス連携です。
Github はどのサービスも対応しています。Bitbucket は対応していないサービスが少しあります。
Github PR 対応は、pull request に対しての CI が実行されるかどうかです。
(drone.io は頑張ればできるらしい。)

Self Hosted は Github や Bitbucket などのホスティングサービス以外に、自前のサーバーなどに立てた Git リポジトリなどを使用できるかどうかです。
これに対応しているところはほとんどありませんでした。(調べきれてないだけで使えるかもしれないが…)

プロジェクト設定/ビルド関係

AppVeyorCircle CICodeshipdrone.ioMagnum CIsemaphoreShippableSnap CITravis CIWercker
YAML 設定××××
WebUI 設定×××
Branch Filter××
手動リビルド※1※1
複数環境ビルド※2××××××
private ビルド※3×100/月××
時間制限60分120分180分15分30分60分120分120分120分25分
時間制限(無出力)60分10分10分15分30分60分120分15分10分5分
※1: 最新コミットのみ
※2: コンテナを複数使うことで可能。ブログズミ: Circle CI 始めました
※3: Free and Open Source 設定だと使えない。

次は設定やビルド環境です。
CI サービスのほとんどが、YAML か WebUI で設定をします。目的に合わせて、お好きな方を選んでください。

Branch Filter は任意のブランチを CI 対象 or 除外できるかどうかという点で○×を付けてますが、それぞれサービスごとにできることが違うので注意。どういう形式なのかドキュメントで確認してください。

private ビルドはビルド結果などが他者から見えないようにできるかどうかです。

最後は時間制限です。時間制限はサービスごとに大きく差が出る結果になりました。
また、ログが一定時間出力されないとタイムアウトするサービスもあります。
先週のブログ「Snap CI 始めました」にも書きましたが、Snap CI はステージごとの時間制限なので複数ステージにすることで、より長く使うことができるので、この点においては最強です。

Notifications
AppVeyorCircle CICodeshipdrone.ioMagnum CIsemaphoreShippableSnap CITravis CIWercker
Badge
E-mail
Github commit status××
WebHook×※1
Campfire××※1
Flowdock××××※1
Grove××××××××※1
HipChat×
Pushover××××××××※1
Sqwiggle××××××××※1
Slack×
IRC×××××※1
VSO Team Room××××××××※1
CCTray××××××××
Chrome Extension×××××××××
※1: Custom step を使うことで可能 (https://app.wercker.com/#explore/steps/search/notify)

最後は通知。バッジやメールはどこでもあります。
Github commit status は CI 結果をコミットステータスとして送る機能です。
pull request のコミットにこんな感じにつきます。


他の通知として、それぞれチャットなどに対応しています。
たいていの CI サービスが WebHook が使えるので、対応していない通知でもちょっと頑張れば対応できます。
(試してはないです。)

まとめ
今回紹介した CI サービスは(semaphore 以外)すべて利用しています。それぞれ別の目的(テストや検証)のために使っているのでどれも必要ではありあすが、強いてオススメをあげるとしたら Travis CI、AppVeyor、Shanp CI でしょうか。
Travis CI はかなり有名ですので言うまでもないかなと、
AppVeyor は Windows での貴重な CI 環境ですので、欠かせません。最近、知名度が上がっているようにも感じてます。Windows 環境の CI だと Visual Studio Team Service (Visual Studio Online) もありますが、無料枠だと時間制限がキツイのと、しばらくログインしていないとビルドを実行してくれないのがメンドクサイです。
Snap CI は最近使い始めたばかりですが、便利に使えそうな印象でした。

Shippable や Wercker も便利で iutest の CI 環境としては欠かせないのですが、
(iutest では python で wandbox api を叩いて、gcc/clang の各種バージョン対応のチェックをしている。)
C++ の CI 環境としては言語サポートされていない点もあり、少し手間かなと思います。

最後に
今回は自分が使っているものを自分目線でまとめました。なので、間違ってる部分もあると思いますし、デプロイや Docker 関係など触れていない部分もあります。
もし、こちらの記事を参考にされて CI サービスを始める時は、求める機能や条件が整っているか改めて公式ドキュメントなどを確認してください。

また、間違いなどありましたらドシドシ指摘していただけると助かります。
以上。