C++ ときどき ごはん、わりとてぃーぶれいく☆

USAGI.NETWORKのなかのひとのブログ。主にC++。

vscode extension: 開かれている vscode.TextEditor を列挙する方法のメモ

import * as vscode from 'vscode'

// 列挙した TextEditor を格納する array
const es: vscode.TextEditor[] = []

// 次の TextEditor を取得するトリック
let nextTextEditor = async () =>
{
  await vscode.commands.executeCommand( 'workbench.action.nextEditor' )
  return vscode.window.activeTextEditor
}

// 現在の TextEditor から逐次 TextEditor を取得し、 undefined または既に列挙済みの TextEditor が再列挙されたらおしまい
// 2020-01-05T15:41+09:00 修正(†1)
for ( let e = vscode.window.activeTextEditor; e && !es.some( _ => (<any>_)._id === (<any>e)._id ); e = await nextTextEditor() )
{
  // おまけデバッグコード: 直前に取得された TextEditor に紐づいている TextDocument の uri をロギング
  console.log( 'debug', e.document.uri )
  es.push( e )
}

参考リンクを元にTS初心者が書いてみました。バッドノウハウの香りが漂う気もしますが、いまのところ vscode の extension 用に公開されている API で実装する方法はこんな具合にならざるを得ないようです。

特定の状態の TextEditor を見つけたいだけなら for の中で見つけたら break 、全部の情報が欲しいなら列挙を終えてから es を観察、操作する実装を応用すればよいでしょう(たぶん)。

参考

(†1) 修正

// 修正後
for ( let e = vscode.window.activeTextEditor; e && !es.some( _ => (<any>_)._id === (<any>e)._id ); e = await nextTextEditor() )
// 修正前
for ( let e = vscode.window.activeTextEditor; e && !es.includes( e ); e = await nextTextEditor() )

TSを介してもESはやっぱりこわいです。疲弊します。おうちに帰りたい的な気持ちになりました…。(個人のTS初心者の感想です)

nodejs: child_process.spawn とシェル実行の方法の模範解答についてのメモ(あるいはバッドノウハウを広めないための自分用の戒めとしてのメモというかあけおめ生存報告のメモ)

最初に答え

let spawn = require('child_process').spawn;

// 模範解答(たぶん)
let p = spawn( 'echo', [ 'hoge' ], { 'shell': true } );

p.stdout.on( 'data', payload => console.log( `[spawn/stdout]: ${payload.toString().trim()}` ) )
p.stderr.on( 'data', payload => console.log( `[spawn/stderr]: ${payload.toString().trim()}` ) )
p.on( 'exit', exit_code => console.log( `[spawn/exit] ${exit_code}` ) )

参考

要点

  • spawn には第3仮引数の options というのがあります
  • optionsshell を定義すると、
    • true にすると実行環境に応じて、 Windows なら process.env.ComSpec から実質的には cmd 、 nodejs が UNIX として扱う環境では /bin/sh-c オプションを噛ませたシェル実行モードになります
    • false にするとシェルを介さずに spawn の第1仮引数の command を直接実行します
    • string 型の値を与えると、与えられた文字列をシェルコマンドと見做して、それに -c オプションを噛ませたシェル実行モードになります

例えば、 powershell をシェルとして実行したい場合は↓のようになります。

let spawn = require('child_process').spawn;

let p = spawn( 'Get-ChildItem', [ '..' ], { 'shell': 'powershell' } );
p.stdout.on( 'data', payload => console.log( `[spawn/stdout]: ${payload.toString().trim()}` ) )
p.stderr.on( 'data', payload => console.log( `[spawn/stderr]: ${payload.toString().trim()}` ) )
p.on( 'exit', exit_code => console.log( `[spawn/exit] ${exit_code}` ) )

powershell は通常は Windows 環境のシステム標準で PATH が通り、 PATHEXT に .EXE があり NTFScase-insensitive なので、実行ファイルのフルパスを書かなくても powershell だけで実行でき、かつ -c オプションが期待動作するのでこれで使えます。

おまけ

