こんにちは。
表題の通り、技術書典10 で「詳解 Integromat iPaaS 完全入門」の販売を開始しました。
本書は GitHub にてコンテンツ以外を公開しております。
本書へのフィードバックはこちらへお願い致します。
https://github.com/srz-zumix/book-integromat
こんにちは。
表題の通り、技術書典10 で「詳解 Integromat iPaaS 完全入門」の販売を開始しました。
本書は GitHub にてコンテンツ以外を公開しております。
本書へのフィードバックはこちらへお願い致します。
https://github.com/srz-zumix/book-integromat
※この記事は C++ Advent Calendar 2020 22日目の記事です。
過去に本ブログでも紹介した template の明示的実体化時に private メンバーアクセス可能な仕様を利用した private メンバー変数・関数へのアクセスですが、最近それを使っていて clang だけとある条件でアクセスできないことに気づきました。
この挙動が仕様として正しいのか正しくないのかは筆者ではわからないので、実挙動ベースの話になってしまいますことをご了承ください。
過去の記事
ブログズミ: [C++] Private な関数のテスト
ブログズミ: [C++] 本当に private なところ
こちらは iutest の private メンバーのテストのための機能を使ったサンプルです。
Wandbox 用に圧縮したソースコードを使ってますので、実装を確認したい場合はこちらを御覧ください。
https://github.com/srz-zumix/iutest/blob/master/include/iutest_prod.hpp#L62
#define IUTEST_USE_MAIN #include "iutest.hpp" class A { public: int GetX(void) { return m_x; } private: int m_x; }; IUTEST_MAKE_PEEP(int A::*, A, m_x); IUTEST(Peep, Test1) { A a; IUTEST_PEEP_GET(a, A, m_x) = 42; IUTEST_EXPECT_EQ(42, a.GetX()); IUTEST_EXPECT_EQ(42, IUTEST_PEEP_GET(a, A, m_x)); } IUTEST(Peep, Test2) { A a; IUTEST_PEEP(A, m_x) x(&a); x = 54; IUTEST_EXPECT_EQ(54, a.GetX()); x += x; IUTEST_EXPECT_EQ(108, a.GetX()); IUTEST_EXPECT_EQ(108, x); }
[Wandbox]三へ( へ՞ਊ ՞)へ ハッハッ
https://wandbox.org/permlink/2ZPvpUz1zDe1KHHs
ポイントは IUTEST_MAKE_PEEP と IUTEST_PEEP_GET です。
IUTEST_MAKE_PEEP で private メンバーアクセスするための情報をセットアップし、IUTEST_PEEP_GET で実インスタンスの private メンバーへの R/W を実現しています。
class Hoge { int x; public: Hoge() : x(42) {} private: int GetX() { return x; } private: int gX() { return x; } int gX() const { return x; } int gX(int) { return x; } }; IUTEST_MAKE_PEEP(int (Hoge::*)(), Hoge, GetX); IUTEST_MAKE_PEEP(int (Hoge::*)(), Hoge, gX); int main() { Hoge hoge; std::cout << IUTEST_PEEP_GET(hoge, Hoge, GetX)() << std::endl; std::cout << IUTEST_PEEP_GET(hoge, Hoge, gX)() << std::endl; }
Clang の場合はエラー
https://wandbox.org/permlink/roGkNKKwsnaLX7og
GCC の場合は OK
https://wandbox.org/permlink/AWd5A19WWDznccfq
エラーとなるのは gX 関数の PEEP で、オーバーロードされた関数があるとダメなようです。
Visual Studio はバージョンによって static メンバー関数がダメだったりするのは認識してましたが、 clang でもうまくいかないケースがあることがわかりました。
この挙動に関してなにか進展があったら、追記したいと思います。
では。
#!/bin/bash # post_build VERSION=$(docker run --rm ${IMAGE_NAME} --version) docker tag ${IMAGE_NAME} ${DOCKER_REPO}:${VERSION} docker push ${DOCKER_REPO}:${VERSION}
※この記事は C++ Advent Calendar 2020 8日目の記事です。
zapcc は clang ベースのキャッシュを利用した高速な C++ コンパイラーです。
zapcc はサーバープロセスのメモリ上にキャッシュを構築して高速化します。
ヘッダーファイルの解析結果や template のインスタンス化などがキャッシュされます。
プリコンパイルヘッダーを使うよりも生成されたコードもキャッシュされるので高速です。
類似のツールで ccache というキャッシュツールがありますが、こちらは翻訳単位ごとにキャッシュする仕組みなのでフルビルドのときはキャッシュ生成するだけでキャッシュの恩恵を受けられませんが、 zapcc の場合は同じヘッダーファイルを include してるファイルで、template インスタンス化などのキャッシュが利用されるためフルビルドでも高速になります。
また、zapcc サーバープロセスがいる間は別のプログラムのコンパイル時でもキャッシュ利用可能なので複数のプログラムをビルドする際も高速になります。
導入は簡単でビルド・インストール後、 CXX=zapcc++ とするだけで使えます。
自作の C++ テスティングフレームワーク iutest のテスト環境として zapcc インストール済みの Docker を用意してるので、よろしければそちらからでも試せます。
https://hub.docker.com/r/srzzumix/zapcc
zapcc はビルドを高速に行うためにキャッシュをサーバーに蓄えます。
キャッシュはサーバープロセスが生きてるうちは有効です。
つまり、1つの実行ファイルをビルドするときだけでなく、その後に別プログラムをビルドする場合にもキャッシュが有効になります。
ライブラリの大量にあるテストプログラムをビルドするときには、このキャッシュがとても有効に働くと思います。
筆者が開発している iutest でも、複数のテストプログラムがあるのでビルド時間が短縮されるのを期待しましたが、結果は「テストの失敗」でした。
ビルドは特に問題なくできているように見えました、しかしながらテストは失敗している。
どうやらテストが失敗するのは、デフォルト設定ではなくテスト用に機能の有効化・無効化をしているテストでした。
iutest はコンフィグマクロを定義することで任意の機能を有効にしたり、無効にしたりするのですが、これが zapcc と相性最悪でした。。
どうやら、以下のようにとあるテストでコンフィグを変えても、キャッシュされたヘッダーファイルを利用してしまうため、#define が伝わっていないことがわかりました。
#define IUTEST_HAS_VARIADIC_TEMPLATES 0 #include "iutest.hpp"
並列ビルドしているとキャッシュされたヘッダーを利用してしまうため、直列にしました。 -j4 とかせず -j1 を指定。
はい。もこの時点で Zapcc の恩恵を捨てています。いやむしろビルド時間的には悪化する場合も考えられます。。。
次に、キャッシュサーバーのプロセスが生きたままになっているので、1プログラム作る度に kill するようにしました。。。
Makefile はこんな感じになりました。
ifeq ($(CXX_NAME),zapcc++) BUILD4ZAPCC=pkill zapcc++; sleep 1 endif $(TARGETS1) : $(OUTDIR)/% : %.cpp $(IUTEST_HEADERS) $(MAKEFILE) $(BUILD4ZAPCC) $(CXX) $(IUTEST_INCLUDE) $(CXXFLAGS) -o $@ $< $(LDFLAGS)
なんか無理くりですが、 iutest はビルド速度改善を目的に zapcc を使っているわけじゃなく、zapcc コンパイラで不具合がないか検証するために使っているので、これでもまぁいいのです。。
zapcc はすごいけど万能ではなかった。
※この記事は C++ Advent Calendar 2020 一日目の記事です。
C++20 で Concepts が導入されました。
コンセプト - cpprefjp C++日本語リファレンス
こういうこと?https://t.co/agPHVeBIV9
— いなむのみたまのかみ🍹☄️🐉🌽☃ (@mitama_rs) December 24, 2019
namespace printer_internal { template<typename Elem, typename Traits, typename T> ::std::basic_ostream<Elem, Traits>& operator << (::std::basic_ostream<Elem, Traits>& os, const T&) { return os << "unknown"; } } // 解決順序 // foo::operator << // ::operator << // ::printer_internal::operator << template<typename T> void print(const T& val) { using namespace ::printer_internal; ::std::cout << val << ::std::endl; }
ブログ更新。
— ずみっくす@あつまれCIサービス (@srz_zumix) September 25, 2020
ブログズミ: [C++] 警告のコンパイラー対応表を作り始めましたhttps://t.co/5fJRl9ChDw#cpp #未解決
[C++] GCC/Clang/VisualStudio の警告をまとめているので紹介|srz_zumix https://t.co/JvYEVEGjX4 #zenn
— ずみっくす@あつまれCIサービス (@srz_zumix) September 25, 2020
より広く見て欲しいので Zenn にも書いた
こちらで紹介した C++ 警告のまとめプロジェクトの作成にあたって、自作テスティングフレームワークの iutest で clang のすべての警告を有効にするオプション「-Weverything」を使って得た知見をまとめます。
double 型テストしてたつもりが float になってたのに気づきました。
なぜか二重についてた ; セミコロンに気づきました。
Windows 系のヘッダーが全部小文字だったのを修正しました。
マクロ内で使っていた変数名が b とか info とかかぶりやすい名前だったのを修正しました。
こちらはワークアラウンドの紹介になりますが、 Clang は Doxygen のコメントに対しての警告がありますが、対応していない Doxygen コマンドが存在します。
Diagnostic flags in Clang — Clang 12 documentation
その場合、コンパイルオプションに -fcomment-block-commands=private,internal,retval のようにコマンドを教えてあげることができます。
ただし、引数のない private や internal コマンドは別の -Wdocumentation 警告がでるようになってしまいます。
../include/internal/iutest_time.hpp:47:13: error: empty paragraph passed to '@internal' command [-Werror,-Wdocumentation] * @internal ~~~~~~~~~^
こちらの回避方法はまだ見つけてないので、見つけたら追記します。
以上。
TeamCity のクラウドサービスが始まるようでそのオープンβがやっていたので使ってみました。
TeamCity Cloud
[![TeamCity Cloud Build Status](https://iutest.beta.teamcity.com/app/rest/builds/buildType:Iutest_GoogleTestCompatibleTest/statusIcon?guest=1)](https://iutest.beta.teamcity.com/viewType.html?buildTypeId=Iutest_GoogleTestCompatibleTest&guest=1)
The Travis CI Blog: The new pricing model for travis-ci.com
Travis CI の新しい料金プランが 2020/11/02 より始まり、あっという間にクレジットを使い切りました。
特に懸念されていたのは CI サービスでの制限です。
DockerHub にログインしていない場合は IP に対して制限がかかるため、利用者の多いサービスではあっという間に上限越えて、制限がかかってしまうことが予想されました。
これに対し、すでに(期限付きではありますが)制限を受けないようにする交渉が完了しているサービスもあります。
DockerHub による2020/11からのコンテナイメージ Pull 回数制限のCircleCIへの影響 - Build Environment - CircleCI Discuss
ある程度猶予があるかもしれないですが…
何れにせよ、今後 DockerHub からイメージを pull して CI を回す場合は、事前に DockerHub へのログインをするようにパイプラインを更新しておくのが良さそうです。
それらへの対応方法についても、記事冒頭のドキュメントからリンクが貼られていたり、各 CI サービスから案内が出ていると思います。
筆者が開発している C++ テスティングフレームワークの iutest はめちゃくちゃたくさん CI サービスを使っているので(Docker 関係ないものもあるので全部ではないが)絶賛対応中です。
対応方法はログインするだけなんですが、各サービスやり方が異なるのでここでは対応方法は省略します。
一応、状況はこちらの issue で確認できます。
https://github.com/srz-zumix/iutest/issues/519
https://t.co/E8DUTOMi4M
— ずみっくす@あつまれCIサービス (@srz_zumix) October 23, 2020
DockerHub の pull 制限回避のためのログイン対応中。
CI サービス多用してるので大変(docker 使ってないものも多いけど)
CircleCI みたいに延命されると嬉しいなぁ・・ pic.twitter.com/UnQaIeY9ih
で、ようやく本題。
このログイン対応をしていて思ったのは、「設定したけど本当にログインした状態で pull できているのかをどう確認したらわからなくて不安」でした。
docker login してるかどうか確認するコマンドってない?
— ずみっくす@あつまれCIサービス (@srz_zumix) October 29, 2020
docker のコマンドに「それ」を確認するものがあればよかったのですが、なさそうだったので以下の方法で確認しました。
「echo a | docker login」
ログイン済みなら以下のように成功となります。
$ echo a | docker login Authenticating with existing credentials... Login Succeeded $ echo $? 0
$ echo a | docker login Error: Cannot perform an interactive login from a non TTY device $ echo $? 1
Include-What-You-Use-CL is Visual Studio toolset for Include-What-You-Use
git clone https://github.com/srz-zumix/include-what-you-use-cl.git
cd include-what-you-use-cl
install.bat
uninstall.bat
pip install lizard
lizard: runs-on: ubuntu-18.04 needs: prepare steps: - uses: actions/checkout@master - name: Lizard uses: docker://srzzumix/lizard with: args: -o lizard.html --html ./include - name: Archive code metrics results uses: actions/upload-artifact@v1 with: name: lizard.html path: lizard.html
python: error while loading shared libraries: libpython3.8.so.1.0: cannot open shared object file: No such file or directory
GitHub Actions で setup-python 使って python のテストをしていたのですが、とあるときから上記エラーが出るようになっていたので、以下の修正で対応しました。
zapcc-basic-test: runs-on: ubuntu-18.04 container: docker://srzzumix/zapcc needs: prepare steps: - uses: actions/checkout@master - uses: actions/setup-python@v2 with: python-version: 3.8 - name: zapcc test run: | make -C test clean make -C test showcxxversion make -C test check_stdlib make -C test -j1 IUTEST_REQUIRE_PYTHON=1 make -C test test
zapcc-basic-test: runs-on: ubuntu-18.04 container: docker://srzzumix/zapcc needs: prepare steps: - uses: actions/checkout@master - uses: actions/setup-python@v2 with: python-version: 3.8 #### ここを追加 #### - name: Set Python environment variable run: echo "LD_LIBRARY_PATH=${{ env.pythonLocation }}/lib" >> $GITHUB_ENV ################ - name: zapcc test run: | make -C test clean make -C test showcxxversion make -C test check_stdlib make -C test -j1 IUTEST_REQUIRE_PYTHON=1 make -C test test
setup-python が pythonLocation 環境変数をセットしてくれるのでそれを使って LD_LIBRARY_PATH を設定します。
以上。
set-env コマンドは Deprecated だったので修正しました。
GitHub Actions: Deprecating set-env and add-path commands - GitHub Changelog
修正前: echo '::set-env name=LD_LIBRARY_PATH::${{ env.pythonLocation }}/lib'
修正後: echo "LD_LIBRARY_PATH=${{ env.pythonLocation }}/lib" >> $GITHUB_ENV
Zenn が話題になっていたので自分も記事を書くことにしました。
本も書きたいなと思っています。
現時点で何個か記事を書きました。
CI サービスを活用して Zenn の執筆環境を作る - 序章|srz_zumix https://t.co/F7ZmQvho6g
— ずみっくす@あつまれCIサービス (@srz_zumix) September 23, 2020
書いた
[C++] GCC/Clang/VisualStudio の警告をまとめているので紹介|srz_zumix https://t.co/JvYEVEGjX4 #zenn
— ずみっくす@あつまれCIサービス (@srz_zumix) September 25, 2020
より広く見て欲しいので Zenn にも書いた
[textlint] Zenn 独自記法への警告を除外する|srz_zumix https://t.co/h2FG34lU8A #zenn
— ずみっくす@あつまれCIサービス (@srz_zumix) September 25, 2020
ついでにもう1つ書いた
srz-zumix/awesome-cpp-warning: c++ warning correspondence table (Clang/GCC and Visual Studio)
マルチプラットフォームやってると、Visual Studio (VC++) と clang で警告の制御方法が異なるので面倒くさいなーって思っていたので対応表を作りました。
(全部 clang にしたら楽なんですけどね・・・)
特に vc++ は C4096 とかの ID でコントロールするのでわかりにくいんですよね。
あとは当然、clang では警告になるけど、vc++ は警告ないとか。逆パターンとか、clang だとエラーとか、あるあるだと思います。
そんなマルチプラットフォーム開発のビルドエンジニア向けにまとめた(まとめている)ものが↑↑です。
とりあえず、VC++ の警告を一通りみてサンプルコードがあるものや、すぐに再現できたものに対してはこちらの表に記載してます。
https://github.com/srz-zumix/awesome-cpp-warning/blob/master/VCLIST.md
そして、おそらくみんなが欲しいのは clang/gcc の -Whogehoge 警告が vc++ だと ID いくつなのかって点だと思うので top にまとめてます。
(すべての警告を無視(よくないけど)したり、すべての警告を as error として直さなければならない環境ならあまり必要ないかも?)
今後も対応表を増やしていこうと思ってます。
もちろん PR 大歓迎です!!
今回は以上。では。
[![GitHub Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub&color=ff69b4)](https://github.com/sponsors/srz-zumix)
技術書典9 が始まりましたね。
私は今回サークル参加しておりませんが、前回初めて参加しました。
来年また参加できたらいいなと思っております。
さて、そんな中今回は執筆環境周りのことを書きたいと思います。
技術書典9が始まったばかりですが、こちらはイベント後に役に立つ内容かと思うので、このタイミングでの公開としました。
紹介するのは表題のとおり、「Re:VIEW Starter」で作成された書籍をただの「Re:VIEW」で扱える状態にコンバートするツールです。
このツールがなぜ必要になったのか?はここでは省略しますが、この変換が必要になる人は今後も少なからず出てくるのではないかな?と思っております。
(私自身も今後の執筆にただの「Re:VIEW」を使うつもりはなく、「Re:VIEW Starter」や他の便利な環境を使いたいと思っているので、またお世話になることもあるかもしれません。)
ツールは「Re:VIEW Retrovert」といいます。ruby で書かれていて gem install review-retrovert ですぐに使えます。
また、コードは GitHub にて公開中です。
https://rubygems.org/gems/review-retrovert
https://github.com/srz-zumix/review-retrovert
review-retrovert convert /path/to/dir/review-starter/config.yml <output directory>
Re:VIEW Starter のプロジェクトの config.yml から Re:VIEW のプロジェクトを生成して出力ディレクトリに書き出します。(Re:VEIW のバージョンは 3.2 です)
テストとして Re:VIEW Starter のテンプレプロジェクトを変換したものが GitHub Actions の成果物として残してあるので、どんな結果になるのかすぐ見てみたい人はダウンロードしてみてください。
https://github.com/srz-zumix/review-retrovert/actions/runs/201132608
Re:VIEW Starter は Re:VIEW という名がついていますが、単なる Re:VIEW とはもう別物といっていいくらい便利な機能が拡張されています。
その分、Re:VIEW Retrovert ではこれらの拡張機能を Re:VIEW でも取り扱えるようになるべく、もとの状態を保つように頑張ってます。
ただ、どうしても全く同じ出力にすることはできません。
コンバート後は一通り目を通していただき、不自然な箇所や欠落した場所を調整していただく必要がありますのでご了承ください。
いくつか事例をあげておきます。
出力される Re:VIEW プロジェクトは version 3.2 を想定しています。
4 系が使いたい場合は issue 投げてください。(3.2 から 4.X へアップグレードできるかもしれないので、もしかしたら使えるかもしれません。)
まず Re:VIEW で表現できない命令は削除されます。
文字サイズや修飾はなくなるものと考えてください。(一部は類似の命令に置換します)
次に、ネストされたインライン命令は Re:VIEW では対応してないので、それぞれネストにならないように分解して出力しています。
また、テーブル中のインライン命令も安定しないため、テーブル中の @<br> は削除されます。
空のセルとして . を使用している場合に Re:VIEW の出力がなぜか2行になってしまっていたので、空のセルは . ではなくスペースに置換しています。
また、ブロック命令もネストできないので内側の命令は無視されるので注意してください。
他にもいろいろ無理やり対応しているところがあるので、もし使ってみておかしなところがあれば issue 出してください。
https://github.com/srz-zumix/review-retrovert/issues
もともとは自分用に書いたツールですが誰かの役に立てば幸いです。
執筆環境の制約はどうしても発生することがありますが、私としてはこのツールのおかげで安心して Re:VIEW Starter を使っていけるようになったかなと思います。
では。
ミスって gems に publish できてませんでしたmm
v0.9.1 から新しい Re:VIEW Starter に対応してます。
https://rubygems.org/gems/review-retrovert
表題のとおりですが以前公開した wandbox-api に
C/CPP/Go/JavaScript/Nim/OpenSSL/Perl/Python/Ruby/TypeScript のラッパーコマンドを追加しました。(以前の記事はこちら「ブログズミ: Wandbox の CLI ツールを作ってみた」)
それぞれ言語ごと特有のオプションやコンパイラオプション・ランタイムオプションが使用可能かどうかに対応しています。
また、C/CPP/C++ であれば #include してるファイル(システムヘッダー除く)を自動的にファイルリストに追加する機能がありますが、Python の import や Ruby の require なども対応をしています。
OpenSLL は少し特殊でローカルで openssl を使うのと同じように使えるように工夫してます。
(あんまりデバッグしてないので対応してないサブコマンドありそうですが・・)
例えば、以下のように鍵の作成が可能です。
> wandbox-ssl genrsa -out test.key 2048
> wandbox-ssl rsa -in test.key -pubout -out test.key.pub
できた pic.twitter.com/iPNXEakQBA
— ずみっくす@あつまれCIサービス (@srz_zumix) August 21, 2020
需要があるのかわからないけど、openssl がインストールされてなくても python があれば openssl 相当のことができるようになりました。
筆者が明るくない言語はファイルリストの自動登録機能が正しく動作してなかったり、対応してない構文があったりするかもしれません。
(実際、JavaScript/TypeScript の require は対応してないです)
ぜひ、PR いただけると嬉しいです。
ではでは。
\renewcommand{\starter@subsection@symbol}{$▶$}
/** * @page CMDLINE コマンドラインオプション * @par Command Line Options