明日にはでっかい太陽が昇るかもしれません。

「覚悟」とは!! 暗闇の荒野に!!進むべき道を切り開く事だッ!

ぼくのかんがえたさいきょうかいはつかんきょう

どういうこと?

VMWare Player が 5.0 になったときに、ライセンスの解釈が変わったとかどうとかで、仕事の開発環境として VMWare Player が利用できなくなったとかいう話がありました。(結論どうでしたっけ??)

それからしばらくして、開発が停滞していた(と思われていた) VirtualBox も 5.0 がリリースされ、メンテナンスリリースもされるなど、活発な開発が行われているように見えることから、個人的な Linux 開発環境についても見直しを行ってみるか!という気分になりました。

期待する環境

MUST

  1. パフォーマンスが良いこと
  2. 業務用と個人用で共通化したい

SHOULD

  1. バックグラウンド実行したい(サービス化でも良い)
  2. HDDイメージは圧縮可能であること(肥大化後のシュリンク

MAYBE

  1. VT on VT ができること

なんか、他にもあった気がしましたが、思い出したら追記します。。。

ともかく、いろいろ考えた結果、 VirtualBox にすることにしました。

やはり、 VMWare だとライセンスの解釈で業務では使えない可能性があるのがネックでした。

上記の期待を VMWareVirtualBox に当てはめると、以下のようになりました。

項目 比較 備考
パフォーマンス VMWareVirtualBox 世間的な評価だけだが、体感的な差はない!?
業務利用 VMWare << VirtualBox ライセンス的には VirtualBox は安心。
バックグラウンド実行 VMWareVirtualBox VMWare も外部アプリでサービス化できるが、標準対応している VirtualBox にはかなわない。
HDDイメージ圧縮 VMWareVirtualBox VMWare Player は標準では圧縮ツールが付属されないらしい。。。
VT on VT VMWareVirtualBox VirtualBox は随分前からチケットがあるけど対応されていない。。。

そもそも、 Linux をメインにすればいいんじゃね!?という発送もあるのですが、お家では Windows がプリインストールしかないので、試すことができないのです。。。

インストールしたいツール

とりあえず、開発環境として以下のツールは導入したい。

目的 ツール 備考
サーバのコンテナ化 Docker トライ済み
プロジェクト管理 OpenProject 今までは Trac を長年使用
バージョン管理 git 業務で長年使用
コードホスティング kallithea トライ済み
CI Jenkins トライ済み
モダンなビルド環境 cmake トライ済み
モダンなコンパイル環境 llvm+clang トライ済み
レガシィコンパイル環境 gcc 業務で長年使用
静的解析 cppcheck 検討中
ユニットテスト CppUTest トライ済み
コードドキュメンテーション Doxygen トライ済み
ドキュメントジェネレータ pandoc Markdown -> reStructuredText or Word
ドキュメントジェネレータ sphinx reStructuredText -> Html or PDF
ドキュメント解析 RedPen 検討中

ドキュメント(技術文書)については、編集の容易さ、差分確認やドキュメント解析(をやりたい)の観点から、軽量マークアップ言語からの変換で納品に耐えられるフォーマット(想定は Word)にたどり着くように試してみたい。 (先人の記事などで、後工程でのトラブルは発生することをある程度覚悟しているが、やはり試したい)

現状は Markdowns (flavored github) を検討しているが、 AsciiDoc も気になる。。。

ただし、 AsciiDoc は pandoc での変換入力に対応していないので、 AsciiDoc → DocBook → reStructuredText のように変換が増えるので、どのような感じになるか試す必要がある。

少しでも、業務にフィードバックできれば、残業時間の完全コントロールも夢じゃない!かも!?

いまさらUML勉強中

部屋の本棚に技術書が収まらなくなってきたので、手放す本を検討中。

とりあえず、10年もののUMLの学習書を手放そうと思ったけど、よくよく考えたらほとんど読んでいないことに気付く(笑)

UMLの思想は別に嫌いじゃないし、今ならきちんと活用できそうな気がするので、リトライ中。

とりあえず、

は新たな発見。

プロのプログラマとは?

プロのプログラマとは? - プログラマが知るべき97のこと

リンクにあるエッセイの中では、著者の「プロのプログラマとは?」という問いの答えが書かれているが、かなり同意。

とくに、「キャリアに責任を持つ」という内容では、自分の成長は自分で責任を持つということが書かれていて、若手に限らず、中堅(という年代)でも足りない人がうちの会社には多い。

休日などに技術的な勉強をすることを薦める(風潮から指示できないw)のは、「ブラックだ!」みたいなことを叫ぶ人がいるが、まさに「自分のキャリアに責任を持っていない」人たちだと思う。

プログラマは創造的な職業で、常に最先端を追い求めていないと「過去の人」にすぐになってしまうのに、会社の就業時間内でしか技術に接したくないという。

医者、弁護士はいうに及ばす、画家や音楽家、料理人、美容師など、創造的な仕事では、仕事が終わってから勉強を重ねて、ようやく一人前になれるというのに、、、技術が嫌いなら仕事変えれば?と思ってしまう。


最近知った、将棋棋士佐藤康光九段が過去のインタビューで、

「休み?休みなんか要るんですか。だって勉強は労働じゃないでしょう」

ということを話したらしいけど、この言葉には衝撃が走った!!

確かに、勉強は自分のためで、だからこそ自分の成長につながるわけだけれども、どこか労働と同じように考えてしまっていた自分がいたから。

「勉強」というものの考え方一つでも、トップランナーとの差を見せつけられたと思いました。

clang de coverage!

llvmでのカバレッジ計測ができない。。。

*.gcda*.gcno の作成まではできてるんだけど、 gcovr で生成しても空になるし、 llvm-cov は使い方が何やら合ってない様子。。。

というより、 llvm-cov の情報少なすぎ!!

もう少し調べるけど、もしかして llvm-cov のコード読んだほうが早い!?


追記

*.gcda のバイナリフォーマットを確認したら、gcc で生成したものと llvm で生成したものがぜんぜん違うっ!!?

うーん、、、個人的には調査したいけど、仕事にも流用することを考えると、clang は時期尚早ということで、 gcc の開発環境をもっと詰めていくか。

clang でカバレッジ計測

clang+llvm と CppUTest を使って、組み込み向けのUT環境をつくろうとしているが、カバレッジ計測を行う場合は、CppUTestも clang+llvmコンパイルしておかないと、リンクできなくなる!?

  • CppUTest → gcov をリンクしようとする
  • テストコード → clang_rt.profile-xxx をリンクしようとする

という状況になる模様。

CppUTestの組み込み機能を利用せずにカバレッジ計測を行えばいいのかもしれないけど。。。

まずは CppUTest の使い方を勉強しているので clang+llvm は諦めるかな。

ほとんどのライブラリでは影響が無いのだろうけど、こういったコンパイラのミスマッチによるリンクエラーが出る可能性があるということは clang+llvm を利用する上では意識する必要がありそう。


  • gcov のみリンクした場合
/path/to/source/xxxx.c:(.text+0x232): `llvm_gcda_start_file' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x258): `llvm_gcda_emit_function' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x26c): `llvm_gcda_emit_arcs' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x28d): `llvm_gcda_emit_function' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x2a1): `llvm_gcda_emit_arcs' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x2c2): `llvm_gcda_emit_function' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x2d6): `llvm_gcda_emit_arcs' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x2f7): `llvm_gcda_emit_function' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x30b): `llvm_gcda_emit_arcs' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x310): `llvm_gcda_summary_info' に対する定義されていない参照です
/path/to/source/xxxx.c:(.text+0x315): `llvm_gcda_end_file' に対する定義されていない参照です
  • clang_rt.profile-x86_64 と gcov をリンクした場合
/opt/toolchains/clang+llvm/lib/clang/3.7.0/lib/linux/libclang_rt.profile-x86_64.a(GCDAProfiling.c.o): 関数 `__gcov_flush' 内:
GCDAProfiling.c:(.text.__gcov_flush+0x0): `__gcov_flush' が重複して定義されています
/usr/lib/gcc/x86_64-linux-gnu/4.8/libgcov.a(_gcov.o):(.text+0x20d0): ここで最初に定義されています
clang-3.7: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [tests/console_test] エラー 1
make[1]: *** [tests/CMakeFiles/console_test.dir/all] エラー 2
make: *** [all] エラー 2
  • clang_rt.profile-x86_64 のみリンクした場合
/opt/toolchains/cpputest/lib/libCppUTest.a(MemoryLeakWarningPlugin.cpp.o): 関数 `_GLOBAL__sub_I_65535_0__Z44cpputest_malloc_location_with_le
ak_detectionmPKci' 内:
/home/workbench/public/workspace/cpputest-3.6/include/CppUTest/TestFailure.h:113: `__gcov_init' に対する定義されていない参照です
/opt/toolchains/cpputest/lib/libCppUTest.a(MemoryLeakWarningPlugin.cpp.o):(.data+0xc0): `__gcov_merge_add' に対する定義されていない参照です
/opt/toolchains/cpputest/lib/libCppUTest.a(CommandLineTestRunner.cpp.o): 関数 `_GLOBAL__sub_I_65535_0__ZN21CommandLineTestRunnerC2EiPPKcP10T
estOutputP12TestRegistry' 内:
...