諸事情により7年ぶりに TypeScript でおもちゃを書きはじめました。それで、なんでわざわざこんなメモを残したのかというと、世の中にはしばしば公式ドキュメントを読めばきれいな実現方法が書いてあるのに、読まずに、"俺は試行錯誤の結果こうしたらできたからみんなもこうするといいよ"的な野良バッドノウハウがおそらく誰も悪意などなく意図せずとも広まりやすい言語というのがあります。それ自体は発生してしまったものですし、わざわざあちこちに公開されているバッドノウハウへたまたま見つけたからというだけで7年ぶりにちょっと触った程度の nodejs 初心者がマサカリを投げるほど、私は傲慢でも暇でも親切でもないのですが、自分用には面白い戒めにもなるな、と思い、少し丁寧にメモを残してみました。

// これは日本語に限らず、参考用にソースを眺めたOSSでも少なくなかったバッドノウハウの例です
let p = spawn( 'cmd', [ '/c', 'echo', 'this is a bad know-how; read the official document first.' ] )

私もたくさんのバッドノウハウを悪意はなくとも広めてしまっている事もあるのでしょうが、なかのひとの気持ちとしてはできるだけきれいに、かつ(複数の意味で)面倒なく快適に、これからもお鮨を食べ、フリッツを食べ、不幸よりも幸せを多く感じて2020年以降も生きたいと思います。

あけおめ。

vcpkg_chii: vcpkg cmake hyper integration injector 作りましたのメモ

↓つくりました:

vcpkg を使い始めてから、自分の便利用に書いた CMake 用のギミックをモジュール化したものです。 README.md の冒頭で

Let's do more easy, make it more convenient for vcpkg and CMake users.

(にほんご↓)

もっと楽に、便利に、 vcpkg と CMake ユーザーを。

と、いうわけで vcpkg_chii を使うと、 "hyper" (過剰なくらいの) な vcpkg のインテグレーション(統合機能)を CMake へ注入します。具体的には、

  1. cmake .. するだけ(理想的には)でOKになります(†1)
    1. VCPKG_TARGET_TRIPLET環境変数またはシステム標準から自動設定されるようになります
    2. CMAKE_TOOLCHAIN_FILEvcpkg コマンドのパスから自動設定されるようになります
  2. 事前に vcpkg install <library> することを気にしなくてよくなります
    1. 必要なライブラリーは cmake の中で自動的に vcpkg でインストールされるようになります

なので、ちょっと過剰なんですが、実用性としてはとても便利になるのでまあいっかーと思います。注意点として、一応、この機能を使用するプロジェクトを公開する場合は、ソースからビルドするユーザーに対してこんな機能を取り込んでいるよって表示はした方が良いと思います。何も指定しないと試しに CMake したら依存ライブラリーを vcpkg で全自動で落としてビルドし始めて気づいたら cmake するだけでビルドまで終わってしまった…というのは、状況によっては望まないか警戒されると思うので。たいていは、実際問題便利なだけだと…思うけどね。

ちなみに、 cmake .. -DVCPKG_CHII_ENABLE=OFF すれば vcpkg_chii の機能は使わないモードになるので、 vcpkg あるいは vcpkg_chii を使いたくない状況やユーザーにも必要最小限ていどには安心かもしれません。

vcpkg, cmake に興味があれば、とりあえず使ってみて下さい。使い方の例は、 example に簡単な vcpkg から Eigen と google-test を引っ張ってきて使う CMake + vcpkg_chii 採用なミニ・プロジェクトを用意したので、そちらでお試し下さい。

(†1): vcpkg 標準の CMake インテグレーションは cmake .. -DCMAKE_TOOLCHAIN_FILE=<path-to-vcpkg>/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static とか良くも悪くも cmake するときに長い呪文の詠唱を必要とします。

C++ のパッケージマネージャーの選択メモ( conan vs. vcpkg vs. Hunter on Windows and Ubuntu ): C++ 実装がサブプロジェクトとして内包されるクロスプラットフォームアプリのリポジトリーの場合

タイトルが少しややこしいので最初に整理します。

  • このメモは: C++ のパッケージマネージャーの選択のはなし
  • ただし:
    • アプリはクロスプラットフォーム ( このメモでの具体例は Windows-10 & Ubuntu-19.04 )
    • アプリ全体(=このメモでは「ソリューション」とします)はいくつかの構成部品(=このメモでは「プロジェクト」とします)に分けて作られる
    • プロジェクトの1つ以上に C++ を採用したい
      • そのプロジェクト単位で C++ のライブラリーを管理できるパッケージマネージャーを導入したい → どうするのが楽そうかな

のメモです。

