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 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 することができる。 間違っても死ぬわけじゃないのでそんなに恐れずやっていいと思う。
これで良いのかは分からないが,まあ動くっぽいのでヨシッ! 厳密なこと言うといくらでもダメな状況ってのが出てきそう。
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 ってのが発表されましたね。
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 Arch Linux GNOME 以下,思いついたら追記する。
入れる このへんは base-devel
make gcc automake その他
clang cmake Emacs(ビルド) vim(設定いじる時用。あと xxd 目当てで) ninja(mozc のビルドにいる) mozc(自分のリポジトリからビルド) texlive-langjapanese, texlive-latexextra, texlive-pictures poppler-data(poppler とセットで入らない意味がよくわからない) firefox-developer-edition(署名せずに拡張機能使いたい) thunderbird コピーして引っ越さないといけない系 ~/Documents (TeX のゴミファイルは消した方がいいかも) ~/source 以下ゴソッと。~/source/aur はいらない。 ~/.ssh セットアップ SSH 鍵 dotfiles を clone して install .emacs.d を clone 他の設定 gsettings set org.gnome.desktop.input-sources xkb-options "['ctrl:nocaps']" gsettings set org.gnome.desktop.wm.preferences button-layout 'close,minimize,maximize:appmenu' Firefox, Thunderbird の言語を日本語に && Wayland を使うことにする。ウェイウェイ いらない desktop entry がたくさんあるので ~/.local/share/applications に /dev/null への symlink をたくさんつくって消す /etc/default/grub をいじって起動時のログを冗長にする GRUB じゃなくて systemd-boot 使えばいいや ibus が起動してくれなかったらなんとかする PHP で SQLite が使えるように設定ファイルを足す(ファイル名は何でもいいけど /etc/php/conf.d/sqlite.ini とかに) 置くやつ on Gist
アクセスログ見たら脆弱性突いてくるアクセスがかなりきていた。 このサイトはページを返す上で CGI の類いは動いていないのでアプリケーションサーバーであること を前提とした攻撃に対して脆弱性が発生することはないが,これが Linux カーネルや Nginx の脆弱性を突くものだったらと考えるとセキュリティ対策の重要性を思い知らされる。
セキュリティとは別の話にはなるが,聞いたこともないようなクローラもたくさん来ていて クローラが乱立しているなと思う。まあデータマイニングとかその周辺の技術が流行ってるからなあ。
ibus-daemon(1) が起動していないことが原因らしい。 ビルドし直せば治るかなと思って GNOME の設定から mozc を消してしまったので デバッグできなくなっていた。
とりあえず,これが解消するまでは自分で systemd のユニットファイルを作って 自動起動してやることにした。 ちゃんと起動するようになったらバグるかもしれんが, まあそのときはなんとかして disable すればなんとかなるやろ。
https://gist.github.com/kofuk/4ef7b0baec48f1af2e6f5561fda89f98
最近全然書いてなかったけど,いろいろ変えたのでまとめておくことにしました。
最近の更新はおおまかに分けて次の3点です。
パフォーマンスの改善 処理のパイプライン化 その他機能追加 パフォーマンスの改善 やることを減らすってのが一番の高速化の方法なので,いろいろ処理を省けるようにしました。 最初の愚直な実装から4つくらいやることを減らしています。
1つ目が更新していないチャンクを再描画しないというもので,これはチャンクの LastUpdate というタグを見て判定しています。LastUpdate の値を region ファイルごとに ファイルにダンプしておいて,次の再描画の時に LastUpdate の値がそれよりも 大きくなっていたら再描画して,そうでなかったら省くという感じになっています。 前の描画内容に上書きするために,もとのファイルを読むという処理が追加されているので, PNG のデコードとか走るんですが,チャンクを再描画するほうがずっと遅いので 問題ないです。あと,更新されているチャンクがあって初めてもとのファイルを開く ことにしているので,画像の範囲の中で更新されているチャンクが1つもない場合は 画像ファイルに触りもしないということになっています。
C の比較演算の結果で,true の場合は 1 で false の場合は 0 っていうのが常識的な 挙動のような気がするけど,未規定とかじゃなくてちゃんと決まっているのか, 前から気になっていたのでちゃんと調べた。 素直に検索しても出なかったけど,ちゃんと規格(に近いもの)を見に行ったら 簡単に書いてあるのが見つかって,どうやら true が 1 で false が 0 になるってのは 決まってるっぽい。
つまり,以下のコードは環境に依存せずに 2 を出力する。
#include <stdio.h> int main(void) { int num = (0 == 0) + (0 == 0); printf ("%d\n", num); return 0; } あと,結果の型は int。
参考 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf
なんじゃこりゃ
%:include <stdio.h> int main(void) <% char str<::> = "Hello, world!"; printf("%s\n", str); return 0; %> これが
$ gcc main.c コンパイルすると
$ ./a.out Hello, world 動いてしまう。
<:, :>, <%, %>, %:, %:%: の6つのトークンは, [, ], {, }, #, ## と同じように解釈されるらしい。
なんじゃそりゃ。
参照 http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf