WindowsにCMakeのプロジェクトを移植する

UNIX で Makefile 生成してビルドしていたような CMake のプロジェクトを Windows に移植する。 ここでは Visual Studio について言及するとき Visual Studio 2019 を前提とする (というか試せる環境がそれしかない)が多分そこにはそんなに依存していないはず。 とりあえず言えることは,CMake で Visual Studio のプロジェクトを生成する方法は Make を使ったプロジェクトとビルドシステムの設計というか思想が違いすぎてその差異を CMakeLists.txt で吸収するのは無理だと思う(たぶん単純なプロジェクトだと大丈夫だけど凝ったことをしようとすると すぐ詰む)。書くの面倒臭いので飛ばすけど Visual Studio は CMake では Multi-config という扱いになって Makefile とはちょっと違う環境になるので。 というわけで,NMake の Makefile を生成するのが簡単な方法だと思う。 この方法だと最小限のプラットフォーム固有の(cmake の)コードでビルドが通るようにできる。

Gitで一部の変更だけをコミットする

全ファイルコミットできる単位でコミットしろよ←わかる 全ファイルをコミットする 一番簡単。だいたいこれでやってる気がする。 $ git add -A 一部のファイルだけコミットする 普通。 $ git add foo.c bar.c baz.c 一部の hunk だけコミットする $ git add -p ってやると hunk を stage するか聞かれるので stage したい hunk で y と答える。 hunk の一部だけコミットする 変更がくっついていると違う内容の変更が 1 個の hunk に入ってしまったりする。 $ git add -p した後に追加したい変更が入っている hunk で e と答える(え?) するとテキストエディタが起動して,diff を編集しろと言ってくる。 で,これは編集しろと言ってくるファイルにも書いてあるが, - で始まる行(削除した行)をなかったことにしたかったら - を (スペース)で置き換える + で始まる行(追加した行)をなかったことにしたかったらその行自体を削除する という感じで編集すると望んだ部分だけを stage することができる。 間違っても死ぬわけじゃないのでそんなに恐れずやっていいと思う。

Waylandで動いているかXWaylandで動いているか見分ける

小数単位でのスケーリングをしていたら XWayland のアプリケーションは ぼやけているので自明な感じはあるが,面白い(かつ見た目が良い?)見分け方を 見つけたので。 xeyes を起動する。 マウスを動かしてみる。 簡単ですね! マウスをいろんなウィンドウの上に動かしてみて目が動くウィンドウは XWayland, 目が動かないウィンドウは Wayland で動いている。 参考 https://medium.com/@bugaevc/how-to-easily-determine-if-an-app-runs-on-xwayland-or-on-wayland-natively-8191b506ab9a xeyes のソースコード: https://gitlab.freedesktop.org/xorg/app/xeyes

Firefox on Wayland

XWayland だとスケーリングしたときにぼやける問題があるので,Wayland を使うようにする。 今の段階だと MOZ_ENABLE_WAYLAND=1 という環境変数があった場合は Wayland を使う ようになっている。毎回端末から実行すれば当然できるが,それは面倒なのでアイコンをクリックしたときでも Wayland を使う設定で普通に起動するようにしたい。 同じ方法で Thunderbird にも Wayland を使わせることができる。 方法1: .bashrc とかに書く 一番簡単。でも僕はむやみに環境変数足したくない派(全然関係ないプロセスからアプリケーション固有の 設定が見えるのが無駄な感じがする)なのでこの方法はあまり好きじゃない。 方法2: デスクトップエントリーをいじる /usr/share/applications/firefox.desktop を ~/.local/share/applications/ に コピーしてきて Exec の行のコマンドの先頭に env MOZ_ENABLE_WAYLAND=1 を追加する。 本当は差分だけ編集したい(systemd のユニットファイルみたく)けどそういう方法では動かなかった。

型ごとの上限・下限