選択肢と大雑把な検討

  1. conan https://conan.io/
  2. vcpkg https://github.com/microsoft/vcpkg
    • MicrosoftWindows 向けの Visual Studio のために作ったパッケージマネージャー「だった」。今では GNU/LinuxOSX も対象プラットフォームという事になっている
  3. Hunter https://github.com/cpp-pm/hunter
  4. (最終手段) ライブラリーごとに手書きの CMake 魔術を作りプロジェクトの CMakeLists.txt へ仕込む https://cmake.org/cmake/help/latest/
    • これを選択すると保守の手間が増えるので 1, 2, 3 の何れかにしたい

対応パッケージの手広さ対決

登録パッケージ数を比べてもあんまり意味が無いので、実際に私がソフトウェア開発プロジェクトで触れる機会、可能性のあるライブラリーやフレームワークを適当に列挙して、実際にコマンドで search を叩く、最新のリストから grep しつつ、ついでにライセンスとオリジナルの入手情報も整理しました。パッケージ名に気を付けると良さそうな場合は有無の〇×の〇代わりにパッケージ名を記載しました。

要注意 この表は 2019年12月29日 の調査結果です。

categorynameLICENSEconanvcpkgHunteroriginal
3D-data, FormatAssimpBSD-3-Clause×https://github.com/assimp/assimp
All-purposeBoost 1.0Boost 1.0https://github.com/Boost 1.0org/Boost 1.0
Civil-engineeringOSGeo/PROJMIT×proj4PROJ4https://github.com/OSGeo/PROJ
Civil-engineering, Image, FormatOSGeo/libgeotiffpublic domain××https://github.com/OSGeo/libgeotiff
Compressionzlibzlib/libpnghttps://www.zlib.net/
CompressionzstdBSD | GPLv2×https://facebook.github.io/zstd/
Compressionliblzmapublic domainlzmahttps://tukaani.org/xz/
CompressionSnappyApache 2.0https://google.github.io/snappy/
CompressionLZ4BSD-2-Clausehttps://github.com/lz4/lz4
ConcurrencyOpenCLKhronos OpenCLhttps://github.com/KhronosGroup/OpenCL-Headers
ConcurrencyOpenCL-cppKhronos OpenCLkhronos-opencl-clhpp×https://github.com/KhronosGroup/libclcxx
ConcurrencyTBBApache 2.0×https://github.com/intel/tbb
CryptoCryptoPPBoost 1.0https://github.com/weidai11/cryptopp
DatabaseSQLite3public domainhttps://sqlite.org/src/timeline
DatabasesqlitecppMIT×https://github.com/SRombauts/SQLiteCpp
Image, Computer-visioningOpenCVBSD-3-Clausehttps://github.com/opencv/opencv
Image, Computer-visioningOpenMVGMPL 2.0××https://github.com/openMVG/openMVG
Image, Computer-visioningOpenMVSAGPL××https://github.com/cdcseacave/openMVS
Image, Font, Format(*)stbpublic domainhttps://github.com/nothings/stb
Image, FormatlibtiffBSD-liketifftiffhttp://www.simplesystems.org/libtiff/
Image, Format, JPEGlibjpegBSD-likejpeghttp://libjpeg.sourceforge.net/
Image, Format, PNGlibpngzlib/libpngpnghttps://libpng.sourceforge.io/
Image, Format, WebPWebPBSDhttps://developers.google.com/speed/webp/
Linear-algebra, MathEigenMPL 2.0http://eigen.tuxfamily.org/
NetworkingcurlMIThttps://github.com/curl/curl
NetworkingcurlppMIT××https://github.com/jpbarrette/curlpp
NetworkingBoringSSLOpenSSL××https://boringssl.googlesource.com/boringssl/
NetworkingOpenSSLApache-stylehttps://www.openssl.org/
NetworkingCrowBSD-3-Clause××https://github.com/ipkn/crow
Networking, RPC, gRPCgRPCApache 2.0×https://github.com/grpc/grpc/tree/master/src/cpp
OpenGLOpenGL RegistryKhronos OpenGL×opengl-registry×https://github.com/KhronosGroup/OpenGL-Registry
OpenGLGLFWzlib/libpngglfw3https://github.com/glfw/glfw
OpenGL, GUIimguiMIThttps://github.com/ocornut/imgui
OpenGL, MathglmHappy Bunnyhttps://glm.g-truc.net/
OpenGL, WindowsglewBSD-3-Clausehttps://github.com/nigels-com/glew
OpenGL, Windows, Direct3DANGLEBSD-3-Clause××http://angleproject.org/
Script, JavascriptV8BSD-3-Clause××https://v8.dev/
Script, LuaLuaMIT×https://github.com/lua/lua
SerializationcerealBSD-3-Clausehttps://github.com/USCiLab/cereal
Serialization, CSVcsv-parser-plusplusGPLv3××https://github.com/headupinclouds/csv-parser-cplusplus
Serialization, CSVfast-cpp-csv-parserBSD-3-Clause××https://github.com/ben-strasser/fast-cpp-csv-parser
Serialization, JSONRapidJSONBSD-3-Clausehttps://github.com/Tencent/rapidjson/
Serialization, JSON, BSONjsonMITnlohmann_jsonnlohmann-jsonnlohmann_jsonhttps://github.com/nlohmann/json
Serialization, MessagePackmsgpackBoost 1.0https://github.com/msgpack/msgpack-c
Serialization, XMLRapidXMLBoost 1.0http://rapidxml.sourceforge.net/
Serialization, XMLXercesApache 2.0×http://xerces.apache.org/xerces-c/
Unit-testCatchBoost 1.0https://github.com/catchorg/Catch2
Image, Computer-visioningpclBSD-3-Clause××https://github.com/PointCloudLibrary/pcl
Image, Computer-visioningOpenNI2Apache 2.0××https://github.com/occipital/openni2
Concurrency, GPGPUCUDAGPLv2 and etc.××https://developer.nvidia.com/cuda-zone