cmake 使ってみた

しばらくおいたままになっていたけど、 cmake を使ってみました。

とりあえず、プロジェクト構成は以下のようにしました。

cmake_sample/
 + product/
 |  + main.c
 |  + CMakeLists.txt
 + test/
 |  + main1_test.cpp
 |  + main2_test.cpp
 |  + CMakeLists.txt
 + CMakeLists.txt

実行モジュールのコードは product/ ディレクトリに配置し、テストコードを test/ に配置しました。

  • cmake_sample/CMakeLists.txt
# 使用する cmake のバージョン.
cmake_minimum_required(VERSION 3.1)

# プロジェクト名.
project(embryoshell)

# バージョン番号.
set(MAJOR_VERSION "0")
set(MINOR_VERSION "0")
set(BUILD_VERSION "0")
set(SERIAL "${MAJOR_VERSION}.${MINOR_VERSION}.${BUILD_VERSION}")

# テストを有効にする.
enable_testing()

# プロダクトコードディレクトリ.
add_subdirectory(product)

# テストコードディレクトリ.
add_subdirectory(test)
add_test(test01 test/test01_test)
add_test(test02 test/test02_test)
  • cmake_sample/product/CMakeLists.txt
# 使用する cmake のバージョン.
cmake_minimum_required(VERSION 3.1)

# プロジェクト名.
project(cmake sample)

# ソースファイル.
file(GLOB SOURCES *.c)

# リリースビルドでのコンパイルオプション.
set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -Wextra -O2")

# デバッグビルドでのコンパイルオプション.
set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror -Wextra -g -pg -O0")

# 実行モジュールの作成を指示.
add_executable(sample ${SOURCES})

# リンクするライブラリを指定する.
target_link_libraries(sample
        edit
        ncurses
)
  • cmake_sample/test/CMakeLists.txt
# 使用する cmake のバージョン.
cmake_minimum_required(VERSION 3.1)

# プロジェクト名.
project(embryoshell)

# リリースビルドでのコンパイルオプション.
set(CMAKE_C_FLAGS_RELEASE "-Wall -Werror -Wextra -O2")

# デバッグビルドでのコンパイルオプション.
set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror -Wextra -g -pg -O0")

# 実行モジュールの作成を指示.
add_executable(test01_test test01_test.cpp)
add_executable(test02_test test02_test.cpp)

これで、テストを googletest や cpputest を使って実施できれば、モダンな環境に近づくかな?

プログラマが知るべき97のこと > 見られて恥ずかしいデータは使わないこと

見られて恥ずかしいデータは使わないこと - プログラマが知るべき97のこと では、一時的と思って適当な(社会的には不適当な)データを成果物に埋め込んじゃうことが書かれています。

ここまで大事になったことは無いけど、一時的と思ってたコードが残ったままになっているコードはよく見かけます。

#warning とりあえず失敗させるけど、これでよい?

とか、入った製品コード。。。コンパイルのたびに表示されるけど、他社部分のレガシーコードだから、だれも触らない。

こういった、誰が見ても問題になりそうなパターンは別として、コーディング中は(特に調子が良い時は)ハイになっているので、あとから見返すと「こっちのほうが良かったな」というような実装を選択していると思う。

こういったコードは、レビューなどで検出することになると思うけど(動作上は問題ないので静的解析でも指摘されない)、レビューまで検出が遅くなると、コードを修正することが難しくなることも多い。(デバッグ後とかだと、構造は変えたくなくなるので)

ペアプログラミングが検出のタイミングとしては一番良いと思うけど、うちの会社では導入できなさそう。

あとは、自分で検出できるように、一区切り書ききったタイミングでセルフレビューすることを習慣にするしか無いのかな?何か、ツールなどあれば良いのだけど。


プログラマが知るべき97のこと