一応型ごとの大きさは規格では決まってない(最小限のビット数はあるけどこれを書いても意味がない) けど x86_64 だったら普通同じになるはず。 Type Bits Min Max signed char 8 -128 127 unsigned char 8 0 255 signed short 16 -32768 32767 unsigned short 16 0 65535 signed int 32 -2147483648 2147483647 unsigned int 32 0 4294967295 signed long int 64 -9223372036854775808 9223372036854775807 unsigned long int 64 0 18446744073709551615 signed long long int 64 -9223372036854775808 9223372036854775807 unsigned long long int 64 0 18446744073709551615 コード #include <iostream> #include <limits> using namespace std; #define LIMIT(type) cout << "`" #type "` | " \ << sizeof(type) * numeric_limits<unsigned char>::digits << " | " \ << +numeric_limits<type>::min() << " | " \ << +numeric_limits<type>::max() << endl; int main() { cout << "Type | Bits | Min | Max" << endl; cout << "-----|------|-----|----" << endl; LIMIT(signed char); LIMIT(unsigned char); LIMIT(signed short); LIMIT(unsigned short); LIMIT(signed int); LIMIT(unsigned int); LIMIT(signed long int); LIMIT(unsigned long int); LIMIT(signed long long int); LIMIT(unsigned long long int); } 浮動小数点数 10進での桁数 type num float 6 double 15 long double 18

GNOME端末にSixelが入るかも?

2021/8/10 追記 ちゃんとマージされていたので、それを入れる方法をこちらに書きました。 知らんけど。 なんか今作業中っぽいやつを適当に clone してきてビルドして使ってみた。 ビルドしてインストールされてる GNOME 端末で使う方法を適当に紹介。 ライブラリとかは適当に入れてください。僕は gobject-introspection と vala を追加で入れる必要があった。Ubuntu とかだとヘッダファイルも 入れないといけない気がする。 ソースを落としてくる。僕はここから持ってきた。 https://gitlab.gnome.org/hansp/vte/-/tree/sixel-v5-hpj (けどこれはマージされてもマージされなくても消えるはず) meson _build とかしてビルド用のディレクトリに ninja でビルドするファイルを生成する。 ninja -C _build -j8 でビルド。-j オプションはコア数に合わせるとたぶん良い。 なんかエラーが出たので適当にエラーが出ないように修正。フォーマット文字列と型が一致しないとかだった。 _build/src/ に libvteなんとかかんとかというファイルが生成されているのでリンクじゃないどれかを/usr/libにコピーする。 /usr/lib/libvteなんとかかんとか.so.0のシンボリックリンクをさっきコピーしたライブラリを指すように張り直す。 /usr/libにコピーしなくても LD_LIBRARY_PATH の通ってるディレクトリに置けばいい気はするけど /tmp で作業したのとめんどくさかったのとでこういう感じにした。

awkなしでフィールドを切り出す

スペース区切りの出力から特定のフィールドを取り出す方法といったらだいたい cut か awk ってことになると思うんですが,フィールドを取り出すためだけに awk を起動するのもなー と思う。で,cut を使おうとするが,これが空白の連続に対応できない。 よくあるプログラミング言語の split 関数みたいな感じだなと。 で結論から言うとっていうか結論を言ったらこの投稿は終了なんだけど,以下のようにする。 $ your-command | tr -s ' ' | cut -d ' ' -f2 これでも先頭に空白がある ps の出力とかは謎の 2-index みたいになってしまうけど まあ妥協。変えたかったら sed とかで頑張ればいいと思うけどそこまでやる価値があるのかは不明。 あとオプションと引数をつなげると文字数減らせるハックなど(無駄) $ your-command|tr -s \ |cut -d\ -f2

CMakeのExternalProject