この調査結果からは、私の中では意外な事に vcpkg がとても有用そうな事がわかりました。少なくとも Windows で cl.exe 系のツールチェインを使う場合には vcpkg が期待動作しない事も少ないでしょうから、クロスプラットフォーム対応ではなく Windows だけを対象にする場合は vcpkg 一択で良さそうです。

vcpkg の懸念は Windows 以外でも期待動作してくれるのか…です。これは実際に試してみないと安心できません。

お試し

このメモでは...

  1. Eigen http://eigen.tuxfamily.org/
    • // header only
  2. Message Pack (msgpack-c) https://github.com/msgpack/msgpack-c
    • // build required

conan, vcpkg, Hunter で取り込んでみます。

翻訳するソース my_something.cpp は...

#include <Eigen/Core>
#include <msgpack.hpp>
#include <fstream>

extern "C" double my_norm( double x, double y, double z )
{
  return ::Eigen::Vector3d{ x, y, z };
}

extern "C" void my_serialize( const std::string& path, double value )
{
  ::msgpack::sbuffer b;
  ::msgpack::pack( b, value );
  ::std::oftream( path, ::std::ios::binary ).write( b.data(), b.size() );
}

無事に build.cmake/lib/libmy_something.so を作れた場合は、 pythonod (Ubuntuなどの場合) または Format-Hex (Windows/PowerShellの場合) で簡易動作確認します:

>>> from ctypes import *
>>> l = cdll.LoadLibrary( 'lib/libmy_something.so' )
>>> l.my_norm.restype = c_double
>>> l.my_norm( c_double( 1 ), c_double( 2 ), c_double( 3 ) )
3.7416573867739413
>>> l.my_serialize( c_char_p( 'out'.encode( 'utf-8' ) ), c_double( l.my_norm( c_double(1), c_double(2), c_double(3) ) ) )
0
(CTRL+D)

od -tx1z -Ax out または Format-Hex -Path outout を確認

000000 cb 40 0d ee ea 11 68 3f 49                       >.@....h?I<
000009

Notes:

conan

導入方法

  1. python と pip を使える状態にする
  2. pip install conan

プロジェクトへのパッケージ追加方法

  1. パッケージを探す:
    1. conan search "*eigen*" --remote=conan-center
    2. conan search "*msgpack*" --remote=conan-center
    3. コツ: 検索キーワードは小文字にし、ありそうな名称の前後に * を付けてワイルドカード付きで検索すると見つけやすいです
    4. 動作はわりともっさりですが、数秒待っていれば動きます
  2. パッケージを確認:
    1. conan inspect eigen/3.3.7
    2. conan inspect msgpack/3.2.0@bincrafters/stable
  3. パッケージを使用可能な状態にする:
    1. プロジェクト内のパッケージの定義ファイルを作る: conanfile.txt (†1)
    2. パッケージのビルドディレクトリーを作って入る: mkdir build.conan && pushd build.conan
    3. 導入: conan install .. && popd; ..conanfile.txt のある場所
      • conanfile.txt へライブラリーを追加する事があれば conan install の再実行も必要
      • Windows, Ubuntu あたりの一般的なツールチェインはバイナリーが降ってくるのですぐ終わります
  4. プロジェクトに CMake プロジェクトファイルを用意して conan のパッケージを使用してビルド:
    1. CMakeLists.txt を用意して conan 用の追記...
      1. include(${PROJECT_SOURCE_DIR}/conan.build/conanbuildinfo.cmake)
      2. conan_basic_setup()
      3. target_link_libraries( my_project ${CONAN_LIBS} )
    2. mkdir build.cmake && pushd build.cmake
    3. cmake ..
    4. cmake --build .

(†1) ↓ conanfile.txt; パッケージ名は大文字小文字に敏感です

[requires]
eigen/3.3.7
msgpack/3.2.0@bincrafters/stable

[generators]
cmake

パッケージの実体

  • ~/.conan ディレクトリー内にパッケージごとに実体が conan install .. で必要になる度に導入が確認され格納される
    • プロジェクト内にはパッケージはソース、バイナリー何れも配置されず、 cmake から↑が参照される
    • パッケージの管理単位にバージョン情報なども内包しているので、複数プロジェクトでパッケージが混乱する事は無さそう(たぶん)

vcpkg

導入方法

  1. git clone https://github.com/Microsoft/vcpkg.git
    • または git subtree, git submodule で取り込む
  2. pushd vcpkg
  3. vcpkg の実行ファイルをビルド; 数分程度かかるかもしれません
    • GNU/Linux っぽい環境: ./bootstrap-vcpkg.sh
    • Windows っぽい環境: ./bootstrap-vcpkg.bat
  4. ビルドツールへの仕込み; しなくてもいいけど、すると便利かもしれないし、厄介事の原因になるかもしれないのでプロジェクトにあわせてどうぞ
  5. popd

プロジェクトへのパッケージ追加方法