これで良いのかは分からないが,まあ動くっぽいのでヨシッ! 厳密なこと言うといくらでもダメな状況ってのが出てきそう。 cmake_minimum_required(VERSION 3.15) project(ext_sample CXX) set(CMAKE_CXX_STANDARD 17) set(CMAKE_STANDARD_REQUIRED ON) include(ExternalProject) ExternalProject_Add(zlib_project URL https://zlib.net/zlib-1.2.11.tar.xz CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_SOURCE_DIR}/zlib) ExternalProject_Add(libpng_project URL https://download.sourceforge.net/libpng/libpng-1.6.37.tar.xz CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${PROJECT_SOURCE_DIR}/libpng) add_library(zlib IMPORTED SHARED) set_target_properties(zlib PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/zlib/lib/libz.so) add_library(libpng IMPORTED SHARED) add_dependencies(libpng zlib) set_target_properties(libpng PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/libpng/lib/libpng.so INTERFACE_INCLUDE_DIRECTORIES ${PROJECT_SOURCE_DIR}/zlib/include INTERFACE_LINK_LIBRARIES zlib) find_package(Threads) find_package(Boost COMPONENTS unit_test_framework) add_executable(mcmap) target_include_directories(mcmap PRIVATE ${PROJECT_SOURCE_DIR}/libpng/include ${PROJECT_SOURCE_DIR}/zlib/include) target_include_directories(mcmap PRIVATE ${CMAKE_BINARY_DIR}) target_link_libraries(mcmap PRIVATE zlib libpng ${CMAKE_THREAD_LIBS_INIT}) add_subdirectory(block) add_subdirectory(src) で試しに ldd で見てみる。 $ ldd build/mcmap linux-vdso.so.1 (0x00007fffbf7f6000) libpng16.so.16 => /tmp/foo/libpng/lib/libpng16.so.16 (0x00007f3a7ffea000) libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f3a7ff9c000) libz.so.1 => /tmp/foo/zlib/lib/libz.so.1 (0x00007f3a7ff7b000) libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x00007f3a7fd9e000) libm.so.6 => /usr/lib/libm.so.6 (0x00007f3a7fc59000) libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x00007f3a7fc3f000) libc.so.6 => /usr/lib/libc.so.6 (0x00007f3a7fa76000) /lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007f3a8007c000) あといい感じに install を書きましょう(こんな方法が必要なのは Windows でのビルドだけのような気がするが)。 まあ実際に使うときは最初に find_package してみてダメだったらフォールバックする って感じにするかなと。 そういや最近 Windows の winget ってのが発表されましたね。

WindowsでCMakeのプロジェクトをビルドする

Visual Studio 入れて試してみたら簡単だった(今まで MSYS2 入れて UNIX Makefile を生成してビルドしていた). 基本的には root の CMakeLists.txt があるディレクトリを Visual Studio の「フォルダを開く」的な メニュー(プロジェクトを開くに非ず)から開けばいい感じに cmake を実行するところまでやってくれる. ただちょっと困っているのが pkg-config がないことだ. もっとも Windows にはシステムに1つライブラリを入れて多数のアプリから使うという 習慣がなさそうに思われるので,システムに入っているという状況が普通ないというのは理解できるのだが. しかし依存関係しているライブラリを全部 CMake でダウンロードしてビルドして,というのは流石に 面倒臭すぎる.どうにかならないものだろうか. MSYS2 でビルドする場合だと,(あの空間は *nix 的な設計がされているので)pkg-config で依存するライブラリのインクルードパスやライブラリの設定ができた. そして,ldd とかで依存しているライブラリを調べてそれらと一緒に他の環境に持っていけば 問題なく動作させることができた(というのも Windows はライブラリを探すときに最初にその executable があるパスを探すので).

ThinkPad X1 Carbon

買ったの書いてなかった. Lenovo の ThinkPad X1 Carbon (7th Gen) を買った.価格は税込みで 21 万くらいだった. 14インチで1キロ強というのはやっぱり軽くていいなと思う. まあまだ外に持ち出したことないけど. 主な構成 CPU: Intel Core i7 10510U メモリ: 16 GB ストレージ: 512 GB NVMe ディスプレイ: 1920x1080 キーボードは英語(どうでもいいけど何故か金取られるので書かずにはいられない) 正直言ってあまりストレージやメモリを使うことをやってないのでメモリ 16 GB とストレージ 512 GB はオーバースペックな気がするが,まあそこ気づいていないことになっている. で,買った段階では OS が入っていないので(Windows?知らない子ですね)ArchLinux を入れた. 僕は面倒な環境構築はすっ飛ばしたい派なので ArchLinux を入れて面倒くさいことを することを目的としているわけではなくて,単に新しいバージョンのがバイナリ配布で入る 便利ディストロとして ArchLinux を使っている.まあパーディション分けるときに 迷うくらいで構成決まってればインストールそんなに大変じゃないよね. パーティションはめんどくさいので ESP だけ分けて他は1つのパーティションという 雑運用がされている.