Note: vcpkg をどこに置くかによらずパスを通したり alias を張ったりする場合は vcpkg/vcpkg とパス付きで呼ぶ必要はないのですが、今回はプロジェクト単位でライブラリー管理時にしか使わないので、パス付きで呼んで済ませます。

  1. パッケージを探す:
    1. vcpkg/vcpkg search eigen -> eigen3 3.3.7-3 C++ template library for linear algebra: matrices, vectors, numerical solvers,...
    2. vcpkg/vcpkg search msgpack -> msgpack 3.2.0-1 MessagePack is an efficient binary serialization format, which lets you exchan...
  2. バージョンの固定が必要なら ports ディレクトリーの中身を適当に編集して対処します
    • 不要な場合は何もせず↓へ
  3. パッケージを導入:
    1. vcpkg/vcpkg install eigen3 終了時に CMake 用の情報を教えてくれます(†1)
    2. vcpkg/vcpkg install msgpack 終了時に CMake 用の情報を教えてくれます(†2)
  4. CMakeLists.txt にライブラリーを追加; ↑で教えてくれる例をもとにプロジェクト名を main から実際の my_something へ変えて追加
    1. find_package( Eigen3 CONFIG REQUIRED )
    2. find_package( msgpack CONFIG REQUIRED )
    3. target_link_libraries( my_something PRIVATE Eigen3::Eigen msgpackc msgpackc-cxx msgpackc-static)
  5. ビルド:
    1. mkdir build
    2. cd build
    3. cmake .. -DCMAKE_TOOLCHAIN_FILE=../vcpkg/scripts/buildsystems/vcpkg.cmake
      • CMake Error ... "msgpackc-static" is imported but not globally visible とか出たら
        • vcpkg/installed/ { x64-linux などのプラットフォーム名 } /share/msgpack/msgpack-targets.cmake
        • add_library(msgpackc-static ... に GLOBAL を追記する修正が一時的に必要かもしれません
        • https://github.com/microsoft/vcpkg/issues/7205
    4. cmake --build .

(†1): ↓ ./vcpkg install eigen3 の終わりに表示される CMake ではこうしてね情報:

    find_package(Eigen3 CONFIG REQUIRED)
    target_link_libraries(main PRIVATE Eigen3::Eigen)

(†2): ↓ ./vcpkg install msgpack の終わりに表示される CMake ではこうしてね情報:

    find_package(msgpack CONFIG REQUIRED)
    target_link_libraries(main PRIVATE msgpackc msgpackc-cxx msgpackc-static)

パッケージの実体

  • vcpkg 導入先の buildtrees, installed, packages にそれぞれソースやビルドされたライブラリーが放り込まれます

Hunter

導入方法

  1. Hunter をプロジェクト単位で使うための HUNTER_ROOT 用のディレクトリーを作成:
    • mkdir hunter_root (†2)
  2. HunterGate をプロジェクトへ仕込む https://cpp-pm-hunter.readthedocs.io/en/latest/quick-start.html
    1. mkdir cmake
    2. HunterGate.cmake をダウンロードして配置
      • wget を使う場合: wget https://raw.githubusercontent.com/hunter-packages/gate/master/cmake/HunterGate.cmake -O cmake/HunterGate.cmake
      • PowerShell を使う場合: Invoke-WebRequest -Uri https://raw.githubusercontent.com/hunter-packages/gate/master/cmake/HunterGate.cmake -OutFile cmake/HunterGate.cmake
  3. CMakeLists.txtproject よりも前に Hunter を仕込む... (†1)
    1. set( ENV{HUNTER_ROOT} "${CMAKE_CURRENT_SOURCE_DIR}/hunter_root" ) (†2)
    2. include( "cmake/HunterGate.cmake" )
    3. HunterGate( URL "https://github.com/cpp-pm/hunter/archive/v0.23.240.tar.gz" SHA1 "ca19f3769e6c80cfdd19d8b12ba5102c27b074e0" )

(†1): この仕様のため、 Hunter は add_subdirectory されるサブプロジェクト単位で使用したい場合に少し厄介です。サブディレクトリー単位で独立した CMake を呼ぶトリックを仕込むか、諦めてルートになるプロジェクトの project よりも前に Hunter を仕込むか、状況によっては悩ましい対応が必要になるかもしれません。

(†2): ~/.hunter_root%HOMEPATH%/.hunter_root を用意して、 .bashrcWindows環境変数設定で HUNTER_ROOT をその場所へ設定しておくと conan のように合理的なパッケージ実体の管理方法になります。このメモの方法はプロジェクト単位の中へ Hunter のパッケージ管理と本体も押し込めたい場合の簡単なトリックの例です。

プロジェクトへのパッケージ追加方法

  1. パッケージを探す... https://cpp-pm-hunter.readthedocs.io/en/latest/packages.html
    1. Eigen https://cpp-pm-hunter.readthedocs.io/en/latest/packages/pkg/Eigen.html
    2. msgpack https://cpp-pm-hunter.readthedocs.io/en/latest/packages/pkg/msgpack.html
  2. CMakeLists.txt にライブラリーを追加
    1. hunter_add_package( Eigen )
    2. hunter_add_package( msgpack )
    3. find_package( Eigen3 CONFIG REQUIRED )
    4. find_package( msgpack CONFIG REQUIRED )
  3. ビルド
    1. mkdir build.cmake && pushd build.cmake
    2. cmake ..
      • Hunter のパッケージビルドがここで行われるので容赦なくかなりながい時間がここでかかります
        • 妙に長いので🍵ブレイク後に見たら Eigen, msgpack のほか OpenSSL, ZLIB もフルビルドされていました...
    3. cmake --build .

パッケージの実体

  • CMake から HunterGate が実行された際の HUNTER_ROOT 環境変数ディレクトリー内へ、ダウンロード、ビルドされる
    • メタ情報の管理も細かくされていて、パッケージバージョンが混乱したりする心配は無さそう
  • conan のようにパッケージの実体はプロジェクトを超えて合理的に共有したい場合は適当な共有用のディレクトリーを設け、 HUNTER_ROOT 環境変数をプロジェクトの外で設定すればOK

現時点での感想

  1. WindowsUbuntu 程度の軽いクロスプラットフォーム対応性
    • 現時点では conan, vcpkg, Hunter どれでも問題になる事の方が少なさそう
      • vcpkgmsgpack では手修正が必要な問題が発生しましたが、エラーメッセージを読めば対応できる程度なのでまあ…どうだろう…プロジェクトの開発者が初心者だらけだったら…厳しいかもしれませんね…
  2. ライブラリーの対応の幅広さ、抜け目の無さ
    1. 現時点での一般論としては vcpkg が他に比べて少し有能そう; OSGeo/PROJ, OpenMVG, curppp など
    2. conan, Hunter も一般性の高いパッケージに困る事はおおよそない; zlib, libjpeg, boost など
  3. パッケージ検索のし易さ
    1. vcpkg が理想的かもしれません。
      • vcpkg search の動作がわりと軽快
      • 導入先の ports ディレクトリーを眺めるだけでも探せる
    2. conan searchpip のようなもっさり感はあるものの(中身はpythonだしね...)、実用十分には探せる&耐えられる
    3. Hunter はコマンド式のインターフェースは無く、"読み物"から探すのは地味にだるいです...
  4. プロジェクト単位での使いやすさ
    1. conan がとても合理的; 実体はバージョンごと共有管理するけれど使用はプロジェクト単位で特定バージョンを引っ張れる
      • しばしば conan は CMake の使い方が邪悪と言われるけれど、そもそも CMake のパッケージ管理のゆるふわ感を考えるとどうでもいいかな、むしろこういうまとめ方もユーザーには便利でいいかもーくらいにゆるっと思う程度です
    2. vcpkg はプロジェクト単位での使用方法が極めて強引ですが、プロジェクトで採用する補助ツールを git subtree / git submodule などで取り込みやすい場合には寧ろ好都合かもしれません
      • 強引なものの、結果的には、パッケージの実体と vcpkg そのものを完全にプロジェクト単位の中だけで固有に管理しやすいので、ポータビリティーを考えると悪くないかもしれません
    3. Hunter は CMake 的に複雑なソリューションの中のサブプロジェクトとしては工夫しないと採用できない点が地味にめんどくさいかも; add_subdirectory の先に配置したい場合に少し厄介
      • しばしば conan との比較で CMake が綺麗と言われているように、実際、キレイです。キレイです…が、 conan を使った後だと CMake の記述量が少しですが多い点をだるく感じてしまうかもしれません
      • このメモに残したちょっとしたトリック程度で比較的簡単にパッケージの実体と Hunter の本体をまるごとプロジェクト単位の中に埋められるので、ポータビリティー的には vcpkg と同等の強さがあります
  5. 時間
    1. conan はビルド済みのバイナリーも提供してくれるので一般的な用途では便利
    2. vcpkg, Hunter は基本的にソースからビルドなので重いライブラリーを引っ張るとビルドに時間がかかります

KDE アプリが Windows/WSL/Ubuntu-19.04 環境で libQt5Core.so.5 が云々とかエラーを吐いて動かないときの対処方法のメモ

KDE なアプリたち、例えば umbrello とか kwrite とか、とにかくみんな↓のようなエラーを吐いて Windows/WSL/Ubuntu-19.04 環境で動いてくれない現象に遭遇しました。

kwrite: error while loading shared libraries: libQt5Core.so.5: cannot open shared object file: No such file or directory

発生した環境の状態:

  • Windows 10 Pro 64-Bit (10.0.18362.535)
  • WSL の Ubuntu を 19.04 へ do-release-upgrade したばかり
  • X は X410 を使っています (今回の問題に直接は関係ありません)

ぐぐったら既に superuser で解決されていました:

Ripdog の Answer はおおよそ正解ですが、さらに bart がコメントしているように、少しだけ状況が異なる可能性があります。私の場合も同様。

正解の安定手順は:

  1. findlibQt5Core.so.5 のパスを確認
  2. strip で .note.ABI-tag を消しちゃう

のようです。

find /usr/lib -iname "*qt5core.so*"

/usr/lib/x86_64-linux-gnu/libQt5Core.so
/usr/lib/x86_64-linux-gnu/libQt5Core.so.5
/usr/lib/x86_64-linux-gnu/libQt5Core.so.5.12
/usr/lib/x86_64-linux-gnu/libQt5Core.so.5.12.2

sudo strip --remove-section=.note.ABI-tag /usr/lib/x86_64-linux-gnu/libQt5Core.so.5

これで、 KDE なアプリたち(というより /usr/lib/x86_64-linux-gnu/libQt5Core.so.5 に依存するアプリたち)が少なくともこの問題については解決され動作してくれるようになります。

f:id:USAGI-WRP:20191226173734p:plain

f:id:USAGI-WRP:20191226174005p:plain

Windows 10: CPU 100% 張り付き問題の解決

少し前に、次の状況に気が付きました:

  • Windows 10 Pro 64-Bit ( 10.0, Build 18362 ) で、
  • Task Manager の CPU 負荷が Processes タブと Performance タブで全てのコアが常に 100% に張り付いた状態になる
  • 但し、下図のように GL-Z などタスクマネージャーではない方法で観測するとタスクマネージャーが "うそ" の報告をしている疑いがあります
  • 蛇足: マルウェアのせいじゃないと思うよ

f:id:USAGI-WRP:20191225064404p:plain

困るような、困らないような状況ですが、少なくとも精神衛生上の問題と気持ち悪さはあります。緊急性は無さそうなのでしばらく放置していましたが、タスクマネージャーを使うと目に入るので、気になって少し調べてみると:

Windows Insider 系の投稿に 2018 に WaritC が同様の問題を報告している事に気が付きました。キーワードを工夫しないと、当てずっぽうでいい加減な「どうせマルウェアだろ」的な記事ばかりググられてしまったりもしますし、この記事でも Ken Blake がさっそく「よくわからないが、たぶんマルウェアのせいだろう」と返信を付けています。

もちろん、私に先ほどまで起きていた "この問題" あるいは WaritC に起きていた "この問題" はマルウェアのせいではありませんでした。 WaritC はマルウェアの指摘にも真摯に対応しながら、最初の投稿から3日後に、

I was able to randomly find a fix on my own after reading around on the internet.

It seems like the issue came from "Power Options" (right clicking on battery icon) and when I "restore default settings for this plan" the CPU usage level dropped down to normal levels.

著者訳:

インターネットで調べたり、あちこち適当にいじってみたところ、私はこの問題を解決できました。

この問題は "Power Options" (バッテリーのアイコンを右クリックして) から、"restore default settings for this plan" すると CPU の使用状況を正常な状態まで下げられます。

と、いうわけで、私も試してみました。 "狙って探す" のは少し分かりにくい部分をポチる必要があります:

f:id:USAGI-WRP:20191225071930p:plain

(†1): ↑この画面の "Change plan settings" のリンクをポチり、

f:id:USAGI-WRP:20191225071317p:plain

(†2): ↑この画面の "Restore default settings for this plan" のリンクをポチると、その瞬間以降タスクマネージャーのCPU負荷の表示が期待動作する状態に回復します。

手順を整理すると:

  1. スタートメニューの "Settings" (たぶん日本語だと「設定」) から
  2. "Edit Power Plan" (日本語では「電源プラン」のなんとか…だと思います)
  3. 画面(†1)から、選択中ならどのプランでもいいので、プランの右側にある "Change plan settings" (プラン設定を変更とか日本語では出ているのかも) のリンクをポチり、
  4. 画面(†2)から、"Restore default settings for this plan" のリンクをポチる (日本語ではデフォルトの設定を復元する、とか標準の設定に戻すとかそういう表現かもしれません)

です。

f:id:USAGI-WRP:20191225072442p:plain

すっきりしました🧙‍♀️

🎄 Happy holidays ⛄

Thunderbird-68.3.1 で可能な本当のダークモードの設定方法のメモ: メッセージ本文領域にも闇を

f:id:USAGI-WRP:20191218144528p:plain

Dark Theme を使いたい人は↑こうしたいと思って Dark Theme を選択すると思います。たいてい。なので、標準搭載されている Dark Theme は「そうじゃない…」ってなると思います。私はなりました。標準搭載の Dark Theme やアドオンマネージャーでインストールできる自称 Dark 系のテーマでは、特にメッセージ本文の部分が白背景と黒文字のままで、電子メールアプリの本体部分みたいなところが眩しすぎてつらいままです。つらいです。

今回はこの ShadowBird で画面写真のように安らぎを得ました。この repos の README にある 3. (Optional) の部分がこの問題にとっては重要です。

プロファイルディレクトリー( Thunderbird の「ヘルプ」→「トラブルシューティング情報」の「プロファイルフォルダー」の「フォルダーを開く」 )に user.js を作成して、

user_pref("browser.display.foreground_color", "#b1b1b3");
user_pref("browser.display.background_color", "#38383d");

を書きましょうと案内されています。これで幸せになれます。あなたの目にも眩しすぎる光が心の平穏を乱さず適度に降り注ぐ未来が訪れますようにお祈り(このメモ)を残します。

参考